Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(NetworkTransformBase): Add Velocity and AngularVelocity #3802

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
58 changes: 58 additions & 0 deletions Assets/Mirror/Components/NetworkTransform/NetworkTransformBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,54 @@ protected override void OnValidate()
if (coordinateSpace == CoordinateSpace.World) synchronizationSelections &= ~SyncInterpolateOptions.Scale;
}

// These are in global coordinates for calculating velocity and angular velocity.
Vector3 lastPosition;
Quaternion lastRotation;

public Vector3 velocity { get; internal set; } = Vector3.zero;
public Vector3 angularVelocity { get; internal set; } = Vector3.zero;

protected virtual void Start()
{
// set target to self if none yet
if (target == null) target = transform;

// Set last position and rotation to current values
// so we can calculate velocity and angular velocity.
target.GetPositionAndRotation(out lastPosition, out lastRotation);
}

protected virtual void Update()
{
// set target to self if none yet
if (target == null) target = transform;

// Use global coordinates for velocity and angular velocity.
target.GetPositionAndRotation(out Vector3 pos, out Quaternion rot);

// Update velocity and angular velocity
velocity = (pos - lastPosition) / Time.deltaTime;
CalculateAngularVelocity(rot);

// Update last position and rotation
lastPosition = pos;
lastRotation = rot;
}

void CalculateAngularVelocity(Quaternion currentRot)
{
// calculate angle between two rotations
Quaternion deltaRotation = currentRot * Quaternion.Inverse(lastRotation);
MrGadget1024 marked this conversation as resolved.
Show resolved Hide resolved
//Quaternion deltaRotation = (currentRot * Quaternion.Inverse(lastRotation)).normalize;

// convert to angle axis
deltaRotation.ToAngleAxis(out float angle, out Vector3 axis);

// we assume the angle is always the shortest path
// we don't need to check for 360 degree rotations
angularVelocity = axis * angle * Mathf.Deg2Rad / Time.deltaTime;
}

// snapshot functions //////////////////////////////////////////////////
// get local/world position
protected virtual Vector3 GetPosition() =>
Expand Down Expand Up @@ -394,6 +442,16 @@ public virtual void ResetState()
// so let's clear the buffers.
serverSnapshots.Clear();
clientSnapshots.Clear();

// set target to self if none yet
if (target == null) target = transform;

// Reset last position and rotation
target.GetPositionAndRotation(out lastPosition, out lastRotation);

// Reset velocity / angular velocity
velocity = Vector3.zero;
angularVelocity = Vector3.zero;
}

public virtual void Reset()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ public class NetworkTransformReliable : NetworkTransformBase
protected int lastClientCount = 1;

// update //////////////////////////////////////////////////////////////
void Update()
protected override void Update()
{
// if server then always sync to others.
if (isServer) UpdateServer();
// 'else if' because host mode shouldn't send anything to server.
// it is the server. don't overwrite anything there.
else if (isClient) UpdateClient();

base.Update();
}

void LateUpdate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ public class NetworkTransformUnreliable : NetworkTransformBase

// update //////////////////////////////////////////////////////////////
// Update applies interpolation
void Update()
protected override void Update()
{
if (isServer) UpdateServerInterpolation();
// for all other clients (and for local player if !authority),
// we need to apply snapshots from the buffer.
// 'else if' because host mode shouldn't interpolate client
else if (isClient && !IsClientWithAuthority) UpdateClientInterpolation();

base.Update();
}

// LateUpdate broadcasts.
Expand Down