-
-
Save DoubleDeez/9e032411a5578264285f6c68905da8fa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Godot; | |
using System; | |
public class PositionReplicator : Node2D | |
{ | |
[Export] | |
private float SendPeriod = 0.06f; | |
[Export] | |
private float ForceSyncTime = 2f; | |
private float TimeUntilSend = 0f; | |
private float LastSyncTime = 0f; | |
private Vector2 LastPosition = new Vector2(); | |
private float LastRotation; | |
private Vector2 TargetPosition = new Vector2(); | |
private float TargetRotation; | |
public Vector2 LinearVelocity = new Vector2(); | |
public float AngularVelocity = 0f; | |
private float LastPacketTime = 0f; | |
private float LerpTime = 0f; | |
private bool IsEnabled = true; | |
private Node2D Target; | |
private bool IsMaster = false; | |
public delegate void MasterChangedEventHandler(bool IsMaster); | |
public event MasterChangedEventHandler OnMasterChangedEvent = delegate {}; | |
public delegate void SyncPositionEventHandler(Vector2 OldPos, Vector2 NewPos); | |
public event SyncPositionEventHandler OnSyncPositionEvent = delegate {}; | |
public delegate void SyncRotationEventHandler(float OldRot, float NewRot); | |
public event SyncRotationEventHandler OnSyncRotationEvent = delegate {}; | |
public event Func<Vector2> GetLinearVelocity = null; | |
public event Func<float> GetAngularVelocity = null; | |
private const string LOG_CAT = "LogPositionReplicator"; | |
public override void _Ready() | |
{ | |
if (Target == null) | |
{ | |
Target = this; | |
} | |
LastPacketTime = OS.GetTicksMsec(); | |
IsMaster = this.IsMaster(); | |
OnMasterChanged(IsMaster); | |
MDLog.AddLogCategoryProperties(LOG_CAT, new MDLogProperties(MDLogLevel.Info)); | |
} | |
public void SetTarget(Node2D InTarget) | |
{ | |
Target = InTarget; | |
TargetPosition = Target.Position; | |
TargetRotation = Target.Rotation; | |
} | |
public override void _Process(float Delta) | |
{ | |
if (IsEnabled == false) | |
{ | |
return; | |
} | |
bool CurIsMaster = this.IsMaster(); | |
if (CurIsMaster != IsMaster) | |
{ | |
IsMaster = CurIsMaster; | |
OnMasterChanged(IsMaster); | |
} | |
if (MDStatics.IsNetworkActive()) | |
{ | |
if (IsMaster) | |
{ | |
TimeUntilSend -= Delta; | |
if (TimeUntilSend <= 0f) | |
{ | |
if (GetLinearVelocity != null) | |
{ | |
LinearVelocity = GetLinearVelocity(); | |
} | |
else | |
{ | |
LinearVelocity = (Target.Position - LastPosition) / Delta; | |
} | |
if (GetAngularVelocity != null) | |
{ | |
AngularVelocity = GetAngularVelocity(); | |
} | |
else | |
{ | |
AngularVelocity = (Target.Rotation - LastRotation) / Delta; | |
} | |
TimeUntilSend = SendPeriod; | |
RpcUnreliable(nameof(SyncPosition), Target.Position, Target.Rotation, LinearVelocity, AngularVelocity); | |
} | |
LastPosition = Target.Position; | |
LastRotation = Target.Rotation; | |
} | |
} | |
} | |
public override void _PhysicsProcess(float Delta) | |
{ | |
if (IsEnabled == false) | |
{ | |
return; | |
} | |
if (MDStatics.IsNetworkActive() && IsMaster == false) | |
{ | |
Vector2 OldPos = Target.Position; | |
float OldRot = Target.Rotation; | |
if (LerpTime > 0) | |
{ | |
Target.Position += (TargetPosition - Target.Position) / LerpTime * Delta; | |
Target.Rotation += (TargetRotation - Target.Rotation) / LerpTime * Delta; | |
LerpTime -= Delta; | |
} | |
else | |
{ | |
Target.Position = TargetPosition; | |
Target.Rotation = TargetRotation; | |
} | |
OnSyncPositionEvent(OldPos, Target.Position); | |
OnSyncRotationEvent(OldRot, Target.Rotation); | |
} | |
} | |
public void SetIsEnabled(bool InIsEnabled) | |
{ | |
if (InIsEnabled != IsEnabled) | |
{ | |
IsEnabled = InIsEnabled; | |
} | |
} | |
[Puppet] | |
void SyncPosition(Vector2 InPosition, float InRotation, Vector2 LinVelocity, float AngVelocity) | |
{ | |
float CurrentTime = OS.GetTicksMsec() / 1000f; | |
float TimeDelta = CurrentTime - LastPacketTime; | |
float Jitter = TimeDelta - SendPeriod; | |
LerpTime = SendPeriod - Jitter; | |
LastPacketTime = CurrentTime; | |
TargetPosition = InPosition + (LinVelocity * TimeDelta); | |
TargetRotation = InRotation + (AngVelocity * TimeDelta); | |
LinearVelocity = LinVelocity; | |
AngVelocity = AngularVelocity; | |
if ((LastSyncTime + ForceSyncTime) < CurrentTime) | |
{ | |
Vector2 OldPos = Target.Position; | |
float OldRot = Target.Rotation; | |
LastSyncTime = CurrentTime; | |
Target.Position = InPosition; | |
Target.Rotation = InRotation; | |
OnSyncPositionEvent(OldPos, Target.Position); | |
OnSyncRotationEvent(OldRot, Target.Rotation); | |
} | |
} | |
private void OnMasterChanged(bool IsMaster) | |
{ | |
OnMasterChangedEvent(IsMaster); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment