using System.Linq; using UnityEngine; using UnityEngine.Assertions; using Unity.Netcode; using System.Collections.Generic; [System.Serializable] public class Rope { public Point[] points; public Stick[] sticks; public Rope() {} public Rope(Point[] points, Stick[] sticks) { this.points = points; this.sticks = sticks; } public float CalculateLengthOvershoot() { float sum = 0f; foreach (Stick stick in sticks) { Debug.DrawRay(stick.B.position, (stick.A.position - stick.B.position).normalized * stick.desiredLength); float dist = Vector3.Distance(stick.A.position, stick.B.position); sum += dist - stick.desiredLength; } return sum; } public static float CalcDiff(Rope r1, Rope r2, bool excludeZ = true) { if (r1.points.Length != r2.points.Length) { throw new System.ArgumentException("Ropes are not the same length"); } float diff = 0; if (excludeZ) { for (int i = 0; i < r1.points.Length; i++) { Vector3 p1, p2; p1 = new Vector2(r1.points[i].position.x, r1.points[i].position.y); p2 = new Vector2(r2.points[i].position.x, r2.points[i].position.y); diff += Vector2.Distance(p1, p2); } } else { 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 Rope Copy(float stickLength) { RopeBuilder builder = new(); foreach (var point in points) { builder.AddPoint(new Point(point.position, point.locked)); } for (int i = 0; i < points.Length - 1; i++) { builder.ConnectPointsWithDesiredLength(i, i + 1, 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); } } } */ } [System.Serializable] 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]); } */ } }