diff --git a/Assets/Scripts/Multiplayer/Project.Scripts.Multiplayer.asmdef b/Assets/Scripts/Multiplayer/Project.Scripts.Multiplayer.asmdef index 931573e..d12e737 100644 --- a/Assets/Scripts/Multiplayer/Project.Scripts.Multiplayer.asmdef +++ b/Assets/Scripts/Multiplayer/Project.Scripts.Multiplayer.asmdef @@ -2,13 +2,11 @@ "name": "Project.Scripts.Multiplayer", "rootNamespace": "", "references": [ - "GUID:bcf1cb15035164f59bdb33e59e5dd367", "GUID:6055be8ebefd69e48b49212b09b47b2f", "GUID:2aa43b0c797e0d444a7e82e75d4f2082", "GUID:3b8ed52f1b5c64994af4c4e0aa4b6c4b", "GUID:1491147abca9d7d4bb7105af628b223e", "GUID:75469ad4d38634e559750d17036d5f7c", - "GUID:dfa0fc7c5444edd619a15e6f8c8f242a", "GUID:42d1898a72cfe6848ae89835fb20acd2", "GUID:ff1c299121c93f34ca827a253fc30a61", "GUID:1eb4e3e6c04cdc848bab71651b1e2ecd", diff --git a/Assets/Scripts/Rope/Project.Scripts.Rope.asmdef b/Assets/Scripts/Rope/Project.Scripts.Rope.asmdef index ffa4845..faf882b 100644 --- a/Assets/Scripts/Rope/Project.Scripts.Rope.asmdef +++ b/Assets/Scripts/Rope/Project.Scripts.Rope.asmdef @@ -8,7 +8,8 @@ "GUID:ddd4dba7c768b564a879069c52854fc5", "GUID:c0e1b40f519e6e84b8f4af9930403ecb", "GUID:3b8ed52f1b5c64994af4c4e0aa4b6c4b", - "GUID:1491147abca9d7d4bb7105af628b223e" + "GUID:1491147abca9d7d4bb7105af628b223e", + "GUID:068707ae079d6e851b7a76adaa3014f8" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Assets/Scripts/Rope/Rope.cs b/Assets/Scripts/Rope/Rope.cs index 2699a0f..e8220e2 100644 --- a/Assets/Scripts/Rope/Rope.cs +++ b/Assets/Scripts/Rope/Rope.cs @@ -24,4 +24,5 @@ public class Rope } return sum; } + } diff --git a/Assets/Scripts/Rope/RopeSimulator.cs b/Assets/Scripts/Rope/RopeSimulator.cs index e2df954..2c5a4ad 100644 --- a/Assets/Scripts/Rope/RopeSimulator.cs +++ b/Assets/Scripts/Rope/RopeSimulator.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using Unity.Netcode; @@ -64,7 +63,12 @@ public class RopeSimulator : NetworkBehaviour [Header("Animaion")] [SerializeField] float pullAnimationOvershootThreshold = 0.2f; - int[] order; + [Header("Netcode")] + private const int k_rngSeed = 6969; + private System.Random rng = new System.Random(k_rngSeed); + private NetworkTimer networkTimer; + + private int[] order; public float Overshoot => rope.CalculateLengthOvershoot(); public bool InSwingMode => start.locked || end.locked; @@ -80,6 +84,7 @@ public class RopeSimulator : NetworkBehaviour // TODO: also true in single player mode private bool ShouldSimulate => IsHost; + private void Awake() { if (instance == null) @@ -300,7 +305,7 @@ public class RopeSimulator : NetworkBehaviour rope.points.First().position = start.position; rope.points.Last().position = end.position; - Simulate(); + Simulate(Time.fixedDeltaTime); // Update the rope collider positions for (int i = 0; i < rope.points.Count; i++) @@ -417,7 +422,7 @@ public class RopeSimulator : NetworkBehaviour } } - void Simulate() + void Simulate(float dt) { Assert.IsTrue(ShouldSimulate, "Should not simulate rope on client!"); @@ -427,7 +432,7 @@ public class RopeSimulator : NetworkBehaviour { Vector3 positionBeforeUpdate = p.position; p.position += p.position - p.prevPosition; - p.position.z -= gravity * Time.deltaTime * Time.deltaTime; + p.position.z -= gravity * dt * dt; p.prevPosition = positionBeforeUpdate; } } @@ -438,9 +443,7 @@ public class RopeSimulator : NetworkBehaviour { Stick stick = rope.sticks[order[s]]; if (stick.dead) - { continue; - } Vector3 stickCentre = (stick.A.position + stick.B.position) / 2; Vector3 stickDir = (stick.A.position - stick.B.position).normalized; @@ -464,6 +467,7 @@ public class RopeSimulator : NetworkBehaviour private void TryMovePointToPosition(Point point, Vector3 position) { Assert.IsTrue(ShouldSimulate); + Vector2 moveDir = new Vector2(position.x, position.y) - new Vector2(point.position.x, point.position.y); int stepsRequired = (int) Mathf.Ceil(moveDir.magnitude / collisionCheckDist); moveDir.Normalize(); @@ -531,7 +535,7 @@ public class RopeSimulator : NetworkBehaviour { order[i] = i; } - ShuffleArray(order, new System.Random()); + ShuffleArray(order, rng); } public static T[] ShuffleArray(T[] array, System.Random prng) @@ -541,7 +545,6 @@ public class RopeSimulator : NetworkBehaviour while (elementsRemainingToShuffle > 1) { - // Choose a random element from array randomIndex = prng.Next(0, elementsRemainingToShuffle); T chosenElement = array[randomIndex]; diff --git a/Assets/Scripts/Utilities.meta b/Assets/Scripts/Utilities.meta new file mode 100644 index 0000000..0132616 --- /dev/null +++ b/Assets/Scripts/Utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d48856ef91909169cb2161e0aed7193e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/CircularBuffer.cs b/Assets/Scripts/Utilities/CircularBuffer.cs new file mode 100644 index 0000000..a8a3076 --- /dev/null +++ b/Assets/Scripts/Utilities/CircularBuffer.cs @@ -0,0 +1,13 @@ +public class CircularBuffer { + T[] buffer; + int bufferSize; + + public CircularBuffer(int bufferSize) { + this.bufferSize = bufferSize; + buffer = new T[bufferSize]; + } + + public void Add(T item, int index) => buffer[index % bufferSize] = item; + public T Get(int index) => buffer[index % bufferSize]; + public void Clear() => buffer = new T[bufferSize]; +} diff --git a/Assets/Scripts/Utilities/CircularBuffer.cs.meta b/Assets/Scripts/Utilities/CircularBuffer.cs.meta new file mode 100644 index 0000000..58f7959 --- /dev/null +++ b/Assets/Scripts/Utilities/CircularBuffer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 82749b4844b9f18ffa95eeaabc003f4e \ No newline at end of file diff --git a/Assets/Scripts/Utilities/NetworkTimer.cs b/Assets/Scripts/Utilities/NetworkTimer.cs new file mode 100644 index 0000000..6ea74f6 --- /dev/null +++ b/Assets/Scripts/Utilities/NetworkTimer.cs @@ -0,0 +1,23 @@ +public class NetworkTimer { + float timer; + public float MinTimeBetweenTicks { get; } + public int CurrentTick { get; private set; } + + public NetworkTimer(float serverTickRate) { + MinTimeBetweenTicks = 1f / serverTickRate; + } + + public void Update(float deltaTime) { + timer += deltaTime; + } + + public bool ShouldTick() { + if (timer >= MinTimeBetweenTicks) { + timer -= MinTimeBetweenTicks; + CurrentTick++; + return true; + } + + return false; + } +} diff --git a/Assets/Scripts/Utilities/NetworkTimer.cs.meta b/Assets/Scripts/Utilities/NetworkTimer.cs.meta new file mode 100644 index 0000000..5a7c3d6 --- /dev/null +++ b/Assets/Scripts/Utilities/NetworkTimer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5eefe3926a904f2ebb22193055448eee \ No newline at end of file diff --git a/Assets/Scripts/Utilities/Project.Scripts.Utilities.asmdef b/Assets/Scripts/Utilities/Project.Scripts.Utilities.asmdef new file mode 100644 index 0000000..26cf92d --- /dev/null +++ b/Assets/Scripts/Utilities/Project.Scripts.Utilities.asmdef @@ -0,0 +1,3 @@ +{ + "name": "Project.Scripts.Utilities" +} diff --git a/Assets/Scripts/Utilities/Project.Scripts.Utilities.asmdef.meta b/Assets/Scripts/Utilities/Project.Scripts.Utilities.asmdef.meta new file mode 100644 index 0000000..9da06eb --- /dev/null +++ b/Assets/Scripts/Utilities/Project.Scripts.Utilities.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 068707ae079d6e851b7a76adaa3014f8 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Utilities/Timer.cs b/Assets/Scripts/Utilities/Timer.cs new file mode 100644 index 0000000..c99ae4d --- /dev/null +++ b/Assets/Scripts/Utilities/Timer.cs @@ -0,0 +1,77 @@ +using System; + +namespace Utilities { + public abstract class Timer { + protected float initialTime; + protected float Time { get; set; } + public bool IsRunning { get; protected set; } + + public float Progress => Time / initialTime; + + public Action OnTimerStart = delegate { }; + public Action OnTimerStop = delegate { }; + + protected Timer(float value) { + initialTime = value; + IsRunning = false; + } + + public void Start() { + Time = initialTime; + if (!IsRunning) { + IsRunning = true; + OnTimerStart.Invoke(); + } + } + + public void Stop() { + if (IsRunning) { + IsRunning = false; + OnTimerStop.Invoke(); + } + } + + public void Resume() => IsRunning = true; + public void Pause() => IsRunning = false; + + public abstract void Tick(float deltaTime); + } + + public class CountdownTimer : Timer { + public CountdownTimer(float value) : base(value) { } + + public override void Tick(float deltaTime) { + if (IsRunning && Time > 0) { + Time -= deltaTime; + } + + if (IsRunning && Time <= 0) { + Stop(); + } + } + + public bool IsFinished => Time <= 0; + + public void Reset() => Time = initialTime; + + public void Reset(float newTime) { + initialTime = newTime; + Reset(); + } + } + + public class StopwatchTimer : Timer { + public StopwatchTimer() : base(0) { } + + public override void Tick(float deltaTime) { + if (IsRunning) { + Time += deltaTime; + } + } + + public void Reset() => Time = 0; + + public float GetTime() => Time; + } + +} diff --git a/Assets/Scripts/Utilities/Timer.cs.meta b/Assets/Scripts/Utilities/Timer.cs.meta new file mode 100644 index 0000000..4d92a2d --- /dev/null +++ b/Assets/Scripts/Utilities/Timer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 79ecfa1b4cbfadfdfb6120c79507b4cd \ No newline at end of file