From f0f56c5b700936419fbdeea80eb91205c2351a8c Mon Sep 17 00:00:00 2001 From: Sveske_Juice Date: Mon, 4 Mar 2024 17:40:23 +0100 Subject: [PATCH] rope wip --- Assets/Prefabs/Networked/RopePoint.prefab | 54 ------ Assets/Prefabs/Rope.prefab | 45 +---- Assets/Scenes/GameScene.unity | 13 +- Assets/Scripts/Rope/Point.cs | 21 ++- Assets/Scripts/Rope/Rope.cs | 209 +++++++++++++++++++++- Assets/Scripts/Rope/RopeBuilder.cs | 2 +- Assets/Scripts/Rope/RopeSimulator.cs | 96 +++++----- Assets/Scripts/Rope/Stick.cs | 17 +- 8 files changed, 302 insertions(+), 155 deletions(-) diff --git a/Assets/Prefabs/Networked/RopePoint.prefab b/Assets/Prefabs/Networked/RopePoint.prefab index 8fae474..f758615 100644 --- a/Assets/Prefabs/Networked/RopePoint.prefab +++ b/Assets/Prefabs/Networked/RopePoint.prefab @@ -11,8 +11,6 @@ GameObject: - component: {fileID: 3817028170077760731} - component: {fileID: 4590407122831754579} - component: {fileID: 8963967235500975272} - - component: {fileID: -5174249022758144916} - - component: {fileID: -7862229988660046446} m_Layer: 0 m_Name: RopePoint m_TagString: Untagged @@ -98,55 +96,3 @@ Rigidbody2D: m_SleepingMode: 1 m_CollisionDetection: 0 m_Constraints: 0 ---- !u!114 &-5174249022758144916 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4736158799711156794} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} - m_Name: - m_EditorClassIdentifier: - GlobalObjectIdHash: 1634323294 - InScenePlacedSourceGlobalObjectIdHash: 0 - AlwaysReplicateAsRoot: 0 - SynchronizeTransform: 1 - ActiveSceneSynchronization: 0 - SceneMigrationSynchronization: 1 - SpawnWithObservers: 1 - DontDestroyWithOwner: 0 - AutoObjectParentSync: 1 ---- !u!114 &-7862229988660046446 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4736158799711156794} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e96cb6065543e43c4a752faaa1468eb1, type: 3} - m_Name: - m_EditorClassIdentifier: - UseUnreliableDeltas: 0 - SyncPositionX: 1 - SyncPositionY: 1 - SyncPositionZ: 1 - SyncRotAngleX: 0 - SyncRotAngleY: 0 - SyncRotAngleZ: 0 - SyncScaleX: 0 - SyncScaleY: 0 - SyncScaleZ: 0 - PositionThreshold: 0.001 - RotAngleThreshold: 0.01 - ScaleThreshold: 0.01 - UseQuaternionSynchronization: 0 - UseQuaternionCompression: 0 - UseHalfFloatPrecision: 0 - InLocalSpace: 0 - Interpolate: 1 - SlerpPosition: 0 diff --git a/Assets/Prefabs/Rope.prefab b/Assets/Prefabs/Rope.prefab index c2d39d3..3187be6 100644 --- a/Assets/Prefabs/Rope.prefab +++ b/Assets/Prefabs/Rope.prefab @@ -9,12 +9,11 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 144529238244638330} - - component: {fileID: 2894273998966960381} + - component: {fileID: 6056950010778645813} - component: {fileID: 7717684785049474632} - component: {fileID: 901761791259710742} - component: {fileID: 4976294692568481572} - component: {fileID: 2066655509941542230} - - component: {fileID: 7670104141912458081} m_Layer: 0 m_Name: Rope m_TagString: Untagged @@ -37,7 +36,7 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &2894273998966960381 +--- !u!114 &6056950010778645813 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -49,15 +48,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} m_Name: m_EditorClassIdentifier: - GlobalObjectIdHash: 3972580189 - InScenePlacedSourceGlobalObjectIdHash: 1619090677 + GlobalObjectIdHash: 15502151 + InScenePlacedSourceGlobalObjectIdHash: 0 AlwaysReplicateAsRoot: 0 SynchronizeTransform: 1 ActiveSceneSynchronization: 0 SceneMigrationSynchronization: 1 SpawnWithObservers: 1 DontDestroyWithOwner: 0 - AutoObjectParentSync: 0 + AutoObjectParentSync: 1 --- !u!114 &7717684785049474632 MonoBehaviour: m_ObjectHideFlags: 0 @@ -119,6 +118,9 @@ MonoBehaviour: ropeCollidersParent: {fileID: 144529238244638330} lineRenderer: {fileID: 901761791259710742} pullAnimationOvershootThreshold: 0.2 + rope: + points: [] + sticks: [] --- !u!120 &901761791259710742 LineRenderer: serializedVersion: 2 @@ -333,34 +335,3 @@ AudioSource: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 ---- !u!114 &7670104141912458081 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5991265243222894942} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e96cb6065543e43c4a752faaa1468eb1, type: 3} - m_Name: - m_EditorClassIdentifier: - UseUnreliableDeltas: 0 - SyncPositionX: 1 - SyncPositionY: 1 - SyncPositionZ: 1 - SyncRotAngleX: 0 - SyncRotAngleY: 0 - SyncRotAngleZ: 0 - SyncScaleX: 0 - SyncScaleY: 0 - SyncScaleZ: 0 - PositionThreshold: 0.001 - RotAngleThreshold: 0.01 - ScaleThreshold: 0.01 - UseQuaternionSynchronization: 0 - UseQuaternionCompression: 0 - UseHalfFloatPrecision: 0 - InLocalSpace: 0 - Interpolate: 1 - SlerpPosition: 0 diff --git a/Assets/Scenes/GameScene.unity b/Assets/Scenes/GameScene.unity index bdf47c5..e81028f 100644 --- a/Assets/Scenes/GameScene.unity +++ b/Assets/Scenes/GameScene.unity @@ -3722,7 +3722,6 @@ MonoBehaviour: difficulty: 1 difficultyIncreasePerWave: 3 WaveTime: 20 - enemyDifficulties: [] SpawnRadius: 22.6 NumEnemies: 6 initialSpawnDelay: 5 @@ -3902,14 +3901,18 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 2894273998966960381, guid: 0248db69242a3dd47898c6742b6c9f60, type: 3} - propertyPath: GlobalObjectIdHash - value: 3972580189 - objectReference: {fileID: 0} - target: {fileID: 5991265243222894942, guid: 0248db69242a3dd47898c6742b6c9f60, type: 3} propertyPath: m_Name value: Rope objectReference: {fileID: 0} + - target: {fileID: 6056950010778645813, guid: 0248db69242a3dd47898c6742b6c9f60, type: 3} + propertyPath: GlobalObjectIdHash + value: 1448608317 + objectReference: {fileID: 0} + - target: {fileID: 6056950010778645813, guid: 0248db69242a3dd47898c6742b6c9f60, type: 3} + propertyPath: InScenePlacedSourceGlobalObjectIdHash + value: 331293026 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] diff --git a/Assets/Scripts/Rope/Point.cs b/Assets/Scripts/Rope/Point.cs index 6bf6b10..bc0b178 100644 --- a/Assets/Scripts/Rope/Point.cs +++ b/Assets/Scripts/Rope/Point.cs @@ -1,15 +1,32 @@ using UnityEngine; +using Unity.Netcode; [System.Serializable] -public class Point +public class Point : INetworkSerializable { public Vector3 position, prevPosition; public bool locked; + public Point() {} + public Point(Vector3 position, bool locked = false) { this.position = position; this.prevPosition = position; this.locked = locked; } -} \ No newline at end of file + + public Point(Vector3 position, Vector3 prevPosition, bool locked = false) + { + this.position = position; + this.prevPosition = prevPosition; + this.locked = locked; + } + + public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter + { + serializer.SerializeValue(ref position); + serializer.SerializeValue(ref prevPosition); + serializer.SerializeValue(ref locked); + } +} diff --git a/Assets/Scripts/Rope/Rope.cs b/Assets/Scripts/Rope/Rope.cs index e8220e2..4ee9032 100644 --- a/Assets/Scripts/Rope/Rope.cs +++ b/Assets/Scripts/Rope/Rope.cs @@ -1,13 +1,18 @@ -using System.Collections.Generic; +using System.Linq; using UnityEngine; +using UnityEngine.Assertions; +using Unity.Netcode; +using System.Collections.Generic; [System.Serializable] public class Rope { - public List points { get ; private set; } - public List sticks { get; private set; } + public Point[] points; + public Stick[] sticks; - public Rope(List points, List sticks) + public Rope() {} + + public Rope(Point[] points, Stick[] sticks) { this.points = points; this.sticks = sticks; @@ -25,4 +30,200 @@ public class Rope return sum; } + public static float CalcDiff(Rope r1, Rope r2) + { + if (r1.points.Length != r2.points.Length) + { + throw new System.ArgumentException("Ropes are not the same length"); + } + + float diff = 0; + for (int i = 0; i < r1.points.Length; i++) + { + diff += Vector3.Distance(r1.points[i].position, r2.points[i].position); + } + return diff; + } + + public static NetworkRope ToNetworkRope(Rope rope) + { + return new NetworkRope + { + positions = rope.points.Select(p => p.position).ToArray(), + prevPositions = rope.points.Select(p => p.prevPosition).ToArray(), + locked = rope.points.Select(p => p.locked).ToArray(), + + sPosA = rope.sticks.Select(s => s.A.position).ToArray(), + sPrevPosA = rope.sticks.Select(s => s.A.prevPosition).ToArray(), + sPosB = rope.sticks.Select(s => s.B.position).ToArray(), + sPrevPosB = rope.sticks.Select(s => s.B.prevPosition).ToArray(), + dead = rope.sticks.Select(s => s.dead).ToArray(), + }; + } + + public static Rope FromNetworkRope(NetworkRope nrope, float stickLength) + { + Assert.IsTrue(nrope.positions.Length == nrope.prevPositions.Length); + Point[] points = new Point[nrope.positions.Length]; + for (int i = 0; i < nrope.positions.Length; i++) + { + points[i] = new Point(nrope.positions[i], nrope.prevPositions[i], nrope.locked[i]); + } + + RopeBuilder builder = new RopeBuilder(new List(points), new List()); + + for (int i = 0; i < (points.Length - 1); i++) + { + builder.ConnectPointsWithDesiredLength(i, i + 1, desiredLength: stickLength); + } + + return builder.Build(); + } + + /* public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter + { + int pLen = 0; + int sLen = 0; + + if (serializer.IsWriter) + { + pLen = points.Length; + sLen = sticks.Length; + } + + serializer.SerializeValue(ref pLen); + serializer.SerializeValue(ref sLen); + + if (serializer.IsReader) + { + points = new Point[pLen]; + sticks = new Stick[sLen]; + + for (int i = 0; i < pLen; i++) + { + serializer.GetFastBufferReader().ReadValueSafe(out points[i]); + } + + for (int i = 0; i < sLen; i++) + { + serializer.GetFastBufferReader().ReadValueSafe(out sticks[i]); + } + } + else + { + for (int i = 0; i < pLen; i++) + { + points[i].NetworkSerialize(serializer); + } + + for (int i = 0; i < sLen; i++) + { + sticks[i].NetworkSerialize(serializer); + } + } + } */ +} + +public struct NetworkRope : INetworkSerializable +{ + // For rope points + public Vector3[] positions; + public Vector3[] prevPositions; + public bool[] locked; + + // For rope sticks + public Vector3[] sPosA; + public Vector3[] sPrevPosA; + + public Vector3[] sPosB; + public Vector3[] sPrevPosB; + + public bool[] dead; + + public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter + { + int positionsLen = 0; + int prevPositionsLen = 0; + int lockedLen = 0; + int sPosALen = 0; + int sPrevPosALen = 0; + int sPosBLen = 0; + int sPrevPosBLen = 0; + int deadLen = 0; + + if (!serializer.IsReader) + { + positionsLen = positions.Length; + prevPositionsLen = prevPositions.Length; + lockedLen = locked.Length; + + sPosALen = sPosA.Length; + sPrevPosALen = sPrevPosA.Length; + sPosBLen = sPosB.Length; + sPrevPosBLen = sPrevPosB.Length; + deadLen = dead.Length; + } + + serializer.SerializeValue(ref positionsLen); + serializer.SerializeValue(ref prevPositionsLen); + serializer.SerializeValue(ref lockedLen); + serializer.SerializeValue(ref sPosALen); + serializer.SerializeValue(ref sPrevPosALen); + serializer.SerializeValue(ref sPosBLen); + serializer.SerializeValue(ref sPrevPosBLen); + serializer.SerializeValue(ref deadLen); + + if (serializer.IsReader) + { + positions = new Vector3[positionsLen]; + prevPositions = new Vector3[prevPositionsLen]; + locked = new bool[lockedLen]; + + sPosA = new Vector3[sPosALen]; + sPrevPosA = new Vector3[sPrevPosALen]; + sPosB = new Vector3[sPosBLen]; + sPrevPosB = new Vector3[sPrevPosBLen]; + dead = new bool[deadLen]; + } + + for (int i = 0; i < positionsLen; i++) + { + serializer.SerializeValue(ref positions[i]); + } + + for (int i = 0; i < prevPositionsLen; i++) + { + serializer.SerializeValue(ref prevPositions[i]); + } + + for (int i = 0; i < lockedLen; i++) + { + serializer.SerializeValue(ref locked[i]); + } + + for (int i = 0; i < sPosALen; i++) + { + serializer.SerializeValue(ref sPosA[i]); + } + + for (int i = 0; i < sPrevPosALen; i++) + { + serializer.SerializeValue(ref sPrevPosA[i]); + } + + for (int i = 0; i < sPosBLen; i++) + { + serializer.SerializeValue(ref sPosB[i]); + } + + for (int i = 0; i < sPrevPosBLen; i++) + { + serializer.SerializeValue(ref sPrevPosB[i]); + } + + for (int i = 0; i < deadLen; i++) + { + serializer.SerializeValue(ref dead[i]); + } + } } diff --git a/Assets/Scripts/Rope/RopeBuilder.cs b/Assets/Scripts/Rope/RopeBuilder.cs index 87ebc3a..8b69e42 100644 --- a/Assets/Scripts/Rope/RopeBuilder.cs +++ b/Assets/Scripts/Rope/RopeBuilder.cs @@ -40,6 +40,6 @@ public class RopeBuilder public Rope Build() { - return new Rope(points: points, sticks: sticks); + return new Rope(points: points.ToArray(), sticks: sticks.ToArray()); } } diff --git a/Assets/Scripts/Rope/RopeSimulator.cs b/Assets/Scripts/Rope/RopeSimulator.cs index 2ae0719..b883c7f 100644 --- a/Assets/Scripts/Rope/RopeSimulator.cs +++ b/Assets/Scripts/Rope/RopeSimulator.cs @@ -65,8 +65,9 @@ public class RopeSimulator : NetworkBehaviour [Header("Netcode")] private const int k_rngSeed = 6969; + private const float k_sendRopeDataRPCThreshold = 0.1f; + private const float k_ropeReconciliateThreshold = 0.1f; private System.Random rng = new System.Random(k_rngSeed); - private NetworkTimer networkTimer; private int[] order; @@ -81,10 +82,6 @@ public class RopeSimulator : NetworkBehaviour private bool IsInitialized => start != null || end != null; - // TODO: also true in single player mode - private bool ShouldSimulate => IsHost; - - private void Awake() { if (instance == null) @@ -109,17 +106,11 @@ public class RopeSimulator : NetworkBehaviour public void PlayersReady(GameObject[] players) { - if (ShouldSimulate) - { - Debug.Log(players[0].name); - BuildRope(players[0].GetComponent(), players[1].GetComponent()); - } + BuildRope(players[0].GetComponent(), players[1].GetComponent()); } public void BuildRope(RopeJoint start, RopeJoint end) { - Assert.IsTrue(ShouldSimulate, "Should not try build rope on client!"); - Assert.IsNotNull(start); Assert.IsNotNull(end); @@ -149,8 +140,6 @@ public class RopeSimulator : NetworkBehaviour void ShrinkenRope(int playerNumber) { - Assert.IsTrue(ShouldSimulate, "Should not shrink rope on client!"); - int prevSubDivision = (int) subDivision; subDivision -= ropeShrinkSpeed * Time.deltaTime; subDivision = Mathf.Clamp(subDivision, ropeMinLength, ropeMaxLength); @@ -159,10 +148,13 @@ public class RopeSimulator : NetworkBehaviour if (prevSubDivision - (int) subDivision <= 0) return; // Shrink from rope point after start rope joint - rope.sticks.Clear(); - rope.points.RemoveAt(1); + List newPoints = new(rope.points.Length - 1); + for (int i = 0; i < (rope.points.Length - 1); i++) + { + newPoints.Add(rope.points[i]); + } - var builder = new RopeBuilder(rope.points, rope.sticks); + var builder = new RopeBuilder(newPoints, new List()); // Re-gen sticks for (int i = 0; i < (int) subDivision; i++) @@ -177,8 +169,6 @@ public class RopeSimulator : NetworkBehaviour void ExtendRope(int playerNumber) { - Assert.IsTrue(ShouldSimulate, "Should not extend rope on client!"); - int prevSubDivision = (int)subDivision; subDivision += ropeExtendSpeed * Time.deltaTime; subDivision = Mathf.Clamp(subDivision, ropeMinLength, ropeMaxLength); @@ -187,10 +177,14 @@ public class RopeSimulator : NetworkBehaviour if (prevSubDivision - (int) subDivision >= 0) return; // Extend from rope point after start rope point - rope.sticks.Clear(); - rope.points.Insert(1, new Point(rope.points[1].position)); + List newPoints = new (rope.points.Length + 1); + newPoints.Add(new Point(rope.points[1].position)); + for (int i = 1; i < rope.points.Length; i++) + { + newPoints.Add(rope.points[i]); + } - var builder = new RopeBuilder(rope.points, rope.sticks); + var builder = new RopeBuilder(newPoints, new List()); // Re-gen sticks for (int i = 0; i < (int)subDivision; i++) @@ -220,8 +214,6 @@ public class RopeSimulator : NetworkBehaviour private void Rebuild() { - Assert.IsTrue(ShouldSimulate, "Should not re-build on clients!"); - Debug.Log("rebuild"); RopeBuilder builder = new RopeBuilder(); @@ -251,8 +243,6 @@ public class RopeSimulator : NetworkBehaviour private void RebuildRopeColliders() { - Assert.IsTrue(ShouldSimulate, "Should not build rope colliders on client!"); - for (int i = 0; i < ropeCollidersParent.childCount; i++) { Destroy(ropeCollidersParent.GetChild(i)); @@ -261,10 +251,8 @@ public class RopeSimulator : NetworkBehaviour foreach (var point in rope.points) { GameObject ropeCollider = Instantiate(colliderPrefab); - var ropeNO = ropeCollider.GetComponent(); - ropeNO.Spawn(); + ropeCollider.transform.parent = ropeCollidersParent; - ropeNO.TrySetParent(ropeCollidersParent); ropeCollider.transform.position = point.position; ropeCollider.tag = colliderTag; ropeCollider.layer = LayerMask.NameToLayer("Rope"); @@ -289,14 +277,21 @@ public class RopeSimulator : NetworkBehaviour lineRenderer.SetPositions(positions.ToArray()); } + [Rpc(SendTo.NotServer)] + private void ServerRopeDataReceivedRpc(NetworkRope nrope) + { + Debug.Log($"Received rope data from server: {nrope}"); + Debug.Log(nrope.sPosA[1]); + Rope serverRope = Rope.FromNetworkRope(nrope, distBetweenRopePoints); + if (Rope.CalcDiff(this.rope, serverRope) > k_ropeReconciliateThreshold) + { + Debug.LogWarning("Reconciliating rope!"); + this.rope = serverRope; + } + } + private void Update() { - if (!ShouldSimulate) - { - DrawRope(); - return; - } - if (!IsInitialized) return; @@ -305,10 +300,18 @@ public class RopeSimulator : NetworkBehaviour rope.points.First().position = start.position; rope.points.Last().position = end.position; - Simulate(Time.fixedDeltaTime); + float ropeDiff = Simulate(Time.fixedDeltaTime); + if (IsServer && ropeDiff > k_sendRopeDataRPCThreshold) + { + Debug.Log($"Sending rope to client"); + NetworkRope nrope = Rope.ToNetworkRope(this.rope); + + // Send server rope to client for reconciliation + ServerRopeDataReceivedRpc(nrope); + } // Update the rope collider positions - for (int i = 0; i < rope.points.Count; i++) + for (int i = 0; i < rope.points.Length; i++) { ropeCollidersParent.GetChild(i).position = rope.points[i].position; } @@ -353,7 +356,6 @@ public class RopeSimulator : NetworkBehaviour private void PlayerPullAnimation(float overshoot) { - Assert.IsTrue(ShouldSimulate); //if (overshoot > pullAnimationOvershootThreshold) //{ @@ -379,8 +381,6 @@ public class RopeSimulator : NetworkBehaviour private void PullPlayers(float overshoot) { - Assert.IsTrue(ShouldSimulate); - if (overshoot <= 0f) return; //start.position = prevStartPos; @@ -398,7 +398,7 @@ public class RopeSimulator : NetworkBehaviour } if (!end.locked) { - Vector2 pullDirection = (rope.points[rope.points.Count - 2].position - end.position).normalized; + Vector2 pullDirection = (rope.points[rope.points.Length - 2].position - end.position).normalized; Vector2 force = pullDirection * overshoot * (pullForce / divider); end.body.AddForce(force); } @@ -422,10 +422,9 @@ public class RopeSimulator : NetworkBehaviour } } - void Simulate(float dt) + float Simulate(float dt) { - Assert.IsTrue(ShouldSimulate, "Should not simulate rope on client!"); - + float diff = 0f; foreach (Point p in rope.points) { if (!p.locked) @@ -433,13 +432,14 @@ public class RopeSimulator : NetworkBehaviour Vector3 positionBeforeUpdate = p.position; p.position += p.position - p.prevPosition; p.position.z -= gravity * dt * dt; + diff += Mathf.Abs(Vector3.Distance(p.prevPosition, p.position)); p.prevPosition = positionBeforeUpdate; } } for (int i = 0; i < solveIterations; i++) { - for (int s = 0; s < rope.sticks.Count; s++) + for (int s = 0; s < rope.sticks.Length; s++) { Stick stick = rope.sticks[order[s]]; if (stick.dead) @@ -462,12 +462,11 @@ public class RopeSimulator : NetworkBehaviour } } } + return diff; } 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(); @@ -506,7 +505,6 @@ public class RopeSimulator : NetworkBehaviour private void HandleStaticCollidersOfPoint(Point p) { - Assert.IsTrue(ShouldSimulate); foreach (var hitCollider in Physics2D.OverlapCircleAll(p.position, ropeRadius*1.1f, staticColliderMask)) { if (hitCollider == null) continue; @@ -530,7 +528,7 @@ public class RopeSimulator : NetworkBehaviour void CreateOrderArray() { - order = new int[rope.sticks.Count]; + order = new int[rope.sticks.Length]; for (int i = 0; i < order.Length; i++) { order[i] = i; diff --git a/Assets/Scripts/Rope/Stick.cs b/Assets/Scripts/Rope/Stick.cs index eee0873..db2f1f3 100644 --- a/Assets/Scripts/Rope/Stick.cs +++ b/Assets/Scripts/Rope/Stick.cs @@ -1,12 +1,15 @@ using UnityEngine; +using Unity.Netcode; [System.Serializable] -public class Stick +public class Stick : INetworkSerializable { public Point A, B; public float desiredLength; public bool dead; + public Stick() { } + public Stick(Point pointA, Point pointB) { this.A = pointA; @@ -14,10 +17,18 @@ public class Stick desiredLength = Vector2.Distance(pointA.position, pointB.position); } - public Stick(Point pointA, Point pointB, float desiredLenght) + public Stick(Point pointA, Point pointB, float desiredLenght) { this.A = pointA; this.B = pointB; this.desiredLength = desiredLenght; } -} \ No newline at end of file + + public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter + { + A.NetworkSerialize(serializer); + B.NetworkSerialize(serializer); + serializer.SerializeValue(ref desiredLength); + serializer.SerializeValue(ref dead); + } +}