diff --git a/Assets/Scripts/Rope/Rope.cs b/Assets/Scripts/Rope/Rope.cs index 5753d8a..e89eaa7 100644 --- a/Assets/Scripts/Rope/Rope.cs +++ b/Assets/Scripts/Rope/Rope.cs @@ -137,6 +137,7 @@ public class Rope } */ } +[System.Serializable] public struct NetworkRope : INetworkSerializable { // For rope points diff --git a/Assets/Scripts/Rope/RopeSimulator.cs b/Assets/Scripts/Rope/RopeSimulator.cs index 0634624..7e5f9d3 100644 --- a/Assets/Scripts/Rope/RopeSimulator.cs +++ b/Assets/Scripts/Rope/RopeSimulator.cs @@ -73,6 +73,8 @@ public class RopeSimulator : NetworkBehaviour private System.Random rng = new System.Random(k_rngSeed); private CountdownTimer ropeSendTimer; private int currentTick => NetworkManager.Singleton.NetworkTickSystem.LocalTime.Tick; + [SerializeField] private CircularBuffer stateBuffer; + private const int k_bufferSize = 512; private int[] order; @@ -98,6 +100,8 @@ public class RopeSimulator : NetworkBehaviour Destroy(instance); } + stateBuffer = new(k_bufferSize); + ropeSendTimer = new(k_sendRopeDataDelay); // ropeSendTimer.OnTimerStop += SendRopeData; @@ -108,13 +112,13 @@ public class RopeSimulator : NetworkBehaviour private void OnEnable() { GameManager.OnPlayersReady += PlayersReady; - NetworkManager.Singleton.NetworkTickSystem.Tick += SendGameState; + NetworkManager.Singleton.NetworkTickSystem.Tick += NetworkTick; } private void OnDisable() { GameManager.OnPlayersReady -= PlayersReady; - NetworkManager.Singleton.NetworkTickSystem.Tick -= SendGameState; + NetworkManager.Singleton.NetworkTickSystem.Tick -= NetworkTick; } public void PlayersReady(GameObject[] players) @@ -305,16 +309,23 @@ public class RopeSimulator : NetworkBehaviour Debug.Log($"Received server state. Server tick: {serverState.tick}, client: {currentTick}"); } - private void SendGameState() + private void NetworkTick() { - if (!IsServer) return; + stateBuffer.Add(ProcessGame(), currentTick); - GameState serverState = new() { + // Send to clients if is server + if (IsServer) + ServerToClientGameStateRpc(stateBuffer.Get(currentTick)); + } + + private GameState ProcessGame() + { + GameState localState = new() { tick = currentTick, nrope = Rope.ToNetworkRope(this.rope) }; - ServerToClientGameStateRpc(serverState); + return localState; } private void SendRopeData() diff --git a/Assets/Scripts/Utilities/CircularBuffer.cs b/Assets/Scripts/Utilities/CircularBuffer.cs index a8a3076..fb34132 100644 --- a/Assets/Scripts/Utilities/CircularBuffer.cs +++ b/Assets/Scripts/Utilities/CircularBuffer.cs @@ -1,6 +1,7 @@ +[System.Serializable] public class CircularBuffer { - T[] buffer; - int bufferSize; + public T[] buffer; + public int bufferSize; public CircularBuffer(int bufferSize) { this.bufferSize = bufferSize; diff --git a/Assets/Scripts/Utilities/CircularBufferDrawer.cs b/Assets/Scripts/Utilities/CircularBufferDrawer.cs new file mode 100644 index 0000000..f1a6a1e --- /dev/null +++ b/Assets/Scripts/Utilities/CircularBufferDrawer.cs @@ -0,0 +1,50 @@ +#if UNITY_EDITOR +using UnityEditor; +using UnityEngine; + +[CustomPropertyDrawer(typeof(CircularBuffer<>))] +public class CircularBufferDrawer : PropertyDrawer +{ + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + EditorGUI.BeginProperty(position, label, property); + + EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); + + EditorGUI.indentLevel++; + + SerializedProperty bufferSizeProp = property.FindPropertyRelative("bufferSize"); + int bufferSize = bufferSizeProp.intValue; + + EditorGUI.PropertyField( + new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight, position.width, EditorGUIUtility.singleLineHeight), + bufferSizeProp); + + SerializedProperty bufferProp = property.FindPropertyRelative("buffer"); + + EditorGUI.LabelField( + new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight * 2, position.width, EditorGUIUtility.singleLineHeight), + "Buffer Elements"); + + float lineHeight = EditorGUIUtility.singleLineHeight; + float bufferHeight = lineHeight * bufferSize; + + Rect bufferRect = new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight * 3, position.width, bufferHeight); + + EditorGUI.PropertyField(bufferRect, bufferProp, GUIContent.none, true); + + EditorGUI.indentLevel--; + + EditorGUI.EndProperty(); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + SerializedProperty bufferSizeProp = property.FindPropertyRelative("bufferSize"); + int bufferSize = bufferSizeProp.intValue; + + return EditorGUIUtility.singleLineHeight * (bufferSize + 3); // 1 for buffer size, 1 for label, and bufferSize for buffer elements + } +} + +#endif diff --git a/Assets/Scripts/Utilities/CircularBufferDrawer.cs.meta b/Assets/Scripts/Utilities/CircularBufferDrawer.cs.meta new file mode 100644 index 0000000..a40c42b --- /dev/null +++ b/Assets/Scripts/Utilities/CircularBufferDrawer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 53ed82cd9cfbdb1868c0d12e415dd33f \ No newline at end of file