mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-01-10 15:53:19 +00:00
298 lines
7.5 KiB
C#
298 lines
7.5 KiB
C#
using QuantumUNET.Messages;
|
|
using QuantumUNET.Transport;
|
|
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.Networking;
|
|
|
|
namespace QuantumUNET.Components
|
|
{
|
|
public class QNetworkTransformChild : QNetworkBehaviour
|
|
{
|
|
public Transform Target
|
|
{
|
|
get => m_Target;
|
|
set => m_Target = value;
|
|
}
|
|
|
|
public uint ChildIndex => m_ChildIndex;
|
|
|
|
public float SendInterval
|
|
{
|
|
get => m_SendInterval;
|
|
set => m_SendInterval = value;
|
|
}
|
|
|
|
public float MovementThreshold
|
|
{
|
|
get => m_MovementThreshold;
|
|
set => m_MovementThreshold = value;
|
|
}
|
|
|
|
public float InterpolateRotation
|
|
{
|
|
get => m_InterpolateRotation;
|
|
set => m_InterpolateRotation = value;
|
|
}
|
|
|
|
public float InterpolateMovement
|
|
{
|
|
get => m_InterpolateMovement;
|
|
set => m_InterpolateMovement = value;
|
|
}
|
|
|
|
public float LastSyncTime { get; private set; }
|
|
public Vector3 TargetSyncPosition => m_TargetSyncPosition;
|
|
public Quaternion TargetSyncRotation3D => m_TargetSyncRotation3D;
|
|
|
|
private void Awake()
|
|
{
|
|
m_PrevPosition = m_Target.localPosition;
|
|
m_PrevRotation = m_Target.localRotation;
|
|
if (LocalPlayerAuthority)
|
|
{
|
|
m_LocalTransformWriter = new QNetworkWriter();
|
|
}
|
|
}
|
|
|
|
public override bool OnSerialize(QNetworkWriter writer, bool initialState)
|
|
{
|
|
if (!initialState)
|
|
{
|
|
if (SyncVarDirtyBits == 0U)
|
|
{
|
|
writer.WritePackedUInt32(0U);
|
|
return false;
|
|
}
|
|
writer.WritePackedUInt32(1U);
|
|
}
|
|
SerializeModeTransform(writer);
|
|
return true;
|
|
}
|
|
|
|
private void SerializeModeTransform(QNetworkWriter writer)
|
|
{
|
|
writer.Write(m_Target.localPosition);
|
|
QNetworkTransform.SerializeRotation(writer, m_Target.localRotation);
|
|
m_PrevPosition = m_Target.localPosition;
|
|
m_PrevRotation = m_Target.localRotation;
|
|
}
|
|
|
|
public override void OnDeserialize(QNetworkReader reader, bool initialState)
|
|
{
|
|
if (!IsServer || !QNetworkServer.localClientActive)
|
|
{
|
|
if (!initialState)
|
|
{
|
|
if (reader.ReadPackedUInt32() == 0U)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
UnserializeModeTransform(reader, initialState);
|
|
LastSyncTime = Time.time;
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000488 RID: 1160 RVA: 0x00019B44 File Offset: 0x00017D44
|
|
private void UnserializeModeTransform(QNetworkReader reader, bool initialState)
|
|
{
|
|
if (HasAuthority)
|
|
{
|
|
reader.ReadVector3();
|
|
QNetworkTransform.DeserializeRotation(reader);
|
|
}
|
|
else
|
|
{
|
|
m_TargetSyncPosition = reader.ReadVector3();
|
|
m_TargetSyncRotation3D = QNetworkTransform.DeserializeRotation(reader);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000489 RID: 1161 RVA: 0x00019C4B File Offset: 0x00017E4B
|
|
private void FixedUpdate()
|
|
{
|
|
if (IsServer)
|
|
{
|
|
FixedUpdateServer();
|
|
}
|
|
if (IsClient)
|
|
{
|
|
FixedUpdateClient();
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600048A RID: 1162 RVA: 0x00019C74 File Offset: 0x00017E74
|
|
private void FixedUpdateServer()
|
|
{
|
|
if (SyncVarDirtyBits == 0U)
|
|
{
|
|
if (QNetworkServer.active)
|
|
{
|
|
if (IsServer)
|
|
{
|
|
if (GetNetworkSendInterval() != 0f)
|
|
{
|
|
var num = (m_Target.localPosition - m_PrevPosition).sqrMagnitude;
|
|
if (num < MovementThreshold)
|
|
{
|
|
num = Quaternion.Angle(m_PrevRotation, m_Target.localRotation);
|
|
if (num < MovementThreshold)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
SetDirtyBit(1U);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600048B RID: 1163 RVA: 0x00019D24 File Offset: 0x00017F24
|
|
private void FixedUpdateClient()
|
|
{
|
|
if (LastSyncTime != 0f)
|
|
{
|
|
if (QNetworkServer.active || QNetworkClient.active)
|
|
{
|
|
if (IsServer || IsClient)
|
|
{
|
|
if (GetNetworkSendInterval() != 0f)
|
|
{
|
|
if (!HasAuthority)
|
|
{
|
|
if (LastSyncTime != 0f)
|
|
{
|
|
m_Target.localPosition = m_InterpolateMovement > 0f
|
|
? Vector3.Lerp(m_Target.localPosition, m_TargetSyncPosition, m_InterpolateMovement)
|
|
: m_TargetSyncPosition;
|
|
m_Target.localRotation = m_InterpolateRotation > 0f
|
|
? Quaternion.Slerp(m_Target.localRotation, m_TargetSyncRotation3D, m_InterpolateRotation)
|
|
: m_TargetSyncRotation3D;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (HasAuthority)
|
|
{
|
|
if (LocalPlayerAuthority)
|
|
{
|
|
if (!QNetworkServer.active)
|
|
{
|
|
if (Time.time - m_LastClientSendTime > GetNetworkSendInterval())
|
|
{
|
|
SendTransform();
|
|
m_LastClientSendTime = Time.time;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool HasMoved()
|
|
{
|
|
var num = (m_Target.localPosition - m_PrevPosition).sqrMagnitude;
|
|
bool result;
|
|
if (num > 1E-05f)
|
|
{
|
|
result = true;
|
|
}
|
|
else
|
|
{
|
|
num = Quaternion.Angle(m_Target.localRotation, m_PrevRotation);
|
|
result = num > 1E-05f;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
[Client]
|
|
private void SendTransform()
|
|
{
|
|
if (HasMoved() && QClientScene.readyConnection != null)
|
|
{
|
|
m_LocalTransformWriter.StartMessage(16);
|
|
m_LocalTransformWriter.Write(NetId);
|
|
m_LocalTransformWriter.WritePackedUInt32(m_ChildIndex);
|
|
SerializeModeTransform(m_LocalTransformWriter);
|
|
m_PrevPosition = m_Target.localPosition;
|
|
m_PrevRotation = m_Target.localRotation;
|
|
m_LocalTransformWriter.FinishMessage();
|
|
QClientScene.readyConnection.SendWriter(m_LocalTransformWriter, GetNetworkChannel());
|
|
}
|
|
}
|
|
|
|
internal static void HandleChildTransform(QNetworkMessage netMsg)
|
|
{
|
|
var networkInstanceId = netMsg.Reader.ReadNetworkId();
|
|
var num = netMsg.Reader.ReadPackedUInt32();
|
|
var gameObject = QNetworkServer.FindLocalObject(networkInstanceId);
|
|
if (gameObject == null)
|
|
{
|
|
Debug.LogError("Received NetworkTransformChild data for GameObject that doesn't exist");
|
|
}
|
|
else
|
|
{
|
|
var components = gameObject.GetComponents<QNetworkTransformChild>();
|
|
if (components == null || components.Length == 0)
|
|
{
|
|
Debug.LogError("HandleChildTransform no children");
|
|
}
|
|
else if (num >= (ulong)components.Length)
|
|
{
|
|
Debug.LogError("HandleChildTransform childIndex invalid");
|
|
}
|
|
else
|
|
{
|
|
var networkTransformChild = components[(int)(UIntPtr)num];
|
|
if (networkTransformChild == null)
|
|
{
|
|
Debug.LogError("HandleChildTransform null target");
|
|
}
|
|
else if (!networkTransformChild.LocalPlayerAuthority)
|
|
{
|
|
Debug.LogError("HandleChildTransform no localPlayerAuthority");
|
|
}
|
|
else if (!netMsg.Connection.ClientOwnedObjects.Contains(networkInstanceId))
|
|
{
|
|
Debug.LogWarning("NetworkTransformChild netId:" + networkInstanceId + " is not for a valid player");
|
|
}
|
|
else
|
|
{
|
|
networkTransformChild.UnserializeModeTransform(netMsg.Reader, false);
|
|
networkTransformChild.LastSyncTime = Time.time;
|
|
if (!networkTransformChild.IsClient)
|
|
{
|
|
networkTransformChild.m_Target.localPosition = networkTransformChild.m_TargetSyncPosition;
|
|
networkTransformChild.m_Target.localRotation = networkTransformChild.m_TargetSyncRotation3D;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override int GetNetworkChannel() => 1;
|
|
public override float GetNetworkSendInterval() => m_SendInterval;
|
|
public Transform m_Target;
|
|
public uint m_ChildIndex;
|
|
public QNetworkTransform m_Root;
|
|
public float m_SendInterval = 0.1f;
|
|
public float m_MovementThreshold = 0.001f;
|
|
public float m_InterpolateRotation = 0.5f;
|
|
public float m_InterpolateMovement = 0.5f;
|
|
private Vector3 m_TargetSyncPosition;
|
|
private Quaternion m_TargetSyncRotation3D;
|
|
private float m_LastClientSendTime;
|
|
private Vector3 m_PrevPosition;
|
|
private Quaternion m_PrevRotation;
|
|
private const float k_LocalMovementThreshold = 1E-05f;
|
|
private const float k_LocalRotationThreshold = 1E-05f;
|
|
private QNetworkWriter m_LocalTransformWriter;
|
|
}
|
|
}
|