Compare commits
4 Commits
f4ba2d210c
...
2a9000b120
Author | SHA1 | Date |
---|---|---|
Sveske_Juice | 2a9000b120 | |
Sveske_Juice | add18eb38c | |
Sveske_Juice | 0b5240af54 | |
Sveske_Juice | f0f56c5b70 |
|
@ -11,8 +11,6 @@ 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
|
||||||
|
@ -98,55 +96,3 @@ 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,12 +9,11 @@ GameObject:
|
||||||
serializedVersion: 6
|
serializedVersion: 6
|
||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 144529238244638330}
|
- component: {fileID: 144529238244638330}
|
||||||
- component: {fileID: 2894273998966960381}
|
- component: {fileID: 6056950010778645813}
|
||||||
- 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
|
||||||
|
@ -37,7 +36,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 &2894273998966960381
|
--- !u!114 &6056950010778645813
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
@ -49,15 +48,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: 3972580189
|
GlobalObjectIdHash: 15502151
|
||||||
InScenePlacedSourceGlobalObjectIdHash: 1619090677
|
InScenePlacedSourceGlobalObjectIdHash: 0
|
||||||
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: 0
|
AutoObjectParentSync: 1
|
||||||
--- !u!114 &7717684785049474632
|
--- !u!114 &7717684785049474632
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -119,6 +118,9 @@ 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
|
||||||
|
@ -333,34 +335,3 @@ 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,14 +4306,18 @@ 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,15 +1,32 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Unity.Netcode;
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class Point
|
public class Point : INetworkSerializable
|
||||||
{
|
{
|
||||||
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,13 +1,18 @@
|
||||||
using System.Collections.Generic;
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Assertions;
|
||||||
|
using Unity.Netcode;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class Rope
|
public class Rope
|
||||||
{
|
{
|
||||||
public List<Point> points { get ; private set; }
|
public Point[] points;
|
||||||
public List<Stick> sticks { get; private set; }
|
public Stick[] sticks;
|
||||||
|
|
||||||
public Rope(List<Point> points, List<Stick> sticks)
|
public Rope() {}
|
||||||
|
|
||||||
|
public Rope(Point[] points, Stick[] sticks)
|
||||||
{
|
{
|
||||||
this.points = points;
|
this.points = points;
|
||||||
this.sticks = sticks;
|
this.sticks = sticks;
|
||||||
|
@ -25,4 +30,213 @@ 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, sticks: sticks);
|
return new Rope(points: points.ToArray(), sticks: sticks.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,8 +65,9 @@ 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;
|
||||||
|
|
||||||
|
@ -81,10 +82,6 @@ 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)
|
||||||
|
@ -109,17 +106,11 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
public void PlayersReady(GameObject[] players)
|
public void PlayersReady(GameObject[] players)
|
||||||
{
|
{
|
||||||
if (ShouldSimulate)
|
|
||||||
{
|
|
||||||
Debug.Log(players[0].name);
|
|
||||||
BuildRope(players[0].GetComponent<RopeJoint>(), players[1].GetComponent<RopeJoint>());
|
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);
|
||||||
|
|
||||||
|
@ -149,8 +140,6 @@ 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);
|
||||||
|
@ -159,10 +148,13 @@ 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
|
||||||
rope.sticks.Clear();
|
List<Point> newPoints = new(rope.points.Length - 1);
|
||||||
rope.points.RemoveAt(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<Stick>());
|
||||||
|
|
||||||
// Re-gen sticks
|
// Re-gen sticks
|
||||||
for (int i = 0; i < (int) subDivision; i++)
|
for (int i = 0; i < (int) subDivision; i++)
|
||||||
|
@ -177,8 +169,6 @@ 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);
|
||||||
|
@ -187,10 +177,14 @@ 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
|
||||||
rope.sticks.Clear();
|
List<Point> newPoints = new (rope.points.Length + 1);
|
||||||
rope.points.Insert(1, new Point(rope.points[1].position));
|
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<Stick>());
|
||||||
|
|
||||||
// Re-gen sticks
|
// Re-gen sticks
|
||||||
for (int i = 0; i < (int)subDivision; i++)
|
for (int i = 0; i < (int)subDivision; i++)
|
||||||
|
@ -220,8 +214,6 @@ 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();
|
||||||
|
@ -251,8 +243,6 @@ 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));
|
||||||
|
@ -261,10 +251,8 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
foreach (var point in rope.points)
|
foreach (var point in rope.points)
|
||||||
{
|
{
|
||||||
GameObject ropeCollider = Instantiate(colliderPrefab);
|
GameObject ropeCollider = Instantiate(colliderPrefab);
|
||||||
var ropeNO = ropeCollider.GetComponent<NetworkObject>();
|
ropeCollider.transform.parent = ropeCollidersParent;
|
||||||
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");
|
||||||
|
@ -288,14 +276,24 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
lineRenderer.SetPositions(positions.ToArray());
|
lineRenderer.SetPositions(positions.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
[Rpc(SendTo.NotServer)]
|
||||||
|
private void ServerRopeDataReceivedRpc(NetworkRope nrope)
|
||||||
{
|
{
|
||||||
if (!ShouldSimulate)
|
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)
|
||||||
{
|
{
|
||||||
DrawRope();
|
Debug.LogWarning("Reconciliating rope!");
|
||||||
return;
|
this.rope = serverRope;
|
||||||
|
Debug.Log(Rope.CalcDiff(this.rope, serverRope));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
if (!IsInitialized)
|
if (!IsInitialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -304,10 +302,18 @@ 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;
|
||||||
|
|
||||||
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
|
// 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;
|
ropeCollidersParent.GetChild(i).position = rope.points[i].position;
|
||||||
}
|
}
|
||||||
|
@ -352,7 +358,6 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
private void PlayerPullAnimation(float overshoot)
|
private void PlayerPullAnimation(float overshoot)
|
||||||
{
|
{
|
||||||
Assert.IsTrue(ShouldSimulate);
|
|
||||||
|
|
||||||
//if (overshoot > pullAnimationOvershootThreshold)
|
//if (overshoot > pullAnimationOvershootThreshold)
|
||||||
//{
|
//{
|
||||||
|
@ -378,8 +383,6 @@ 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;
|
||||||
|
@ -397,7 +400,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
}
|
}
|
||||||
if (!end.locked)
|
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);
|
Vector2 force = pullDirection * overshoot * (pullForce / divider);
|
||||||
end.body.AddForce(force);
|
end.body.AddForce(force);
|
||||||
}
|
}
|
||||||
|
@ -421,10 +424,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)
|
foreach (Point p in rope.points)
|
||||||
{
|
{
|
||||||
if (!p.locked)
|
if (!p.locked)
|
||||||
|
@ -432,13 +434,14 @@ 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.Count; s++)
|
for (int s = 0; s < rope.sticks.Length; s++)
|
||||||
{
|
{
|
||||||
Stick stick = rope.sticks[order[s]];
|
Stick stick = rope.sticks[order[s]];
|
||||||
if (stick.dead)
|
if (stick.dead)
|
||||||
|
@ -461,12 +464,11 @@ 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();
|
||||||
|
@ -505,7 +507,6 @@ 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;
|
||||||
|
@ -529,7 +530,7 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
|
|
||||||
void CreateOrderArray()
|
void CreateOrderArray()
|
||||||
{
|
{
|
||||||
order = new int[rope.sticks.Count];
|
order = new int[rope.sticks.Length];
|
||||||
for (int i = 0; i < order.Length; i++)
|
for (int i = 0; i < order.Length; i++)
|
||||||
{
|
{
|
||||||
order[i] = i;
|
order[i] = i;
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Unity.Netcode;
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class Stick
|
public class Stick : INetworkSerializable
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
@ -20,4 +23,12 @@ public class Stick
|
||||||
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