quantum-space-buddies/QuantumUNET/Components/QNetworkAnimator.cs

387 lines
9.8 KiB
C#
Raw Normal View History

2020-12-07 21:19:16 +00:00
using QuantumUNET.Messages;
using QuantumUNET.Transport;
2020-12-07 21:19:16 +00:00
using UnityEngine;
2020-11-08 14:41:16 +00:00
2020-12-07 21:19:16 +00:00
namespace QuantumUNET.Components
2020-11-08 14:41:16 +00:00
{
2020-12-23 12:58:45 +00:00
public class QNetworkAnimator : QNetworkBehaviour
2020-12-02 21:29:53 +00:00
{
2020-12-23 12:58:45 +00:00
private static readonly QAnimationMessage AnimationMessage = new QAnimationMessage();
private static readonly QAnimationParametersMessage ParametersMessage = new QAnimationParametersMessage();
private static readonly QAnimationTriggerMessage TriggersMessage = new QAnimationTriggerMessage();
2020-11-08 16:10:10 +00:00
2020-12-02 21:29:53 +00:00
private Animator m_Animator;
private uint m_ParameterSendBits;
private int m_AnimationHash;
private int m_TransitionHash;
2020-12-23 12:58:45 +00:00
private QNetworkWriter m_ParameterWriter;
2020-12-02 21:29:53 +00:00
private float m_SendTimer;
2020-11-08 14:41:16 +00:00
2020-12-02 21:29:53 +00:00
public Animator animator
{
2020-12-18 20:28:22 +00:00
get => m_Animator;
2020-12-02 21:29:53 +00:00
set
{
m_Animator = value;
m_ParameterSendBits = 0U;
}
}
2020-11-08 14:41:16 +00:00
2020-12-02 21:29:53 +00:00
public void SetParameterAutoSend(int index, bool value)
{
if (value)
{
2020-12-02 21:29:53 +00:00
m_ParameterSendBits |= (uint)(1 << index);
}
2020-12-02 21:29:53 +00:00
else
{
2020-12-02 21:29:53 +00:00
m_ParameterSendBits &= (uint)~(1 << index);
}
2020-12-02 21:29:53 +00:00
}
2020-11-08 14:41:16 +00:00
public bool GetParameterAutoSend(int index) =>
((int)m_ParameterSendBits & (1 << index)) != 0;
2020-11-08 14:41:16 +00:00
public override void OnStartAuthority() =>
2020-12-23 12:58:45 +00:00
m_ParameterWriter = new QNetworkWriter();
2020-11-08 14:41:16 +00:00
public void FixedUpdate()
2020-12-02 21:29:53 +00:00
{
if (m_ParameterWriter == null)
{
return;
}
CheckSendRate();
if (!CheckAnimStateChanged(out var stateHash, out var normalizedTime))
{
return;
}
2020-12-23 12:58:45 +00:00
var animationMessage = new QAnimationMessage
2020-12-02 21:29:53 +00:00
{
netId = NetId,
stateHash = stateHash,
normalizedTime = normalizedTime
};
2020-11-08 16:10:10 +00:00
2020-12-02 21:29:53 +00:00
m_ParameterWriter.SeekZero();
WriteParameters(m_ParameterWriter, false);
animationMessage.parameters = m_ParameterWriter.ToArray();
2020-11-08 16:10:10 +00:00
2020-12-23 12:58:45 +00:00
if (HasAuthority || QClientScene.readyConnection != null)
2020-12-02 21:29:53 +00:00
{
2020-12-23 12:58:45 +00:00
QClientScene.readyConnection.Send(40, animationMessage);
2020-12-02 21:29:53 +00:00
}
else
{
if (!IsServer || LocalPlayerAuthority)
{
return;
}
2020-12-23 12:58:45 +00:00
QNetworkServer.SendToReady(gameObject, 40, animationMessage);
2020-12-02 21:29:53 +00:00
}
}
2020-11-08 14:41:16 +00:00
2020-12-02 21:29:53 +00:00
private bool CheckAnimStateChanged(out int stateHash, out float normalizedTime)
{
stateHash = 0;
normalizedTime = 0.0f;
if (m_Animator.IsInTransition(0))
{
var animatorTransitionInfo = m_Animator.GetAnimatorTransitionInfo(0);
if (animatorTransitionInfo.fullPathHash == m_TransitionHash)
{
return false;
}
m_TransitionHash = animatorTransitionInfo.fullPathHash;
m_AnimationHash = 0;
return true;
}
var animatorStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
if (animatorStateInfo.fullPathHash == m_AnimationHash)
{
return false;
}
if (m_AnimationHash != 0)
{
stateHash = animatorStateInfo.fullPathHash;
normalizedTime = animatorStateInfo.normalizedTime;
}
m_TransitionHash = 0;
m_AnimationHash = animatorStateInfo.fullPathHash;
return true;
}
2020-11-08 14:41:16 +00:00
2020-12-02 21:29:53 +00:00
private void CheckSendRate()
{
if (GetNetworkSendInterval() == 0.0 || m_SendTimer >= Time.time)
{
return;
}
m_SendTimer = Time.time + GetNetworkSendInterval();
2020-12-23 12:58:45 +00:00
var parametersMessage = new QAnimationParametersMessage
2020-12-02 21:29:53 +00:00
{
netId = NetId
};
m_ParameterWriter.SeekZero();
WriteParameters(m_ParameterWriter, true);
parametersMessage.parameters = m_ParameterWriter.ToArray();
2020-12-23 12:58:45 +00:00
if (HasAuthority && QClientScene.readyConnection != null)
2020-12-02 21:29:53 +00:00
{
2020-12-23 12:58:45 +00:00
QClientScene.readyConnection.Send(41, parametersMessage);
2020-12-02 21:29:53 +00:00
}
else
{
if (!IsServer || LocalPlayerAuthority)
{
2020-12-02 21:29:53 +00:00
return;
}
2020-12-23 12:58:45 +00:00
QNetworkServer.SendToReady(gameObject, 41, parametersMessage);
2020-12-02 21:29:53 +00:00
}
}
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
internal void HandleAnimMsg(QAnimationMessage msg, QNetworkReader reader)
2020-12-02 21:29:53 +00:00
{
if (HasAuthority)
{
return;
}
if (msg.stateHash != 0)
{
m_Animator.Play(msg.stateHash, 0, msg.normalizedTime);
}
ReadParameters(reader, false);
}
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
internal void HandleAnimParamsMsg(QAnimationParametersMessage msg, QNetworkReader reader)
2020-12-02 21:29:53 +00:00
{
if (HasAuthority)
{
return;
}
ReadParameters(reader, true);
}
2020-11-08 14:41:16 +00:00
internal void HandleAnimTriggerMsg(int hash) => m_Animator.SetTrigger(hash);
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
private void WriteParameters(QNetworkWriter writer, bool autoSend)
2020-12-02 21:29:53 +00:00
{
for (var index = 0; index < m_Animator.parameters.Length; ++index)
2020-12-02 21:29:53 +00:00
{
if (!autoSend || GetParameterAutoSend(index))
{
var parameter = m_Animator.parameters[index];
switch (parameter.type)
{
case AnimatorControllerParameterType.Int:
writer.WritePackedUInt32((uint)m_Animator.GetInteger(parameter.nameHash));
break;
2020-12-03 08:28:05 +00:00
2020-12-02 21:29:53 +00:00
case AnimatorControllerParameterType.Float:
writer.Write(m_Animator.GetFloat(parameter.nameHash));
break;
2020-12-03 08:28:05 +00:00
2020-12-02 21:29:53 +00:00
case AnimatorControllerParameterType.Bool:
writer.Write(m_Animator.GetBool(parameter.nameHash));
break;
}
}
}
}
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
private void ReadParameters(QNetworkReader reader, bool autoSend)
2020-12-02 21:29:53 +00:00
{
for (var index = 0; index < m_Animator.parameters.Length; ++index)
2020-12-02 21:29:53 +00:00
{
if (!autoSend || GetParameterAutoSend(index))
{
var parameter = m_Animator.parameters[index];
if (reader.Length == reader.Position)
{
return;
}
switch (parameter.type)
{
case AnimatorControllerParameterType.Int:
var num = (int)reader.ReadPackedUInt32();
m_Animator.SetInteger(parameter.nameHash, num);
break;
2020-12-03 08:28:05 +00:00
2020-12-02 21:29:53 +00:00
case AnimatorControllerParameterType.Float:
var single = reader.ReadSingle();
m_Animator.SetFloat(parameter.nameHash, single);
break;
2020-12-03 08:28:05 +00:00
2020-12-02 21:29:53 +00:00
case AnimatorControllerParameterType.Bool:
var flag = reader.ReadBoolean();
m_Animator.SetBool(parameter.nameHash, flag);
break;
}
}
}
}
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
public override bool OnSerialize(QNetworkWriter writer, bool forceAll)
2020-12-02 21:29:53 +00:00
{
if (!forceAll)
{
return false;
}
if (m_Animator.IsInTransition(0))
{
var animatorStateInfo = m_Animator.GetNextAnimatorStateInfo(0);
writer.Write(animatorStateInfo.fullPathHash);
writer.Write(animatorStateInfo.normalizedTime);
}
else
{
var animatorStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
writer.Write(animatorStateInfo.fullPathHash);
writer.Write(animatorStateInfo.normalizedTime);
}
WriteParameters(writer, false);
return true;
}
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
public override void OnDeserialize(QNetworkReader reader, bool initialState)
2020-12-02 21:29:53 +00:00
{
if (!initialState)
{
return;
}
var stateNameHash = reader.ReadInt32();
var normalizedTime = reader.ReadSingle();
ReadParameters(reader, false);
m_Animator.Play(stateNameHash, 0, normalizedTime);
}
2020-11-08 14:41:16 +00:00
public void SetTrigger(string triggerName) => SetTrigger(Animator.StringToHash(triggerName));
2020-11-08 14:41:16 +00:00
2020-12-02 21:29:53 +00:00
public void SetTrigger(int hash)
{
2020-12-23 12:58:45 +00:00
var animationTriggerMessage = new QAnimationTriggerMessage
2020-12-02 21:29:53 +00:00
{
netId = NetId,
hash = hash
};
if (HasAuthority && LocalPlayerAuthority)
{
2020-12-23 12:58:45 +00:00
if (QNetworkClient.allClients.Count <= 0)
2020-12-02 21:29:53 +00:00
{
return;
}
2020-12-23 12:58:45 +00:00
var readyConnection = QClientScene.readyConnection;
2020-12-02 21:29:53 +00:00
if (readyConnection == null)
{
return;
}
readyConnection.Send(42, animationTriggerMessage);
}
else
{
if (!IsServer || LocalPlayerAuthority)
{
return;
}
2020-12-23 12:58:45 +00:00
QNetworkServer.SendToReady(gameObject, 42, animationTriggerMessage);
2020-12-02 21:29:53 +00:00
}
}
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
internal static void OnAnimationServerMessage(QNetworkMessage netMsg)
2020-12-02 21:29:53 +00:00
{
netMsg.ReadMessage(AnimationMessage);
2020-12-23 12:58:45 +00:00
var localObject = QNetworkServer.FindLocalObject(AnimationMessage.netId);
2020-12-02 21:29:53 +00:00
if (localObject == null)
{
return;
}
2020-12-23 12:58:45 +00:00
var component = localObject.GetComponent<QNetworkAnimator>();
var reader = new QNetworkReader(AnimationMessage.parameters);
2020-12-02 21:29:53 +00:00
component?.HandleAnimMsg(AnimationMessage, reader);
2020-12-23 12:58:45 +00:00
QNetworkServer.SendToReady(localObject, 40, AnimationMessage);
2020-12-02 21:29:53 +00:00
}
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
internal static void OnAnimationParametersServerMessage(QNetworkMessage netMsg)
2020-12-02 21:29:53 +00:00
{
netMsg.ReadMessage(ParametersMessage);
2020-12-23 12:58:45 +00:00
var localObject = QNetworkServer.FindLocalObject(ParametersMessage.netId);
2020-12-02 21:29:53 +00:00
if (localObject == null)
{
return;
}
2020-12-23 12:58:45 +00:00
var component = localObject.GetComponent<QNetworkAnimator>();
var reader = new QNetworkReader(ParametersMessage.parameters);
2020-12-02 21:29:53 +00:00
component?.HandleAnimParamsMsg(ParametersMessage, reader);
2020-12-23 12:58:45 +00:00
QNetworkServer.SendToReady(localObject, 41, ParametersMessage);
2020-12-02 21:29:53 +00:00
}
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
internal static void OnAnimationTriggerServerMessage(QNetworkMessage netMsg)
2020-12-02 21:29:53 +00:00
{
netMsg.ReadMessage(TriggersMessage);
2020-12-23 12:58:45 +00:00
var localObject = QNetworkServer.FindLocalObject(TriggersMessage.netId);
2020-12-02 21:29:53 +00:00
if (localObject == null)
{
return;
}
2020-12-23 12:58:45 +00:00
var component = localObject.GetComponent<QNetworkAnimator>();
2020-12-02 21:29:53 +00:00
component?.HandleAnimTriggerMsg(TriggersMessage.hash);
2020-12-23 12:58:45 +00:00
QNetworkServer.SendToReady(localObject, 42, TriggersMessage);
2020-12-02 21:29:53 +00:00
}
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
internal static void OnAnimationClientMessage(QNetworkMessage netMsg)
2020-12-02 21:29:53 +00:00
{
netMsg.ReadMessage(AnimationMessage);
2020-12-23 12:58:45 +00:00
var localObject = QClientScene.FindLocalObject(AnimationMessage.netId);
2020-12-02 21:29:53 +00:00
if (localObject == null)
{
2020-12-02 21:29:53 +00:00
return;
}
2020-12-23 12:58:45 +00:00
var component = localObject.GetComponent<QNetworkAnimator>();
2020-12-02 21:29:53 +00:00
if (component == null)
{
2020-12-02 21:29:53 +00:00
return;
}
2020-12-23 12:58:45 +00:00
var reader = new QNetworkReader(AnimationMessage.parameters);
2020-12-02 21:29:53 +00:00
component.HandleAnimMsg(AnimationMessage, reader);
}
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
internal static void OnAnimationParametersClientMessage(QNetworkMessage netMsg)
2020-12-02 21:29:53 +00:00
{
netMsg.ReadMessage(ParametersMessage);
2020-12-23 12:58:45 +00:00
var localObject = QClientScene.FindLocalObject(ParametersMessage.netId);
2020-12-02 21:29:53 +00:00
if (localObject == null)
{
2020-12-02 21:29:53 +00:00
return;
}
2020-12-23 12:58:45 +00:00
var component = localObject.GetComponent<QNetworkAnimator>();
2020-12-02 21:29:53 +00:00
if (component == null)
{
2020-12-02 21:29:53 +00:00
return;
}
2020-12-23 12:58:45 +00:00
var reader = new QNetworkReader(ParametersMessage.parameters);
2020-12-02 21:29:53 +00:00
component.HandleAnimParamsMsg(ParametersMessage, reader);
}
2020-11-08 14:41:16 +00:00
2020-12-23 12:58:45 +00:00
internal static void OnAnimationTriggerClientMessage(QNetworkMessage netMsg)
2020-12-02 21:29:53 +00:00
{
netMsg.ReadMessage(TriggersMessage);
2020-12-23 12:58:45 +00:00
var localObject = QClientScene.FindLocalObject(TriggersMessage.netId);
2020-12-02 21:29:53 +00:00
if (localObject == null)
{
2020-12-02 21:29:53 +00:00
return;
}
2020-12-23 12:58:45 +00:00
var component = localObject.GetComponent<QNetworkAnimator>();
2020-12-02 21:29:53 +00:00
if (component == null)
{
2020-12-02 21:29:53 +00:00
return;
}
2020-12-02 21:29:53 +00:00
component.HandleAnimTriggerMsg(TriggersMessage.hash);
}
}
2020-11-08 16:13:10 +00:00
}