This commit is contained in:
in0finite 2021-01-07 16:51:30 +01:00
parent 506bca3faf
commit a9e70bf7cc

View file

@ -122,7 +122,7 @@ namespace SanAndreasUnity.Behaviours.Peds
// (tr, rotation) => tr.localRotation = Quaternion.Euler(rotation)); // (tr, rotation) => tr.localRotation = Quaternion.Euler(rotation));
RegisterDictionaryCallback( RegisterDictionaryCallback(
m_syncDictionaryBoneVelocities, m_syncDictionaryBoneVelocities,
(tr, velocity) => tr.GetComponent<Rigidbody>().velocity = tr.TransformVector(velocity)); (tr, receivedVelocity) => tr.GetComponent<Rigidbody>().velocity = GetReceivedVelocityAsWorld(tr, receivedVelocity));
} }
private void RegisterDictionaryCallback<T>(SyncDictionary<int, T> dict, System.Action<Transform, T> action) private void RegisterDictionaryCallback<T>(SyncDictionary<int, T> dict, System.Action<Transform, T> action)
@ -178,7 +178,7 @@ namespace SanAndreasUnity.Behaviours.Peds
// assign initial velocities // assign initial velocities
foreach (var pair in m_rigidBodiesDict) foreach (var pair in m_rigidBodiesDict)
{ {
m_syncDictionaryBoneVelocities.Add(pair.Key, pair.Value.velocity); m_syncDictionaryBoneVelocities.Add(pair.Key, GetVelocityForSending(pair.Value));
} }
} }
@ -199,7 +199,7 @@ namespace SanAndreasUnity.Behaviours.Peds
foreach (var pair in m_rigidBodiesDict) foreach (var pair in m_rigidBodiesDict)
{ {
Vector3 velocity = pair.Value.transform.InverseTransformVector(pair.Value.velocity); Vector3 velocity = GetVelocityForSending(pair.Value);
if (m_syncDictionaryBoneVelocities[pair.Key] != velocity) if (m_syncDictionaryBoneVelocities[pair.Key] != velocity)
m_syncDictionaryBoneVelocities[pair.Key] = velocity; m_syncDictionaryBoneVelocities[pair.Key] = velocity;
} }
@ -211,33 +211,40 @@ namespace SanAndreasUnity.Behaviours.Peds
int boneId = pair.Key; int boneId = pair.Key;
Transform tr = pair.Value; Transform tr = pair.Value;
// position // rotation
if (m_syncDictionaryBoneRotations.TryGetValue(boneId, out Vector3 rotation))
tr.localRotation = Quaternion.Euler(rotation);
// after rotation is applied, transform velocity to local space and predict position based on it
if (m_syncDictionaryBonePositions.TryGetValue(boneId, out Vector3 pos)) if (m_syncDictionaryBonePositions.TryGetValue(boneId, out Vector3 pos))
{ {
Vector3 targetPos = pos; Vector3 targetPos = pos;
// predict position based on velocity and sync interval // predict position based on velocity and sync interval
// if (m_syncDictionaryBoneVelocities.TryGetValue(boneId, out Vector3 velocity)) // if (boneId == 0) // only for root bone
// { // {
// if (boneId == 0) // only root bone // if (m_syncDictionaryBoneVelocities.TryGetValue(boneId, out Vector3 receivedVelocity))
// targetPos += velocity * this.syncInterval; // {
// Vector3 localVelocity = GetReceivedVelocityAsLocal(tr, receivedVelocity);
// targetPos += localVelocity * this.syncInterval;
// }
// } // }
tr.localPosition = targetPos; tr.localPosition = targetPos;
} }
// rotation
if (m_syncDictionaryBoneRotations.TryGetValue(boneId, out Vector3 rotation))
tr.localRotation = Quaternion.Euler(rotation);
} }
// apply velocity on clients - this is done by rigid bodies ? // apply velocity on clients - this is done by rigid bodies ?
// foreach (var pair in m_syncDictionaryBoneVelocities) // foreach (var pair in m_syncDictionaryBoneVelocities)
// { // {
// int boneId = pair.Key; // int boneId = pair.Key;
// Vector3 receivedVelocity = pair.Value;
// if (m_framesDict.TryGetValue(boneId, out Transform tr)) // if (m_framesDict.TryGetValue(boneId, out Transform tr))
// tr.position += pair.Value * Time.deltaTime; // {
// Vector3 localVelocity = GetReceivedVelocityAsLocal(tr, receivedVelocity);
// tr.localPosition += localVelocity * Time.deltaTime;
// }
// } // }
} }
} }
@ -246,5 +253,22 @@ namespace SanAndreasUnity.Behaviours.Peds
{ {
this.syncInterval = 1.0f / PedManager.Instance.ragdollSyncRate; this.syncInterval = 1.0f / PedManager.Instance.ragdollSyncRate;
} }
private static Vector3 GetVelocityForSending(Rigidbody rb)
{
// it's better to send local velocity, because rotation of ragdoll can change very fast, and so
// will the world velocity
return rb.transform.InverseTransformVector(rb.velocity);
}
private static Vector3 GetReceivedVelocityAsLocal(Transform tr, Vector3 receivedVelocity)
{
return receivedVelocity;
}
private static Vector3 GetReceivedVelocityAsWorld(Transform tr, Vector3 receivedVelocity)
{
return tr.TransformVector(receivedVelocity);
}
} }
} }