Коммит
1197112d92
|
@ -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
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче