Compare commits
No commits in common. "2a9000b1204371bd1b4bb7e461c70852e7512f88" and "f4ba2d210c85af0eded2f4fa711cf4777222f931" have entirely different histories.
2a9000b120
...
f4ba2d210c
|
@ -11,6 +11,8 @@ GameObject:
|
||||||
- component: {fileID: 3817028170077760731}
|
- component: {fileID: 3817028170077760731}
|
||||||
- component: {fileID: 4590407122831754579}
|
- component: {fileID: 4590407122831754579}
|
||||||
- component: {fileID: 8963967235500975272}
|
- component: {fileID: 8963967235500975272}
|
||||||
|
- component: {fileID: -5174249022758144916}
|
||||||
|
- component: {fileID: -7862229988660046446}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: RopePoint
|
m_Name: RopePoint
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
|
@ -96,3 +98,55 @@ Rigidbody2D:
|
||||||
m_SleepingMode: 1
|
m_SleepingMode: 1
|
||||||
m_CollisionDetection: 0
|
m_CollisionDetection: 0
|
||||||
m_Constraints: 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
|
||||||
|
|
|
@ -9,11 +9,12 @@ GameObject:
|
||||||
serializedVersion: 6
|
serializedVersion: 6
|
||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 144529238244638330}
|
- component: {fileID: 144529238244638330}
|
||||||
- component: {fileID: 6056950010778645813}
|
- component: {fileID: 2894273998966960381}
|
||||||
- component: {fileID: 7717684785049474632}
|
- component: {fileID: 7717684785049474632}
|
||||||
- component: {fileID: 901761791259710742}
|
- component: {fileID: 901761791259710742}
|
||||||
- component: {fileID: 4976294692568481572}
|
- component: {fileID: 4976294692568481572}
|
||||||
- component: {fileID: 2066655509941542230}
|
- component: {fileID: 2066655509941542230}
|
||||||
|
- component: {fileID: 7670104141912458081}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: Rope
|
m_Name: Rope
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
|
@ -36,7 +37,7 @@ Transform:
|
||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!114 &6056950010778645813
|
--- !u!114 &2894273998966960381
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
@ -48,15 +49,15 @@ MonoBehaviour:
|
||||||
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
|
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
GlobalObjectIdHash: 15502151
|
GlobalObjectIdHash: 3972580189
|
||||||
InScenePlacedSourceGlobalObjectIdHash: 0
|
InScenePlacedSourceGlobalObjectIdHash: 1619090677
|
||||||
AlwaysReplicateAsRoot: 0
|
AlwaysReplicateAsRoot: 0
|
||||||
SynchronizeTransform: 1
|
SynchronizeTransform: 1
|
||||||
ActiveSceneSynchronization: 0
|
ActiveSceneSynchronization: 0
|
||||||
SceneMigrationSynchronization: 1
|
SceneMigrationSynchronization: 1
|
||||||
SpawnWithObservers: 1
|
SpawnWithObservers: 1
|
||||||
DontDestroyWithOwner: 0
|
DontDestroyWithOwner: 0
|
||||||
AutoObjectParentSync: 1
|
AutoObjectParentSync: 0
|
||||||
--- !u!114 &7717684785049474632
|
--- !u!114 &7717684785049474632
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -118,9 +119,6 @@ MonoBehaviour:
|
||||||
ropeCollidersParent: {fileID: 144529238244638330}
|
ropeCollidersParent: {fileID: 144529238244638330}
|
||||||
lineRenderer: {fileID: 901761791259710742}
|
lineRenderer: {fileID: 901761791259710742}
|
||||||
pullAnimationOvershootThreshold: 0.2
|
pullAnimationOvershootThreshold: 0.2
|
||||||
rope:
|
|
||||||
points: []
|
|
||||||
sticks: []
|
|
||||||
--- !u!120 &901761791259710742
|
--- !u!120 &901761791259710742
|
||||||
LineRenderer:
|
LineRenderer:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
|
@ -335,3 +333,34 @@ AudioSource:
|
||||||
m_PreInfinity: 2
|
m_PreInfinity: 2
|
||||||
m_PostInfinity: 2
|
m_PostInfinity: 2
|
||||||
m_RotationOrder: 4
|
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
|
||||||
|
|
|
@ -4306,18 +4306,14 @@ PrefabInstance:
|
||||||
propertyPath: m_LocalEulerAnglesHint.z
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
value: 0
|
value: 0
|
||||||
objectReference: {fileID: 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}
|
- target: {fileID: 5991265243222894942, guid: 0248db69242a3dd47898c6742b6c9f60, type: 3}
|
||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
value: Rope
|
value: Rope
|
||||||
objectReference: {fileID: 0}
|
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_RemovedComponents: []
|
||||||
m_RemovedGameObjects: []
|
m_RemovedGameObjects: []
|
||||||
m_AddedGameObjects: []
|
m_AddedGameObjects: []
|
||||||
|
|
|
@ -1,32 +1,15 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Unity.Netcode;
|
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class Point : INetworkSerializable
|
public class Point
|
||||||
{
|
{
|
||||||
public Vector3 position, prevPosition;
|
public Vector3 position, prevPosition;
|
||||||
public bool locked;
|
public bool locked;
|
||||||
|
|
||||||
public Point() {}
|
|
||||||
|
|
||||||
public Point(Vector3 position, bool locked = false)
|
public Point(Vector3 position, bool locked = false)
|
||||||
{
|
{
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.prevPosition = position;
|
this.prevPosition = position;
|
||||||
this.locked = locked;
|
this.locked = locked;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point(Vector3 position, Vector3 prevPosition, bool locked = false)
|
|
||||||
{
|
|
||||||
this.position = position;
|
|
||||||
this.prevPosition = prevPosition;
|
|
||||||
this.locked = locked;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
|
|
||||||
{
|
|
||||||
serializer.SerializeValue(ref position);
|
|
||||||
serializer.SerializeValue(ref prevPosition);
|
|
||||||
serializer.SerializeValue(ref locked);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,18 +1,13 @@
|
||||||
using System.Linq;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.Assertions;
|
|
||||||
using Unity.Netcode;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class Rope
|
public class Rope
|
||||||
{
|
{
|
||||||
public Point[] points;
|
public List<Point> points { get ; private set; }
|
||||||
public Stick[] sticks;
|
public List<Stick> sticks { get; private set; }
|
||||||
|
|
||||||
public Rope() {}
|
public Rope(List<Point> points, List<Stick> sticks)
|
||||||
|
|
||||||
public Rope(Point[] points, Stick[] sticks)
|
|
||||||
{
|
{
|
||||||
this.points = points;
|
this.points = points;
|
||||||
this.sticks = sticks;
|
this.sticks = sticks;
|
||||||
|
@ -30,213 +25,4 @@ public class Rope
|
||||||
return sum;
|
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<Point>(points), new List<Stick>());
|
|
||||||
|
|
||||||
for (int i = 0; i < (points.Length - 1); i++)
|
|
||||||
{
|
|
||||||
builder.ConnectPointsWithDesiredLength(i, i + 1, desiredLength: stickLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* public void NetworkSerialize<T>(BufferSerializer<T> 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<T>(BufferSerializer<T> 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]);
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,6 @@ public class RopeBuilder
|
||||||
|
|
||||||
public Rope Build()
|
public Rope Build()
|
||||||
{
|
{
|
||||||
return new Rope(points: points.ToArray(), sticks: sticks.ToArray());
|
return new Rope(points: points, sticks: sticks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,9 +65,8 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
[Header("Netcode")]
|
[Header("Netcode")]
|
||||||
private const int k_rngSeed = 6969;
|
private const int k_rngSeed = 6969;
|
||||||
private const float k_sendRopeDataRPCThreshold = 0.1f;
|
|
||||||
private const float k_ropeReconciliateThreshold = 0.25f;
|
|
||||||
private System.Random rng = new System.Random(k_rngSeed);
|
private System.Random rng = new System.Random(k_rngSeed);
|
||||||
|
private NetworkTimer networkTimer;
|
||||||
|
|
||||||
private int[] order;
|
private int[] order;
|
||||||
|
|
||||||
|
@ -82,6 +81,10 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
private bool IsInitialized => start != null || end != null;
|
private bool IsInitialized => start != null || end != null;
|
||||||
|
|
||||||
|
// TODO: also true in single player mode
|
||||||
|
private bool ShouldSimulate => IsHost;
|
||||||
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
|
@ -106,11 +109,17 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
public void PlayersReady(GameObject[] players)
|
public void PlayersReady(GameObject[] players)
|
||||||
{
|
{
|
||||||
BuildRope(players[0].GetComponent<RopeJoint>(), players[1].GetComponent<RopeJoint>());
|
if (ShouldSimulate)
|
||||||
|
{
|
||||||
|
Debug.Log(players[0].name);
|
||||||
|
BuildRope(players[0].GetComponent<RopeJoint>(), players[1].GetComponent<RopeJoint>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BuildRope(RopeJoint start, RopeJoint end)
|
public void BuildRope(RopeJoint start, RopeJoint end)
|
||||||
{
|
{
|
||||||
|
Assert.IsTrue(ShouldSimulate, "Should not try build rope on client!");
|
||||||
|
|
||||||
Assert.IsNotNull(start);
|
Assert.IsNotNull(start);
|
||||||
Assert.IsNotNull(end);
|
Assert.IsNotNull(end);
|
||||||
|
|
||||||
|
@ -140,6 +149,8 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
void ShrinkenRope(int playerNumber)
|
void ShrinkenRope(int playerNumber)
|
||||||
{
|
{
|
||||||
|
Assert.IsTrue(ShouldSimulate, "Should not shrink rope on client!");
|
||||||
|
|
||||||
int prevSubDivision = (int) subDivision;
|
int prevSubDivision = (int) subDivision;
|
||||||
subDivision -= ropeShrinkSpeed * Time.deltaTime;
|
subDivision -= ropeShrinkSpeed * Time.deltaTime;
|
||||||
subDivision = Mathf.Clamp(subDivision, ropeMinLength, ropeMaxLength);
|
subDivision = Mathf.Clamp(subDivision, ropeMinLength, ropeMaxLength);
|
||||||
|
@ -148,13 +159,10 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
if (prevSubDivision - (int) subDivision <= 0) return;
|
if (prevSubDivision - (int) subDivision <= 0) return;
|
||||||
|
|
||||||
// Shrink from rope point after start rope joint
|
// Shrink from rope point after start rope joint
|
||||||
List<Point> newPoints = new(rope.points.Length - 1);
|
rope.sticks.Clear();
|
||||||
for (int i = 0; i < (rope.points.Length - 1); i++)
|
rope.points.RemoveAt(1);
|
||||||
{
|
|
||||||
newPoints.Add(rope.points[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var builder = new RopeBuilder(newPoints, new List<Stick>());
|
var builder = new RopeBuilder(rope.points, rope.sticks);
|
||||||
|
|
||||||
// Re-gen sticks
|
// Re-gen sticks
|
||||||
for (int i = 0; i < (int) subDivision; i++)
|
for (int i = 0; i < (int) subDivision; i++)
|
||||||
|
@ -169,6 +177,8 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
void ExtendRope(int playerNumber)
|
void ExtendRope(int playerNumber)
|
||||||
{
|
{
|
||||||
|
Assert.IsTrue(ShouldSimulate, "Should not extend rope on client!");
|
||||||
|
|
||||||
int prevSubDivision = (int)subDivision;
|
int prevSubDivision = (int)subDivision;
|
||||||
subDivision += ropeExtendSpeed * Time.deltaTime;
|
subDivision += ropeExtendSpeed * Time.deltaTime;
|
||||||
subDivision = Mathf.Clamp(subDivision, ropeMinLength, ropeMaxLength);
|
subDivision = Mathf.Clamp(subDivision, ropeMinLength, ropeMaxLength);
|
||||||
|
@ -177,14 +187,10 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
if (prevSubDivision - (int) subDivision >= 0) return;
|
if (prevSubDivision - (int) subDivision >= 0) return;
|
||||||
|
|
||||||
// Extend from rope point after start rope point
|
// Extend from rope point after start rope point
|
||||||
List<Point> newPoints = new (rope.points.Length + 1);
|
rope.sticks.Clear();
|
||||||
newPoints.Add(new Point(rope.points[1].position));
|
rope.points.Insert(1, new Point(rope.points[1].position));
|
||||||
for (int i = 1; i < rope.points.Length; i++)
|
|
||||||
{
|
|
||||||
newPoints.Add(rope.points[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var builder = new RopeBuilder(newPoints, new List<Stick>());
|
var builder = new RopeBuilder(rope.points, rope.sticks);
|
||||||
|
|
||||||
// Re-gen sticks
|
// Re-gen sticks
|
||||||
for (int i = 0; i < (int)subDivision; i++)
|
for (int i = 0; i < (int)subDivision; i++)
|
||||||
|
@ -214,6 +220,8 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
private void Rebuild()
|
private void Rebuild()
|
||||||
{
|
{
|
||||||
|
Assert.IsTrue(ShouldSimulate, "Should not re-build on clients!");
|
||||||
|
|
||||||
Debug.Log("rebuild");
|
Debug.Log("rebuild");
|
||||||
|
|
||||||
RopeBuilder builder = new RopeBuilder();
|
RopeBuilder builder = new RopeBuilder();
|
||||||
|
@ -243,6 +251,8 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
private void RebuildRopeColliders()
|
private void RebuildRopeColliders()
|
||||||
{
|
{
|
||||||
|
Assert.IsTrue(ShouldSimulate, "Should not build rope colliders on client!");
|
||||||
|
|
||||||
for (int i = 0; i < ropeCollidersParent.childCount; i++)
|
for (int i = 0; i < ropeCollidersParent.childCount; i++)
|
||||||
{
|
{
|
||||||
Destroy(ropeCollidersParent.GetChild(i));
|
Destroy(ropeCollidersParent.GetChild(i));
|
||||||
|
@ -251,8 +261,10 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
foreach (var point in rope.points)
|
foreach (var point in rope.points)
|
||||||
{
|
{
|
||||||
GameObject ropeCollider = Instantiate(colliderPrefab);
|
GameObject ropeCollider = Instantiate(colliderPrefab);
|
||||||
ropeCollider.transform.parent = ropeCollidersParent;
|
var ropeNO = ropeCollider.GetComponent<NetworkObject>();
|
||||||
|
ropeNO.Spawn();
|
||||||
|
|
||||||
|
ropeNO.TrySetParent(ropeCollidersParent);
|
||||||
ropeCollider.transform.position = point.position;
|
ropeCollider.transform.position = point.position;
|
||||||
ropeCollider.tag = colliderTag;
|
ropeCollider.tag = colliderTag;
|
||||||
ropeCollider.layer = LayerMask.NameToLayer("Rope");
|
ropeCollider.layer = LayerMask.NameToLayer("Rope");
|
||||||
|
@ -276,24 +288,14 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
lineRenderer.SetPositions(positions.ToArray());
|
lineRenderer.SetPositions(positions.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Rpc(SendTo.NotServer)]
|
|
||||||
private void ServerRopeDataReceivedRpc(NetworkRope nrope)
|
|
||||||
{
|
|
||||||
Debug.Log($"Received rope data from server: {nrope}");
|
|
||||||
Rope serverRope = Rope.FromNetworkRope(nrope, distBetweenRopePoints);
|
|
||||||
|
|
||||||
float diff = Rope.CalcDiff(this.rope, serverRope);
|
|
||||||
Debug.Log(diff);
|
|
||||||
if (diff > k_ropeReconciliateThreshold)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("Reconciliating rope!");
|
|
||||||
this.rope = serverRope;
|
|
||||||
Debug.Log(Rope.CalcDiff(this.rope, serverRope));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
|
if (!ShouldSimulate)
|
||||||
|
{
|
||||||
|
DrawRope();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsInitialized)
|
if (!IsInitialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -302,18 +304,10 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
rope.points.First().position = start.position;
|
rope.points.First().position = start.position;
|
||||||
rope.points.Last().position = end.position;
|
rope.points.Last().position = end.position;
|
||||||
|
|
||||||
float ropeDiff = Simulate(Time.fixedDeltaTime);
|
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
|
// Update the rope collider positions
|
||||||
for (int i = 0; i < rope.points.Length; i++)
|
for (int i = 0; i < rope.points.Count; i++)
|
||||||
{
|
{
|
||||||
ropeCollidersParent.GetChild(i).position = rope.points[i].position;
|
ropeCollidersParent.GetChild(i).position = rope.points[i].position;
|
||||||
}
|
}
|
||||||
|
@ -358,6 +352,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
private void PlayerPullAnimation(float overshoot)
|
private void PlayerPullAnimation(float overshoot)
|
||||||
{
|
{
|
||||||
|
Assert.IsTrue(ShouldSimulate);
|
||||||
|
|
||||||
//if (overshoot > pullAnimationOvershootThreshold)
|
//if (overshoot > pullAnimationOvershootThreshold)
|
||||||
//{
|
//{
|
||||||
|
@ -383,6 +378,8 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
private void PullPlayers(float overshoot)
|
private void PullPlayers(float overshoot)
|
||||||
{
|
{
|
||||||
|
Assert.IsTrue(ShouldSimulate);
|
||||||
|
|
||||||
if (overshoot <= 0f) return;
|
if (overshoot <= 0f) return;
|
||||||
|
|
||||||
//start.position = prevStartPos;
|
//start.position = prevStartPos;
|
||||||
|
@ -400,7 +397,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
}
|
}
|
||||||
if (!end.locked)
|
if (!end.locked)
|
||||||
{
|
{
|
||||||
Vector2 pullDirection = (rope.points[rope.points.Length - 2].position - end.position).normalized;
|
Vector2 pullDirection = (rope.points[rope.points.Count - 2].position - end.position).normalized;
|
||||||
Vector2 force = pullDirection * overshoot * (pullForce / divider);
|
Vector2 force = pullDirection * overshoot * (pullForce / divider);
|
||||||
end.body.AddForce(force);
|
end.body.AddForce(force);
|
||||||
}
|
}
|
||||||
|
@ -424,9 +421,10 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float Simulate(float dt)
|
void Simulate(float dt)
|
||||||
{
|
{
|
||||||
float diff = 0f;
|
Assert.IsTrue(ShouldSimulate, "Should not simulate rope on client!");
|
||||||
|
|
||||||
foreach (Point p in rope.points)
|
foreach (Point p in rope.points)
|
||||||
{
|
{
|
||||||
if (!p.locked)
|
if (!p.locked)
|
||||||
|
@ -434,14 +432,13 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
Vector3 positionBeforeUpdate = p.position;
|
Vector3 positionBeforeUpdate = p.position;
|
||||||
p.position += p.position - p.prevPosition;
|
p.position += p.position - p.prevPosition;
|
||||||
p.position.z -= gravity * dt * dt;
|
p.position.z -= gravity * dt * dt;
|
||||||
diff += Mathf.Abs(Vector3.Distance(p.prevPosition, p.position));
|
|
||||||
p.prevPosition = positionBeforeUpdate;
|
p.prevPosition = positionBeforeUpdate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < solveIterations; i++)
|
for (int i = 0; i < solveIterations; i++)
|
||||||
{
|
{
|
||||||
for (int s = 0; s < rope.sticks.Length; s++)
|
for (int s = 0; s < rope.sticks.Count; s++)
|
||||||
{
|
{
|
||||||
Stick stick = rope.sticks[order[s]];
|
Stick stick = rope.sticks[order[s]];
|
||||||
if (stick.dead)
|
if (stick.dead)
|
||||||
|
@ -464,11 +461,12 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return diff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TryMovePointToPosition(Point point, Vector3 position)
|
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);
|
Vector2 moveDir = new Vector2(position.x, position.y) - new Vector2(point.position.x, point.position.y);
|
||||||
int stepsRequired = (int) Mathf.Ceil(moveDir.magnitude / collisionCheckDist);
|
int stepsRequired = (int) Mathf.Ceil(moveDir.magnitude / collisionCheckDist);
|
||||||
moveDir.Normalize();
|
moveDir.Normalize();
|
||||||
|
@ -507,6 +505,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
private void HandleStaticCollidersOfPoint(Point p)
|
private void HandleStaticCollidersOfPoint(Point p)
|
||||||
{
|
{
|
||||||
|
Assert.IsTrue(ShouldSimulate);
|
||||||
foreach (var hitCollider in Physics2D.OverlapCircleAll(p.position, ropeRadius*1.1f, staticColliderMask))
|
foreach (var hitCollider in Physics2D.OverlapCircleAll(p.position, ropeRadius*1.1f, staticColliderMask))
|
||||||
{
|
{
|
||||||
if (hitCollider == null) continue;
|
if (hitCollider == null) continue;
|
||||||
|
@ -530,7 +529,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
void CreateOrderArray()
|
void CreateOrderArray()
|
||||||
{
|
{
|
||||||
order = new int[rope.sticks.Length];
|
order = new int[rope.sticks.Count];
|
||||||
for (int i = 0; i < order.Length; i++)
|
for (int i = 0; i < order.Length; i++)
|
||||||
{
|
{
|
||||||
order[i] = i;
|
order[i] = i;
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Unity.Netcode;
|
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class Stick : INetworkSerializable
|
public class Stick
|
||||||
{
|
{
|
||||||
public Point A, B;
|
public Point A, B;
|
||||||
public float desiredLength;
|
public float desiredLength;
|
||||||
public bool dead;
|
public bool dead;
|
||||||
|
|
||||||
public Stick() { }
|
|
||||||
|
|
||||||
public Stick(Point pointA, Point pointB)
|
public Stick(Point pointA, Point pointB)
|
||||||
{
|
{
|
||||||
this.A = pointA;
|
this.A = pointA;
|
||||||
|
@ -23,12 +20,4 @@ public class Stick : INetworkSerializable
|
||||||
this.B = pointB;
|
this.B = pointB;
|
||||||
this.desiredLength = desiredLenght;
|
this.desiredLength = desiredLenght;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
|
|
||||||
{
|
|
||||||
A.NetworkSerialize(serializer);
|
|
||||||
B.NetworkSerialize(serializer);
|
|
||||||
serializer.SerializeValue(ref desiredLength);
|
|
||||||
serializer.SerializeValue(ref dead);
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue