Merge pull request #16 from TwoTenPvP/synced-vars

Synced vars
This commit is contained in:
Albin Corén 2018-03-08 10:18:59 +01:00 коммит произвёл GitHub
Родитель c47a37b422 fe88778c88
Коммит 1197112d92
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 621 добавлений и 21 удалений

Просмотреть файл

@ -0,0 +1,22 @@
namespace MLAPI.Attributes
{
internal enum FieldType
{
Bool,
Byte,
Char,
Double,
Single,
Int,
Long,
SByte,
Short,
UInt,
ULong,
UShort,
String,
Vector3,
Vector2,
Quaternion
}
}

Просмотреть файл

@ -0,0 +1,10 @@
using System;
namespace MLAPI.Attributes
{
[AttributeUsage(AttributeTargets.Field)]
public class SyncedVar : Attribute
{
}
}

Просмотреть файл

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -41,7 +41,7 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@ -56,6 +56,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Attributes\FieldType.cs" />
<Compile Include="Attributes\SyncedVar.cs" />
<Compile Include="Data\NetworkPool.cs" />
<Compile Include="Data\TrackedPointData.cs" />
<Compile Include="MonoBehaviours\Prototyping\NetworkedAnimator.cs" />

Просмотреть файл

@ -2,11 +2,16 @@
using System.Collections.Generic;
using UnityEngine;
using MLAPI.NetworkingManagerComponents;
using System.Reflection;
using MLAPI.Attributes;
using System.Linq;
using System.IO;
namespace MLAPI
{
public abstract class NetworkedBehaviour : MonoBehaviour
{
public float SyncVarSyncDelay = 0.1f;
public bool isLocalPlayer
{
get
@ -79,6 +84,7 @@ namespace MLAPI
{
_networkedObject = GetComponentInParent<NetworkedObject>();
}
NetworkedObject.NetworkedBehaviours.Add(this);
}
internal bool networkedStartInvoked = false;
@ -109,6 +115,11 @@ namespace MLAPI
MessageManager.RemoveIncomingMessageHandler(name, counter, networkId);
}
private void OnDisable()
{
NetworkedObject.NetworkedBehaviours.Remove(this);
}
private void OnDestroy()
{
foreach (KeyValuePair<string, int> pair in registeredMessageHandlers)
@ -117,6 +128,419 @@ namespace MLAPI
}
}
#region SYNC_VAR
private List<FieldInfo> syncedFields = new List<FieldInfo>();
internal List<FieldType> syncedFieldTypes = new List<FieldType>();
private List<object> syncedFieldValues = new List<object>();
//A dirty field is a field that's not synced.
public bool[] dirtyFields;
internal void SyncVarInit()
{
FieldInfo[] sortedFields = GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance).OrderBy(x => x.Name).ToArray();
for (byte i = 0; i < sortedFields.Length; i++)
{
if(sortedFields[i].IsDefined(typeof(SyncedVar), true))
{
if (sortedFields[i].FieldType == typeof(bool))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.Bool);
}
else if(sortedFields[i].FieldType == typeof(byte))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.Byte);
}
else if (sortedFields[i].FieldType == typeof(char))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.Char);
}
else if (sortedFields[i].FieldType == typeof(double))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.Double);
}
else if (sortedFields[i].FieldType == typeof(float))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.Single);
}
else if (sortedFields[i].FieldType == typeof(int))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.Int);
}
else if (sortedFields[i].FieldType == typeof(long))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.Long);
}
else if (sortedFields[i].FieldType == typeof(sbyte))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.SByte);
}
else if (sortedFields[i].FieldType == typeof(short))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.Short);
}
else if (sortedFields[i].FieldType == typeof(uint))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.UInt);
}
else if (sortedFields[i].FieldType == typeof(ulong))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.ULong);
}
else if (sortedFields[i].FieldType == typeof(ushort))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.UShort);
}
else if(sortedFields[i].FieldType == typeof(string))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.String);
}
else if(sortedFields[i].FieldType == typeof(Vector3))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.Vector3);
}
else if(sortedFields[i].FieldType == typeof(Vector2))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.Vector2);
}
else if (sortedFields[i].FieldType == typeof(Quaternion))
{
syncedFields.Add(sortedFields[i]);
syncedFieldValues.Add(sortedFields[i].GetValue(this));
syncedFieldTypes.Add(FieldType.Quaternion);
}
else
{
Debug.LogError("MLAPI: The type " + sortedFields[i].FieldType.ToString() + " can not be used as a syncvar");
}
}
}
if(dirtyFields.Length > 255)
{
Debug.LogError("MLAPI: You can not have more than 255 SyncVar's per NetworkedBehaviour!");
}
dirtyFields = new bool[syncedFields.Count];
}
internal void OnSyncVarUpdate(object value, byte fieldIndex)
{
syncedFields[fieldIndex].SetValue(this, value);
}
internal void FlushToClient(int clientId)
{
//This NetworkedBehaviour has no SyncVars
if (dirtyFields.Length == 0)
return;
using (MemoryStream stream = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
//Write all indexes
writer.Write(dirtyFields.Length);
for (byte i = 0; i < dirtyFields.Length; i++)
{
writer.Write(networkId);
writer.Write(networkedObject.GetOrderIndex(this));
writer.Write(i); //Index
switch (syncedFieldTypes[i])
{
case FieldType.Bool:
writer.Write((bool)syncedFields[i].GetValue(this));
break;
case FieldType.Byte:
writer.Write((byte)syncedFields[i].GetValue(this));
break;
case FieldType.Char:
writer.Write((char)syncedFields[i].GetValue(this));
break;
case FieldType.Double:
writer.Write((double)syncedFields[i].GetValue(this));
break;
case FieldType.Single:
writer.Write((float)syncedFields[i].GetValue(this));
break;
case FieldType.Int:
writer.Write((int)syncedFields[i].GetValue(this));
break;
case FieldType.Long:
writer.Write((long)syncedFields[i].GetValue(this));
break;
case FieldType.SByte:
writer.Write((sbyte)syncedFields[i].GetValue(this));
break;
case FieldType.Short:
writer.Write((short)syncedFields[i].GetValue(this));
break;
case FieldType.UInt:
writer.Write((uint)syncedFields[i].GetValue(this));
break;
case FieldType.ULong:
writer.Write((ulong)syncedFields[i].GetValue(this));
break;
case FieldType.UShort:
writer.Write((ushort)syncedFields[i].GetValue(this));
break;
case FieldType.String:
writer.Write((string)syncedFields[i].GetValue(this));
break;
case FieldType.Vector3:
Vector3 vector3 = (Vector3)syncedFields[i].GetValue(this);
writer.Write(vector3.x);
writer.Write(vector3.y);
writer.Write(vector3.z);
break;
case FieldType.Vector2:
Vector2 vector2 = (Vector2)syncedFields[i].GetValue(this);
writer.Write(vector2.x);
writer.Write(vector2.y);
break;
case FieldType.Quaternion:
Vector3 euler = ((Quaternion)syncedFields[i].GetValue(this)).eulerAngles;
writer.Write(euler.x);
writer.Write(euler.y);
writer.Write(euler.z);
break;
}
}
NetworkingManager.singleton.Send(clientId, "MLAPI_SYNC_VAR_UPDATE", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.ToArray());
}
}
}
private float lastSyncTime = 0f;
internal void SyncVarUpdate()
{
SetDirtyness();
if(Time.time - lastSyncTime >= SyncVarSyncDelay)
{
byte dirtyCount = (byte)dirtyFields.Count(x => x == true);
if (dirtyCount == 0)
return; //All up to date!
//It's sync time!
using (MemoryStream stream = new MemoryStream())
{
using(BinaryWriter writer = new BinaryWriter(stream))
{
//Write all indexes
writer.Write(dirtyCount);
for (byte i = 0; i < dirtyFields.Length; i++)
{
//Writes all the indexes of the dirty syncvars.
if (dirtyFields[i] == true)
{
writer.Write(networkId);
writer.Write(networkedObject.GetOrderIndex(this));
writer.Write(i); //Index
switch (syncedFieldTypes[i])
{
case FieldType.Bool:
writer.Write((bool)syncedFields[i].GetValue(this));
break;
case FieldType.Byte:
writer.Write((byte)syncedFields[i].GetValue(this));
break;
case FieldType.Char:
writer.Write((char)syncedFields[i].GetValue(this));
break;
case FieldType.Double:
writer.Write((double)syncedFields[i].GetValue(this));
break;
case FieldType.Single:
writer.Write((float)syncedFields[i].GetValue(this));
break;
case FieldType.Int:
writer.Write((int)syncedFields[i].GetValue(this));
break;
case FieldType.Long:
writer.Write((long)syncedFields[i].GetValue(this));
break;
case FieldType.SByte:
writer.Write((sbyte)syncedFields[i].GetValue(this));
break;
case FieldType.Short:
writer.Write((short)syncedFields[i].GetValue(this));
break;
case FieldType.UInt:
writer.Write((uint)syncedFields[i].GetValue(this));
break;
case FieldType.ULong:
writer.Write((ulong)syncedFields[i].GetValue(this));
break;
case FieldType.UShort:
writer.Write((ushort)syncedFields[i].GetValue(this));
break;
case FieldType.String:
writer.Write((string)syncedFields[i].GetValue(this));
break;
case FieldType.Vector3:
Vector3 vector3 = (Vector3)syncedFields[i].GetValue(this);
writer.Write(vector3.x);
writer.Write(vector3.y);
writer.Write(vector3.z);
break;
case FieldType.Vector2:
Vector2 vector2 = (Vector2)syncedFields[i].GetValue(this);
writer.Write(vector2.x);
writer.Write(vector2.y);
break;
case FieldType.Quaternion:
Vector3 euler = ((Quaternion)syncedFields[i].GetValue(this)).eulerAngles;
writer.Write(euler.x);
writer.Write(euler.y);
writer.Write(euler.z);
break;
}
syncedFieldValues[i] = syncedFields[i].GetValue(this);
dirtyFields[i] = false;
}
}
NetworkingManager.singleton.Send("MLAPI_SYNC_VAR_UPDATE", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.ToArray(), ownerClientId);
}
}
lastSyncTime = Time.time;
}
}
private void SetDirtyness()
{
if (!isServer)
return;
for (int i = 0; i < syncedFields.Count; i++)
{
switch (syncedFieldTypes[i])
{
case FieldType.Bool:
if ((bool)syncedFields[i].GetValue(this) != (bool)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.Byte:
if ((byte)syncedFields[i].GetValue(this) != (byte)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.Char:
if ((char)syncedFields[i].GetValue(this) != (char)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.Double:
if ((double)syncedFields[i].GetValue(this) != (double)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.Single:
if ((float)syncedFields[i].GetValue(this) != (float)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.Int:
if ((int)syncedFields[i].GetValue(this) != (int)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.Long:
if ((long)syncedFields[i].GetValue(this) != (long)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.SByte:
if ((sbyte)syncedFields[i].GetValue(this) != (sbyte)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.Short:
if ((short)syncedFields[i].GetValue(this) != (short)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.UInt:
if ((uint)syncedFields[i].GetValue(this) != (uint)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.ULong:
if ((ulong)syncedFields[i].GetValue(this) != (ulong)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.UShort:
if ((ushort)syncedFields[i].GetValue(this) != (ushort)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.String:
if ((string)syncedFields[i].GetValue(this) != (string)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.Vector3:
if ((Vector3)syncedFields[i].GetValue(this) != (Vector3)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.Vector2:
if ((Vector2)syncedFields[i].GetValue(this) != (Vector2)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
case FieldType.Quaternion:
if ((Quaternion)syncedFields[i].GetValue(this) != (Quaternion)syncedFieldValues[i])
dirtyFields[i] = true; //This fields value is out of sync!
else
dirtyFields[i] = false; //Up to date
break;
}
}
}
#endregion
protected void SendToServer(string messageType, string channelName, byte[] data)
{
if(MessageManager.messageTypes[messageType] < 32)

Просмотреть файл

@ -1,4 +1,5 @@
using MLAPI.NetworkingManagerComponents;
using System.Collections.Generic;
using UnityEngine;
namespace MLAPI
@ -63,41 +64,85 @@ namespace MLAPI
internal void InvokeBehaviourOnLostOwnership()
{
NetworkedBehaviour[] netBehaviours = GetComponentsInChildren<NetworkedBehaviour>();
for (int i = 0; i < netBehaviours.Length; i++)
for (int i = 0; i < childNetworkedBehaviours.Count; i++)
{
//We check if we are it's networkedObject owner incase a networkedObject exists as a child of our networkedObject.
if (netBehaviours[i].networkedObject == this)
{
netBehaviours[i].OnLostOwnership();
}
childNetworkedBehaviours[i].OnLostOwnership();
}
}
internal void InvokeBehaviourOnGainedOwnership()
{
NetworkedBehaviour[] netBehaviours = GetComponentsInChildren<NetworkedBehaviour>();
for (int i = 0; i < netBehaviours.Length; i++)
for (int i = 0; i < childNetworkedBehaviours.Count; i++)
{
//We check if we are it's networkedObject owner incase a networkedObject exists as a child of our networkedObject.
if (netBehaviours[i].networkedObject == this)
{
netBehaviours[i].OnGainedOwnership();
}
childNetworkedBehaviours[i].OnGainedOwnership();
}
}
internal void InvokeBehaviourNetworkSpawn()
{
NetworkedBehaviour[] netBehaviours = GetComponentsInChildren<NetworkedBehaviour>();
for (int i = 0; i < netBehaviours.Length; i++)
for (int i = 0; i < childNetworkedBehaviours.Count; i++)
{
//We check if we are it's networkedObject owner incase a networkedObject exists as a child of our networkedObject.
if(netBehaviours[i].networkedObject == this && !netBehaviours[i].networkedStartInvoked)
if(!childNetworkedBehaviours[i].networkedStartInvoked)
{
netBehaviours[i].NetworkStart();
childNetworkedBehaviours[i].NetworkStart();
if (NetworkingManager.singleton.isServer)
childNetworkedBehaviours[i].SyncVarInit();
}
}
}
private List<NetworkedBehaviour> _childNetworkedBehaviours;
internal List<NetworkedBehaviour> childNetworkedBehaviours
{
get
{
if(_childNetworkedBehaviours == null)
{
_childNetworkedBehaviours = new List<NetworkedBehaviour>();
NetworkedBehaviour[] behaviours = GetComponentsInChildren<NetworkedBehaviour>();
for (int i = 0; i < behaviours.Length; i++)
{
if (behaviours[i].networkedObject == this)
_childNetworkedBehaviours.Add(behaviours[i]);
}
}
return _childNetworkedBehaviours;
}
}
internal static List<NetworkedBehaviour> NetworkedBehaviours = new List<NetworkedBehaviour>();
internal static void InvokeSyncvarUpdate()
{
for (int i = 0; i < NetworkedBehaviours.Count; i++)
{
NetworkedBehaviours[i].SyncVarUpdate();
}
}
//Flushes all syncVars to client
internal void FlushToClient(int clientId)
{
for (int i = 0; i < childNetworkedBehaviours.Count; i++)
{
childNetworkedBehaviours[i].FlushToClient(clientId);
}
}
internal ushort GetOrderIndex(NetworkedBehaviour instance)
{
for (ushort i = 0; i < childNetworkedBehaviours.Count; i++)
{
if (childNetworkedBehaviours[i] == instance)
return i;
}
return 0;
}
internal NetworkedBehaviour GetBehaviourAtOrderIndex(ushort index)
{
//TODO index out of bounds
return childNetworkedBehaviours[index];
}
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using MLAPI.NetworkingManagerComponents;
using MLAPI.Attributes;
using MLAPI.NetworkingManagerComponents;
using System;
using System.Collections;
using System.Collections.Generic;
@ -117,6 +118,7 @@ namespace MLAPI
MessageManager.messageTypes.Add("MLAPI_SPAWN_POOL_OBJECT", 6);
MessageManager.messageTypes.Add("MLAPI_DESTROY_POOL_OBJECT", 7);
MessageManager.messageTypes.Add("MLAPI_CHANGE_OWNER", 8);
MessageManager.messageTypes.Add("MLAPI_SYNC_VAR_UPDATE", 9);
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromClient");
NetworkConfig.MessageTypes.Add("MLAPI_OnRecieveTransformFromServer");
NetworkConfig.MessageTypes.Add("MLAPI_HandleAnimationMessage");
@ -360,7 +362,10 @@ namespace MLAPI
}
if (isServer)
{
LagCompensationManager.AddFrames();
NetworkedObject.InvokeSyncvarUpdate();
}
}
private IEnumerator ApprovalTimeout(int clientId)
@ -677,6 +682,93 @@ namespace MLAPI
}
}
break;
case 9:
if (isClient)
{
using (MemoryStream messageReadStream = new MemoryStream(incommingData))
{
using (BinaryReader messageReader = new BinaryReader(messageReadStream))
{
byte dirtyCount = messageReader.ReadByte();
if(dirtyCount > 0)
{
for (int i = 0; i < dirtyCount; i++)
{
uint netId = messageReader.ReadUInt32(); //NetId the syncvar is from
ushort orderIndex = messageReader.ReadUInt16();
byte fieldIndex = messageReader.ReadByte();
FieldType type = SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).syncedFieldTypes[fieldIndex];
switch (type)
{
case FieldType.Bool:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadBoolean(), fieldIndex);
break;
case FieldType.Byte:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadByte(), fieldIndex);
break;
case FieldType.Char:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadChar(), fieldIndex);
break;
case FieldType.Double:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadDouble(), fieldIndex);
break;
case FieldType.Single:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadSingle(), fieldIndex);
break;
case FieldType.Int:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadInt32(), fieldIndex);
break;
case FieldType.Long:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadInt64(), fieldIndex);
break;
case FieldType.SByte:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadSByte(), fieldIndex);
break;
case FieldType.Short:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadInt16(), fieldIndex);
break;
case FieldType.UInt:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadUInt32(), fieldIndex);
break;
case FieldType.ULong:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadUInt64(), fieldIndex);
break;
case FieldType.UShort:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadUInt16(), fieldIndex);
break;
case FieldType.String:
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(messageReader.ReadString(), fieldIndex);
break;
case FieldType.Vector3:
{ //Cases aren't their own scope. Therefor we create a scope for them as they share the X,Y,Z local variables otherwise.
float x = messageReader.ReadSingle();
float y = messageReader.ReadSingle();
float z = messageReader.ReadSingle();
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(new Vector3(x, y, z), fieldIndex);
}
break;
case FieldType.Vector2:
{
float x = messageReader.ReadSingle();
float y = messageReader.ReadSingle();
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(new Vector2(x, y), fieldIndex);
}
break;
case FieldType.Quaternion:
{
float x = messageReader.ReadSingle();
float y = messageReader.ReadSingle();
float z = messageReader.ReadSingle();
SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(Quaternion.Euler(x, y, z), fieldIndex);
}
break;
}
}
}
}
}
}
break;
}
}
}
@ -1065,6 +1157,11 @@ namespace MLAPI
}
Send("MLAPI_ADD_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer(), clientId);
}
//Flush syncvars:
foreach (KeyValuePair<uint, NetworkedObject> networkedObject in SpawnManager.spawnedObjects)
{
networkedObject.Value.FlushToClient(clientId);
}
}
else
{