Compare commits
No commits in common. "3364a2785d16e8074658d041349af3b47becc696" and "99aa0647f2d9d2c93a33b62fdabd79a39ad53456" have entirely different histories.
3364a2785d
...
99aa0647f2
|
@ -179,7 +179,7 @@ LineRenderer:
|
||||||
m_Curve:
|
m_Curve:
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
time: 0
|
time: 0
|
||||||
value: 0.2160211
|
value: 0.2280693
|
||||||
inSlope: 0
|
inSlope: 0
|
||||||
outSlope: 0
|
outSlope: 0
|
||||||
tangentMode: 0
|
tangentMode: 0
|
||||||
|
|
|
@ -2238,7 +2238,6 @@ GameObject:
|
||||||
serializedVersion: 6
|
serializedVersion: 6
|
||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 34894283}
|
- component: {fileID: 34894283}
|
||||||
- component: {fileID: 34894286}
|
|
||||||
- component: {fileID: 34894284}
|
- component: {fileID: 34894284}
|
||||||
- component: {fileID: 34894285}
|
- component: {fileID: 34894285}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
|
@ -2276,14 +2275,14 @@ MonoBehaviour:
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
solveIterations: 10
|
solveIterations: 10
|
||||||
subDivision: 30
|
ropeStart: {fileID: 0}
|
||||||
distBetweenRopePoints: 0.75
|
ropeEnd: {fileID: 0}
|
||||||
|
subDivision: 20
|
||||||
|
distBetweenRopePoints: 1.5
|
||||||
lineRenderer: {fileID: 34894285}
|
lineRenderer: {fileID: 34894285}
|
||||||
rope:
|
rope:
|
||||||
points: []
|
points: []
|
||||||
sticks: []
|
sticks: []
|
||||||
reconciliateThreshold: 2
|
|
||||||
reconciliateLerpFrameDuration: 9
|
|
||||||
stateBuffer:
|
stateBuffer:
|
||||||
buffer: []
|
buffer: []
|
||||||
bufferSize: 0
|
bufferSize: 0
|
||||||
|
@ -2296,7 +2295,7 @@ LineRenderer:
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 34894282}
|
m_GameObject: {fileID: 34894282}
|
||||||
m_Enabled: 1
|
m_Enabled: 1
|
||||||
m_CastShadows: 0
|
m_CastShadows: 1
|
||||||
m_ReceiveShadows: 1
|
m_ReceiveShadows: 1
|
||||||
m_DynamicOccludee: 1
|
m_DynamicOccludee: 1
|
||||||
m_StaticShadowCaster: 0
|
m_StaticShadowCaster: 0
|
||||||
|
@ -2310,7 +2309,7 @@ LineRenderer:
|
||||||
m_RenderingLayerMask: 1
|
m_RenderingLayerMask: 1
|
||||||
m_RendererPriority: 0
|
m_RendererPriority: 0
|
||||||
m_Materials:
|
m_Materials:
|
||||||
- {fileID: 2100000, guid: 62e10f2f26f232f49affb7663a8064fb, type: 2}
|
- {fileID: 10306, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
m_StaticBatchInfo:
|
m_StaticBatchInfo:
|
||||||
firstSubMesh: 0
|
firstSubMesh: 0
|
||||||
subMeshCount: 0
|
subMeshCount: 0
|
||||||
|
@ -2340,7 +2339,7 @@ LineRenderer:
|
||||||
m_Curve:
|
m_Curve:
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
time: 0
|
time: 0
|
||||||
value: 0.21601537
|
value: 0.10041046
|
||||||
inSlope: 0
|
inSlope: 0
|
||||||
outSlope: 0
|
outSlope: 0
|
||||||
tangentMode: 0
|
tangentMode: 0
|
||||||
|
@ -2383,7 +2382,7 @@ LineRenderer:
|
||||||
numCornerVertices: 0
|
numCornerVertices: 0
|
||||||
numCapVertices: 0
|
numCapVertices: 0
|
||||||
alignment: 0
|
alignment: 0
|
||||||
textureMode: 1
|
textureMode: 0
|
||||||
textureScale: {x: 1, y: 1}
|
textureScale: {x: 1, y: 1}
|
||||||
shadowBias: 0.5
|
shadowBias: 0.5
|
||||||
generateLightingData: 0
|
generateLightingData: 0
|
||||||
|
@ -2391,27 +2390,6 @@ LineRenderer:
|
||||||
m_UseWorldSpace: 1
|
m_UseWorldSpace: 1
|
||||||
m_Loop: 0
|
m_Loop: 0
|
||||||
m_ApplyActiveColorSpace: 1
|
m_ApplyActiveColorSpace: 1
|
||||||
--- !u!114 &34894286
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 34894282}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
GlobalObjectIdHash: 1869519831
|
|
||||||
InScenePlacedSourceGlobalObjectIdHash: 0
|
|
||||||
AlwaysReplicateAsRoot: 0
|
|
||||||
SynchronizeTransform: 1
|
|
||||||
ActiveSceneSynchronization: 0
|
|
||||||
SceneMigrationSynchronization: 1
|
|
||||||
SpawnWithObservers: 1
|
|
||||||
DontDestroyWithOwner: 0
|
|
||||||
AutoObjectParentSync: 1
|
|
||||||
--- !u!1001 &37294573
|
--- !u!1001 &37294573
|
||||||
PrefabInstance:
|
PrefabInstance:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
|
@ -87,7 +87,6 @@ public class HealthComponent : MonoBehaviour, ISquezeDamageReceiver
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
// blod regen
|
// blod regen
|
||||||
if (bloodRegen)
|
if (bloodRegen)
|
||||||
{
|
{
|
||||||
|
|
|
@ -93,22 +93,6 @@ public class Rope
|
||||||
return builder.Build();
|
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<T>(BufferSerializer<T> serializer) where T : IReaderWriter
|
/* public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
|
||||||
{
|
{
|
||||||
int pLen = 0;
|
int pLen = 0;
|
||||||
|
|
|
@ -2,9 +2,8 @@ using UnityEngine;
|
||||||
using UnityEngine.Assertions;
|
using UnityEngine.Assertions;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Unity.Netcode;
|
using Unity.Netcode;
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
public class RopeSimulator : NetworkBehaviour
|
public class RopeSimulator : MonoBehaviour
|
||||||
{
|
{
|
||||||
[Header("Solver")]
|
[Header("Solver")]
|
||||||
[SerializeField] int solveIterations = 10;
|
[SerializeField] int solveIterations = 10;
|
||||||
|
@ -20,20 +19,14 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
[SerializeField] Rope rope;
|
[SerializeField] Rope rope;
|
||||||
|
|
||||||
[Header("Networking")]
|
[Header("Networking")]
|
||||||
[SerializeField] float reconciliateThreshold = 1f;
|
|
||||||
[SerializeField] int reconciliateLerpFrameDuration = 5;
|
|
||||||
[SerializeField] CircularBuffer<RopeState> stateBuffer;
|
[SerializeField] CircularBuffer<RopeState> stateBuffer;
|
||||||
[SerializeField] float reconciliateCooldownDuration = 1f;
|
|
||||||
float reconciliateCooldown = -3f; // First reconciliate after n seconds after its begun to populate stateBuffer
|
|
||||||
private const int k_stateBufferSize = 128;
|
private const int k_stateBufferSize = 128;
|
||||||
private int currentTick => NetworkManager.Singleton.NetworkTickSystem.LocalTime.Tick;
|
private int currentTick => NetworkManager.Singleton.NetworkTickSystem.LocalTime.Tick;
|
||||||
|
|
||||||
bool initted = false;
|
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
this.rope = null;
|
|
||||||
stateBuffer = new CircularBuffer<RopeState>(k_stateBufferSize);
|
stateBuffer = new CircularBuffer<RopeState>(k_stateBufferSize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
|
@ -44,16 +37,10 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
private void OnDisable()
|
private void OnDisable()
|
||||||
{
|
{
|
||||||
GameManager.OnPlayersReady += Init;
|
GameManager.OnPlayersReady += Init;
|
||||||
|
|
||||||
if (NetworkManager.Singleton != null)
|
|
||||||
NetworkManager.Singleton.NetworkTickSystem.Tick -= NetworkTick;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
if (!initted) return;
|
|
||||||
|
|
||||||
reconciliateCooldown += Time.deltaTime;
|
|
||||||
rope.points.First().position = ropeStart.position;
|
rope.points.First().position = ropeStart.position;
|
||||||
rope.points.Last().position = ropeEnd.position;
|
rope.points.Last().position = ropeEnd.position;
|
||||||
Simulate(this.rope, Time.deltaTime, this.distBetweenRopePoints, this.solveIterations);
|
Simulate(this.rope, Time.deltaTime, this.distBetweenRopePoints, this.solveIterations);
|
||||||
|
@ -67,80 +54,6 @@ public class RopeSimulator : NetworkBehaviour
|
||||||
this.ropeEnd = players[1].transform;
|
this.ropeEnd = players[1].transform;
|
||||||
|
|
||||||
this.rope = RopeSimulator.BuildRope(this.ropeStart, this.ropeEnd, this.subDivision, this.distBetweenRopePoints);
|
this.rope = RopeSimulator.BuildRope(this.ropeStart, this.ropeEnd, this.subDivision, this.distBetweenRopePoints);
|
||||||
NetworkManager.Singleton.NetworkTickSystem.Tick += NetworkTick;
|
|
||||||
|
|
||||||
initted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void NetworkTick()
|
|
||||||
{
|
|
||||||
RopeState ropeState = new()
|
|
||||||
{
|
|
||||||
tick = currentTick,
|
|
||||||
nrope = Rope.ToNetworkRope(this.rope),
|
|
||||||
playerPositions = GameObject.FindObjectsByType<PlayerMovement>(FindObjectsSortMode.None).Select(p => new Vector3(p.transform.position.x, p.transform.position.y, p.GetComponent<NetworkObject>().NetworkObjectId)).ToArray()
|
|
||||||
};
|
|
||||||
|
|
||||||
stateBuffer.Add(ropeState, currentTick);
|
|
||||||
|
|
||||||
if (IsServer)
|
|
||||||
{
|
|
||||||
ServerToClientRopeStateRpc(ropeState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Rpc(SendTo.NotServer)]
|
|
||||||
private void ServerToClientRopeStateRpc(RopeState serverState)
|
|
||||||
{
|
|
||||||
RopeState clientState = this.stateBuffer.Get(serverState.tick);
|
|
||||||
Rope serverRope = Rope.FromNetworkRope(serverState.nrope, this.distBetweenRopePoints);
|
|
||||||
|
|
||||||
// Not enough information on client to reconcile
|
|
||||||
if (clientState.nrope.Equals(default(NetworkRope)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Rope previousClientRope = Rope.FromNetworkRope(clientState.nrope, this.distBetweenRopePoints);
|
|
||||||
float diff = Rope.CalcDiff(previousClientRope, serverRope);
|
|
||||||
// Debug.Log($"Diff: {diff}, ({serverState.tick})/({currentTick})");
|
|
||||||
|
|
||||||
if (diff > reconciliateThreshold && reconciliateCooldown >= reconciliateCooldownDuration)
|
|
||||||
{
|
|
||||||
reconciliateCooldown = 0f;
|
|
||||||
// StopCoroutine("ReconciliateLerp");
|
|
||||||
// StartCoroutine(ReconciliateLerp(serverRope));
|
|
||||||
Rope localCopy = serverRope.Copy(this.distBetweenRopePoints);
|
|
||||||
int ticksToResimulate = currentTick - serverState.tick;
|
|
||||||
Debug.Log($"Resimulating {ticksToResimulate} ticks");
|
|
||||||
for (int i = 1; i <= ticksToResimulate; i++)
|
|
||||||
{
|
|
||||||
RopeState intermediateState = stateBuffer.Get(serverState.tick + i);
|
|
||||||
Vector3 intermediateRopeStart = new Vector3(intermediateState.playerPositions[0].x, intermediateState.playerPositions[0].y, ropeStart.position.z);
|
|
||||||
Vector3 intermediateRopeEnd = new Vector3(intermediateState.playerPositions[1].x, intermediateState.playerPositions[1].y, ropeEnd.position.z);
|
|
||||||
rope.points.First().position = intermediateRopeStart;
|
|
||||||
rope.points.Last().position = intermediateRopeEnd;
|
|
||||||
|
|
||||||
Simulate(localCopy, 1f / (float) NetworkManager.Singleton.NetworkTickSystem.TickRate, this.distBetweenRopePoints, this.solveIterations);
|
|
||||||
}
|
|
||||||
localCopy.points.First().position = ropeStart.position;
|
|
||||||
localCopy.points.Last().position = ropeEnd.position;
|
|
||||||
|
|
||||||
StopCoroutine("LerpRope");
|
|
||||||
LerpRope(this.rope, localCopy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator LerpRope(Rope from, Rope to)
|
|
||||||
{
|
|
||||||
for (int i = 1; i <= reconciliateLerpFrameDuration; i++)
|
|
||||||
{
|
|
||||||
float t = (float) i / (float) reconciliateLerpFrameDuration;
|
|
||||||
for (int j = 0; j < this.rope.points.Length; j++)
|
|
||||||
{
|
|
||||||
from.points[j].position = Vector3.Lerp(this.rope.points[j].position, to.points[j].position, t);
|
|
||||||
from.points[j].prevPosition = Vector3.Lerp(this.rope.points[j].prevPosition, to.points[j].prevPosition, t);
|
|
||||||
}
|
|
||||||
yield return new WaitForEndOfFrame();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisplayRope()
|
private void DisplayRope()
|
||||||
|
|
|
@ -6,7 +6,6 @@ public struct RopeState : INetworkSerializable
|
||||||
{
|
{
|
||||||
public int tick;
|
public int tick;
|
||||||
public NetworkRope nrope;
|
public NetworkRope nrope;
|
||||||
public Vector3[] playerPositions;
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue