Added NetworkedAnimator & fixed zPos sync on NetworkedTransform

This commit is contained in:
Albin Corén 2018-03-05 15:08:54 +01:00
parent 27ae0bc01f
commit bfe9e9b04a
5 changed files with 360 additions and 12 deletions

View File

@ -41,6 +41,7 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@ -57,6 +58,7 @@
<ItemGroup>
<Compile Include="Data\NetworkPool.cs" />
<Compile Include="Data\TrackedPointData.cs" />
<Compile Include="MonoBehaviours\Prototyping\NetworkedAnimator.cs" />
<Compile Include="NetworkingManagerComponents\LagCompensationManager.cs" />
<Compile Include="MonoBehaviours\Core\NetworkedBehaviour.cs" />
<Compile Include="Data\NetworkedClient.cs" />

View File

@ -164,7 +164,7 @@ namespace MLAPI
NetworkingManager.singleton.Send(ownerClientId, messageType, channelName, data, networkId);
}
protected void SendToNonLocalClients(string messageType, string channelName, byte[] data)
protected void SendToNonLocalClients(string messageType, string channelName, byte[] data, bool ignoreHost = false)
{
if (MessageManager.messageTypes[messageType] < 32)
{
@ -176,10 +176,10 @@ namespace MLAPI
Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported");
return;
}
NetworkingManager.singleton.Send(messageType, channelName, data, ownerClientId);
NetworkingManager.singleton.Send(messageType, channelName, data, ownerClientId, null, ignoreHost);
}
protected void SendToNonLocalClientsTarget(string messageType, string channelName, byte[] data)
protected void SendToNonLocalClientsTarget(string messageType, string channelName, byte[] data, bool ignoreHost = false)
{
if (MessageManager.messageTypes[messageType] < 32)
{
@ -191,7 +191,7 @@ namespace MLAPI
Debug.LogWarning("MLAPI: Sending messages from client to other clients is not yet supported");
return;
}
NetworkingManager.singleton.Send(messageType, channelName, data, ownerClientId, networkId);
NetworkingManager.singleton.Send(messageType, channelName, data, ownerClientId, networkId, true);
}
protected void SendToClient(int clientId, string messageType, string channelName, byte[] data)

View File

@ -93,6 +93,7 @@ namespace MLAPI
//MLAPI channels and messageTypes
NetworkConfig.Channels.Add("MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", QosType.ReliableFragmentedSequenced);
NetworkConfig.Channels.Add("MLAPI_POSITION_UPDATE", QosType.StateUpdate);
NetworkConfig.Channels.Add("MLAPI_ANIMATION_UPDATE", QosType.ReliableSequenced);
MessageManager.messageTypes.Add("MLAPI_CONNECTION_REQUEST", 0);
MessageManager.messageTypes.Add("MLAPI_CONNECTION_APPROVED", 1);
MessageManager.messageTypes.Add("MLAPI_ADD_OBJECT", 2);
@ -104,14 +105,21 @@ namespace MLAPI
MessageManager.messageTypes.Add("MLAPI_CHANGE_OWNER", 8);
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromClient");
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromServer");
NetworkConfig.MessageTypes.Add("MLAPI_HandleAnimationMessage");
NetworkConfig.MessageTypes.Add("MLAPI_HandleAnimationParameterMessage");
NetworkConfig.MessageTypes.Add("MLAPI_HandleAnimationTriggerMessage");
for (int i = 0; i < NetworkConfig.RegisteredScenes.Count; i++)
if (NetworkConfig.EnableSceneSwitching)
{
NetworkSceneManager.registeredSceneNames.Add(NetworkConfig.RegisteredScenes[i]);
NetworkSceneManager.sceneIndexToString.Add((uint)i, NetworkConfig.RegisteredScenes[i]);
NetworkSceneManager.sceneNameToIndex.Add(NetworkConfig.RegisteredScenes[i], (uint)i);
for (int i = 0; i < NetworkConfig.RegisteredScenes.Count; i++)
{
NetworkSceneManager.registeredSceneNames.Add(NetworkConfig.RegisteredScenes[i]);
NetworkSceneManager.sceneIndexToString.Add((uint)i, NetworkConfig.RegisteredScenes[i]);
NetworkSceneManager.sceneNameToIndex.Add(NetworkConfig.RegisteredScenes[i], (uint)i);
}
NetworkSceneManager.SetCurrentSceneIndex();
}
NetworkSceneManager.SetCurrentSceneIndex();
HashSet<string> channelNames = new HashSet<string>();
@ -859,7 +867,7 @@ namespace MLAPI
}
}
internal void Send(string messageType, string channelName, byte[] data, int clientIdToIgnore, uint? networkId = null)
internal void Send(string messageType, string channelName, byte[] data, int clientIdToIgnore, uint? networkId = null, bool ignoreHost = false)
{
//2 bytes for messageType, 2 bytes for buffer length and one byte for target bool
int sizeOfStream = 5;
@ -885,7 +893,7 @@ namespace MLAPI
if (pair.Key == clientIdToIgnore)
continue;
int clientId = pair.Key;
if (isHost && pair.Key == -1)
if (isHost && pair.Key == -1 && !ignoreHost)
{
if (networkId == null)
MessageManager.InvokeMessageHandlers(messageType, data, clientId);

View File

@ -0,0 +1,338 @@
using System;
using System.IO;
using UnityEngine;
namespace MLAPI
{
[DisallowMultipleComponent]
[RequireComponent(typeof(Animator))]
public class NetworkedAnimator : NetworkedBehaviour
{
// configuration
[SerializeField] Animator m_Animator;
[SerializeField] uint m_ParameterSendBits;
[SerializeField] float m_SendRate = 0.1f;
// properties
public Animator animator
{
get { return m_Animator; }
set
{
m_Animator = value;
ResetParameterOptions();
}
}
public void SetParameterAutoSend(int index, bool value)
{
if (value)
{
m_ParameterSendBits |= (uint)(1 << index);
}
else
{
m_ParameterSendBits &= (uint)(~(1 << index));
}
}
public bool GetParameterAutoSend(int index)
{
return (m_ParameterSendBits & (uint)(1 << index)) != 0;
}
int m_AnimationHash;
int m_TransitionHash;
float m_SendTimer;
// tracking - these should probably move to a Preview component.
public string param0;
public string param1;
public string param2;
public string param3;
public string param4;
public string param5;
bool sendMessagesAllowed
{
get
{
return networkedObject.IsOwner || isLocalPlayer;
}
}
void Start()
{
RegisterMessageHandler("MLAPI_HandleAnimationMessage", HandleAnimMsg);
RegisterMessageHandler("MLAPI_HandleAnimationParameterMessage", HandleAnimParamsMsg);
RegisterMessageHandler("MLAPI_HandleAnimationTriggerMessage", HandleAnimTriggerMsg);
}
public void ResetParameterOptions()
{
Debug.Log("ResetParameterOptions");
m_ParameterSendBits = 0;
}
void FixedUpdate()
{
if (!sendMessagesAllowed)
return;
CheckSendRate();
int stateHash;
float normalizedTime;
if (!CheckAnimStateChanged(out stateHash, out normalizedTime))
{
return;
}
using(MemoryStream stream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(stateHash);
writer.Write(normalizedTime);
WriteParameters(writer, false);
}
if(isServer)
{
SendToNonLocalClientsTarget("MLAPI_HandleAnimationMessage", "MLAPI_ANIMATION_UPDATE", stream.ToArray(), true);
}
else
{
SendToServerTarget("MLAPI_HandleAnimationMessage", "MLAPI_ANIMATION_UPDATE", stream.ToArray());
}
}
}
bool CheckAnimStateChanged(out int stateHash, out float normalizedTime)
{
stateHash = 0;
normalizedTime = 0;
if (m_Animator.IsInTransition(0))
{
AnimatorTransitionInfo tt = m_Animator.GetAnimatorTransitionInfo(0);
if (tt.fullPathHash != m_TransitionHash)
{
// first time in this transition
m_TransitionHash = tt.fullPathHash;
m_AnimationHash = 0;
return true;
}
return false;
}
AnimatorStateInfo st = m_Animator.GetCurrentAnimatorStateInfo(0);
if (st.fullPathHash != m_AnimationHash)
{
// first time in this animation state
if (m_AnimationHash != 0)
{
// came from another animation directly - from Play()
stateHash = st.fullPathHash;
normalizedTime = st.normalizedTime;
}
m_TransitionHash = 0;
m_AnimationHash = st.fullPathHash;
return true;
}
return false;
}
void CheckSendRate()
{
if (sendMessagesAllowed && m_SendRate != 0 && m_SendTimer < Time.time)
{
m_SendTimer = Time.time + m_SendRate;
using(MemoryStream stream = new MemoryStream())
{
using(BinaryWriter writer = new BinaryWriter(stream))
{
WriteParameters(writer, true);
}
if (isServer)
{
SendToNonLocalClientsTarget("MLAPI_HandleAnimationParameterMessage", "MLAPI_ANIMATION_UPDATE", stream.ToArray(), true);
}
else
{
SendToServerTarget("MLAPI_HandleAnimationParameterMessage", "MLAPI_ANIMATION_UPDATE", stream.ToArray());
}
}
}
}
void SetSendTrackingParam(string p, int i)
{
p = "Sent Param: " + p;
if (i == 0) param0 = p;
if (i == 1) param1 = p;
if (i == 2) param2 = p;
if (i == 3) param3 = p;
if (i == 4) param4 = p;
if (i == 5) param5 = p;
}
void SetRecvTrackingParam(string p, int i)
{
p = "Recv Param: " + p;
if (i == 0) param0 = p;
if (i == 1) param1 = p;
if (i == 2) param2 = p;
if (i == 3) param3 = p;
if (i == 4) param4 = p;
if (i == 5) param5 = p;
}
internal void HandleAnimMsg(int clientId, byte[] data)
{
// usually transitions will be triggered by parameters, if not, play anims directly.
// NOTE: this plays "animations", not transitions, so any transitions will be skipped.
// NOTE: there is no API to play a transition(?)
//isServer AND the message is not from ourselves. This prevents a stack overflow. Infinite call to itself.
if(isServer)
{
SendToNonLocalClientsTarget("MLAPI_HandleAnimationMessage", "MLAPI_ANIMATION_UPDATE", data, true);
}
using(MemoryStream stream = new MemoryStream(data))
{
using(BinaryReader reader = new BinaryReader(stream))
{
int stateHash = reader.ReadInt32();
float normalizedTime = reader.ReadSingle();
if(stateHash != 0)
{
m_Animator.Play(stateHash, 0, normalizedTime);
}
ReadParameters(reader, false);
}
}
}
internal void HandleAnimParamsMsg(int clientId, byte[] data)
{
if (isServer)
{
SendToNonLocalClientsTarget("MLAPI_HandleAnimationParameterMessage", "MLAPI_ANIMATION_UPDATE", data, true);
}
using (MemoryStream stream = new MemoryStream(data))
{
using (BinaryReader reader = new BinaryReader(stream))
{
ReadParameters(reader, true);
}
}
}
internal void HandleAnimTriggerMsg(int clientId, byte[] data)
{
if (isServer)
{
SendToNonLocalClientsTarget("MLAPI_HandleAnimationTriggerMessage", "MLAPI_ANIMATION_UPDATE", data, true);
}
using (MemoryStream stream = new MemoryStream(data))
{
using(BinaryReader reader = new BinaryReader(stream))
{
m_Animator.SetTrigger(reader.ReadInt32());
}
}
}
void WriteParameters(BinaryWriter writer, bool autoSend)
{
for (int i = 0; i < m_Animator.parameters.Length; i++)
{
if (autoSend && !GetParameterAutoSend(i))
continue;
AnimatorControllerParameter par = m_Animator.parameters[i];
if (par.type == AnimatorControllerParameterType.Int)
{
writer.Write((uint)m_Animator.GetInteger(par.nameHash));
SetSendTrackingParam(par.name + ":" + m_Animator.GetInteger(par.nameHash), i);
}
if (par.type == AnimatorControllerParameterType.Float)
{
writer.Write(m_Animator.GetFloat(par.nameHash));
SetSendTrackingParam(par.name + ":" + m_Animator.GetFloat(par.nameHash), i);
}
if (par.type == AnimatorControllerParameterType.Bool)
{
writer.Write(m_Animator.GetBool(par.nameHash));
SetSendTrackingParam(par.name + ":" + m_Animator.GetBool(par.nameHash), i);
}
}
}
void ReadParameters(BinaryReader reader, bool autoSend)
{
for (int i = 0; i < m_Animator.parameters.Length; i++)
{
if (autoSend && !GetParameterAutoSend(i))
continue;
AnimatorControllerParameter par = m_Animator.parameters[i];
if (par.type == AnimatorControllerParameterType.Int)
{
int newValue = (int)reader.ReadUInt32();
m_Animator.SetInteger(par.nameHash, newValue);
SetRecvTrackingParam(par.name + ":" + newValue, i);
}
if (par.type == AnimatorControllerParameterType.Float)
{
float newFloatValue = reader.ReadSingle();
m_Animator.SetFloat(par.nameHash, newFloatValue);
SetRecvTrackingParam(par.name + ":" + newFloatValue, i);
}
if (par.type == AnimatorControllerParameterType.Bool)
{
bool newBoolValue = reader.ReadBoolean();
m_Animator.SetBool(par.nameHash, newBoolValue);
SetRecvTrackingParam(par.name + ":" + newBoolValue, i);
}
}
}
public void SetTrigger(string triggerName)
{
SetTrigger(Animator.StringToHash(triggerName));
}
public void SetTrigger(int hash)
{
if (isLocalPlayer || networkedObject.IsOwner)
{
using (MemoryStream stream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(hash);
}
if (isServer)
{
SendToNonLocalClientsTarget("MLAPI_HandleAnimationTriggerMessage", "MLAPI_ANIMATION_UPDATE", stream.ToArray(), true);
}
else
{
SendToServerTarget("MLAPI_HandleAnimationTriggerMessage", "MLAPI_ANIMATION_UPDATE", stream.ToArray());
}
}
}
}
}
}

View File

@ -122,7 +122,7 @@ namespace MLAP
float zRot = reader.ReadSingle();
lerpStartPos = transform.position;
lerpStartRot = transform.rotation;
lerpEndPos = new Vector3(xPos, yPos, zRot);
lerpEndPos = new Vector3(xPos, yPos, zPos);
lerpEndRot = Quaternion.Euler(xRot, yRot, zRot);
lerpT = 0;
}