public void CopyFrom(TransformTrack prev) { netTime = prev.netTime; pos = prev.pos; rot = prev.rot; vel = prev.vel; angularVel = prev.angularVel; isSleeping = prev.isSleeping; }
public void AddRemoteDataPoint(VNetMessageNetTransformData message) { TransformTrack temp = new TransformTrack(); temp.angularVel = message.rbRotation; temp.vel = message.rbVelocity; temp.pos = message.localPosition; temp.rot = message.localRotation; temp.isSleeping = message.rbSleeping; temp.netTime = message.time; m_transformQueue.AddDataPoint(temp); }
public bool TakeLocalControl() { if (isLocalControlled) { return(true); } if (isRemoteControlled) { return(false); } localControlStartTime = VNetSessionTime.Inst.GetServerTime(); isLocalControlled = true; TransformTrack track = new TransformTrack(); track.netTime = VNetSessionTime.Inst.GetServerTime() - VNetManager.Inst.TransformUpdateDelay * 2; track.pos = transform.localPosition; track.rot = transform.localRotation; if (rigidBody) { track.angularVel = rigidBody.angularVelocity; track.vel = rigidBody.velocity; track.isSleeping = rigidBody.IsSleeping(); } m_clientPrev = track; track = new TransformTrack(); track.netTime = VNetSessionTime.Inst.GetServerTime() - VNetManager.Inst.TransformUpdateDelay; track.pos = transform.localPosition; track.rot = transform.localRotation; if (rigidBody) { track.angularVel = rigidBody.angularVelocity; track.vel = rigidBody.velocity; track.isSleeping = rigidBody.IsSleeping(); } m_clientPost = track; VNetMessageTransformControl controlMessage = new VNetMessageTransformControl(); controlMessage.transformUID = netIdentifier; controlMessage.clientUID = VNet.Inst.GetUID(); controlMessage.requestTime = localControlStartTime; controllingClient = VNet.Inst.GetUID(); VNet.Inst.SendToLobby(controlMessage, true); return(true); }
void LerpRemote(TransformTrack a, TransformTrack b, float t) { if (a == null || b == null) { return; } transform.localPosition = Vector3.LerpUnclamped(a.pos, b.pos, t); transform.localRotation = Quaternion.LerpUnclamped(a.rot, b.rot, t); if (rigidBody != null) { rigidBody.velocity = Vector3.LerpUnclamped(a.vel, b.vel, t); rigidBody.angularVelocity = Vector3.LerpUnclamped(a.angularVel, b.angularVel, t); } }
private TransformTrack GetPostPoint(float time) { float bestTime = float.MaxValue; TransformTrack best = null; foreach (TransformTrack t in m_queue) { if (t.netTime < bestTime && t.netTime >= time) { bestTime = t.netTime; best = t; } } return(best); }
public TransformTrack MakeTrack() { var keyframes = KeyframeTrack.FromMatrices(Times, Transforms); keyframes.RemoveTrivialTranslations(); keyframes.RemoveTrivialRotations(); keyframes.RemoveTrivialScales(); keyframes.RemoveTrivialFrames(); var track = TransformTrack.FromKeyframes(keyframes); track.Flags = 0; track.Name = Bone.Name; return(track); }
public bool RemoteTakeControl(float time, ulong client) { bool pastTime = localControlStartTime > time; if (isLocalControlled == false || pastTime) { isRemoteControlled = true; controllingClient = client; if (pastTime) { localControlStartTime = 0; isLocalControlled = false; } TransformTrack track = new TransformTrack(); track.netTime = VNetSessionTime.Inst.GetServerTime() - VNetManager.Inst.TransformUpdateDelay * 2; track.pos = transform.localPosition; track.rot = transform.localRotation; if (rigidBody) { track.angularVel = rigidBody.angularVelocity; track.vel = rigidBody.velocity; track.isSleeping = rigidBody.IsSleeping(); } m_transformQueue.AddDataPoint(track); track = new TransformTrack(); track.netTime = VNetSessionTime.Inst.GetServerTime() - VNetManager.Inst.TransformUpdateDelay; track.pos = transform.localPosition; track.rot = transform.localRotation; if (rigidBody) { track.angularVel = rigidBody.angularVelocity; track.vel = rigidBody.velocity; track.isSleeping = rigidBody.IsSleeping(); } m_transformQueue.AddDataPoint(track); return(true); } return(false); }
void Start() { if (netIdentifier == 0) { throw new UnityException("VNetTransform must have a Net Identifier!"); } VNetTransformManager.Inst.RegisterTransform(this); rigidBody = GetComponent <Rigidbody>(); m_transformQueue = new TransformQueue(); m_clientPrev = new TransformTrack(); m_clientPost = new TransformTrack(); if (rigidBody) { usedGravity = rigidBody.useGravity; } isSleeping = false; }
private TransformTrack GetPrevPoint(float time) { float bestTime = -1; TransformTrack best = null; foreach (TransformTrack t in m_queue) { if (t.netTime > bestTime && t.netTime <= time) { bestTime = t.netTime; best = t; } } if (best != null) { while (m_queue.Peek().netTime < bestTime) { m_queue.Dequeue(); } } return(best); }
public void GetDataPoints(float time, out TransformTrack prev, out TransformTrack post) { prev = GetPrevPoint(time); post = GetPostPoint(time); }
public void AddDataPoint(TransformTrack track) { m_queue.Enqueue(track); }
// Update is called once per frame void Update() { if (isRemoteControlled) { UpdateRemoteControl(); return; } if (isLocalControlled) { // See where we expect the values to be... float serverTime = VNetSessionTime.Inst.GetServerTime(); float t = (serverTime - m_clientPrev.netTime) / (m_clientPost.netTime - m_clientPrev.netTime); Vector3 localPos = Vector3.LerpUnclamped(m_clientPrev.pos, m_clientPost.pos, t); // compare this to current values float expectedOffSq = (localPos - transform.localPosition).sqrMagnitude; bool updateRemote = false; if (expectedOffSq > VNetManager.Inst.TransformPredictionSqDstOffset) { updateRemote = true; } if (!updateRemote) { Quaternion localRot = Quaternion.SlerpUnclamped(m_clientPrev.rot, m_clientPost.rot, t); Vector3 forw = localRot * Vector3.forward; Vector3 comp = transform.localRotation * Vector3.forward; if (Vector3.Dot(forw, comp) < VNetManager.Inst.TransformPredictionDotOffset) { updateRemote = true; } } if (updateRemote) { lastSendTime = serverTime; // Create and send a message VNetMessageNetTransformData data = new VNetMessageNetTransformData(); data.transformUID = netIdentifier; data.time = serverTime; data.localPosition = transform.localPosition; data.localRotation = transform.localRotation; if (rigidBody != null) { data.rbSleeping = rigidBody.IsSleeping(); data.rbVelocity = rigidBody.velocity; data.rbRotation = rigidBody.angularVelocity; } // This is now a reliable message VNet.Inst.SendToLobby(data, true); // Update the post and prev TransformTrack temp = m_clientPrev; m_clientPrev = m_clientPost; m_clientPost = temp; m_clientPost.netTime = lastSendTime; m_clientPost.pos = transform.localPosition; m_clientPost.rot = transform.localRotation; if (rigidBody != null) { data.rbSleeping = rigidBody.IsSleeping(); data.rbVelocity = rigidBody.velocity; data.rbRotation = rigidBody.angularVelocity; } } } }