diff --git a/com.unity.multiplayer.mlapi/Prototyping/NetworkTransform.cs b/com.unity.multiplayer.mlapi/Prototyping/NetworkTransform.cs index 65adab6d35..80fd6f1e0d 100644 --- a/com.unity.multiplayer.mlapi/Prototyping/NetworkTransform.cs +++ b/com.unity.multiplayer.mlapi/Prototyping/NetworkTransform.cs @@ -2,7 +2,6 @@ using MLAPI.NetworkVariable; using MLAPI.Transports; using UnityEngine; -using UnityEngine.Serialization; namespace MLAPI.Prototyping { @@ -41,8 +40,6 @@ public enum Authority /// TODO MTT-766 once we have per var interpolation /// Enable interpolation /// - // ReSharper disable once NotAccessedField.Global - [FormerlySerializedAs("m_InterpolatePosition")] [SerializeField, Tooltip("This requires AssumeSyncedSends to be true")] public bool InterpolatePosition = true; @@ -50,7 +47,6 @@ public enum Authority /// TODO MTT-766 once we have per var interpolation /// The distance before snaping to the position /// - // ReSharper disable once NotAccessedField.Global [SerializeField, Tooltip("The transform will snap if the distance is greater than this distance")] public float SnapDistance = 10f; @@ -58,7 +54,6 @@ public enum Authority /// TODO MTT-766 once we have per var interpolation /// Should the server interpolate /// - // ReSharper disable once NotAccessedField.Global [SerializeField] public bool InterpolateServer = true; @@ -68,7 +63,6 @@ public enum Authority /// The setting in the NetworkTransform would be to just apply it to our netvars when available /// The min meters to move before a send is sent /// - // ReSharper disable once NotAccessedField.Global [SerializeField, Tooltip("The min meters to move before a send is sent")] public float MinMeters = 0.15f; @@ -76,7 +70,6 @@ public enum Authority /// TODO MTT-767 once we have this per var setting /// The min degrees to rotate before a send is sent /// - // ReSharper disable once NotAccessedField.Global [SerializeField, Tooltip("The min degrees to rotate before a send is sent")] public float MinDegrees = 1.5f; @@ -84,7 +77,6 @@ public enum Authority /// TODO MTT-767 once we have this per var setting /// The min meters to scale before a send is sent /// - // ReSharper disable once NotAccessedField.Global [SerializeField, Tooltip("The min meters to scale before a send is sent")] public float MinSize = 0.15f; @@ -178,7 +170,7 @@ private void SetWorldScale(Vector3 globalScale) m_Transform.localScale = new Vector3(globalScale.x / lossyScale.x, globalScale.y / lossyScale.y, globalScale.z / lossyScale.z); } - private bool CanUpdateTransform() + public bool CanUpdateTransform() { return (IsClient && TransformAuthority == Authority.Client && IsOwner) || (IsServer && TransformAuthority == Authority.Server) || TransformAuthority == Authority.Shared; } @@ -221,6 +213,11 @@ void SetupVar(NetworkVariable v, T initialValue, ref T oldVal) } } + public override void OnNetworkObjectParentChanged(NetworkObject parentNetworkObject) + { + // TODO: handle parent NetworkObject change and potentially optimize pos/rot/scale replication? + } + private NetworkVariable.OnValueChangedDelegate GetOnValueChangedDelegate(Action assignCurrent) { return (old, current) => diff --git a/com.unity.multiplayer.mlapi/Runtime/Configuration/NetworkConstants.cs b/com.unity.multiplayer.mlapi/Runtime/Configuration/NetworkConstants.cs index 8c1ceac3a9..3222f27f78 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Configuration/NetworkConstants.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Configuration/NetworkConstants.cs @@ -18,6 +18,7 @@ internal static class NetworkConstants internal const byte TIME_SYNC = 11; internal const byte NETWORK_VARIABLE_DELTA = 12; internal const byte ALL_CLIENTS_LOADED_SCENE = 14; + internal const byte PARENT_SYNC = 16; internal const byte UNNAMED_MESSAGE = 20; internal const byte DESTROY_OBJECTS = 21; internal const byte NAMED_MESSAGE = 22; @@ -45,7 +46,7 @@ internal static class NetworkConstants "", "ALL_CLIENTS_SWITCH_SCENE_COMPLETED", "", - "", // 16 + "PARENT_SYNC", // 16 "", "", "", diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkBehaviour.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkBehaviour.cs index 30a17eed7f..6742e69330 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkBehaviour.cs @@ -342,6 +342,11 @@ public virtual void OnGainedOwnership() { } /// public virtual void OnLostOwnership() { } + /// + /// Gets called when the parent NetworkObject of this NetworkBehaviour's NetworkObject has changed + /// + public virtual void OnNetworkObjectParentChanged(NetworkObject parentNetworkObject) { } + private bool m_VarInit = false; private readonly List> m_ChannelMappedNetworkVariableIndexes = new List>(); diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs index 3d15a9b716..207ba51fb0 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs @@ -322,11 +322,11 @@ private void OnValidate() } #endif - private void Init(bool server) + private void Initialize(bool server) { if (NetworkLog.CurrentLogLevel <= LogLevel.Developer) { - NetworkLog.LogInfo(nameof(Init)); + NetworkLog.LogInfo(nameof(Initialize)); } LocalClientId = 0; @@ -337,6 +337,7 @@ private void Init(bool server) PendingClients.Clear(); ConnectedClients.Clear(); ConnectedClientsList.Clear(); + NetworkObject.OrphanChildren.Clear(); // Create spawn manager instance SpawnManager = new NetworkSpawnManager(this); @@ -541,7 +542,7 @@ public SocketTasks StartServer() } } - Init(true); + Initialize(true); var socketTasks = NetworkConfig.NetworkTransport.StartServer(); @@ -576,7 +577,7 @@ public SocketTasks StartClient() return SocketTask.Fault.AsTasks(); } - Init(false); + Initialize(false); var socketTasks = NetworkConfig.NetworkTransport.StartClient(); @@ -702,7 +703,7 @@ public SocketTasks StartHost() } } - Init(true); + Initialize(true); var socketTasks = NetworkConfig.NetworkTransport.StartServer(); @@ -1330,6 +1331,29 @@ internal void HandleIncomingData(ulong clientId, NetworkChannel networkChannel, } } + break; + } + case NetworkConstants.PARENT_SYNC: + { + if (IsClient) + { + using (var reader = PooledNetworkReader.Get(messageStream)) + { + var networkObjectId = reader.ReadUInt64Packed(); + var (isReparented, latestParent) = NetworkObject.ReadNetworkParenting(reader); + if (SpawnManager.SpawnedObjects.ContainsKey(networkObjectId)) + { + var networkObject = SpawnManager.SpawnedObjects[networkObjectId]; + networkObject.SetNetworkParenting(isReparented, latestParent); + networkObject.ApplyNetworkParenting(); + } + else if (NetworkLog.CurrentLogLevel <= LogLevel.Developer) + { + NetworkLog.LogWarning($"Read {nameof(NetworkConstants.PARENT_SYNC)} for {nameof(NetworkObject)} #{networkObjectId} but could not find it in the {nameof(SpawnManager.SpawnedObjects)}"); + } + } + } + break; } default: diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkObject.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkObject.cs index 4db53ee1ca..1194c87ae0 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkObject.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkObject.cs @@ -64,7 +64,7 @@ internal void GenerateGlobalObjectIdHash() /// /// Gets the NetworkManager that owns this NetworkObject instance /// - public NetworkManager NetworkManager => NetworkManagerOwner != null ? NetworkManagerOwner : NetworkManager.Singleton; + public NetworkManager NetworkManager => NetworkManagerOwner ?? NetworkManager.Singleton; /// /// The NetworkManager that owns this NetworkObject. @@ -178,6 +178,11 @@ internal set /// public bool DontDestroyWithOwner; + /// + /// Whether or not to enable automatic NetworkObject parent synchronization. + /// + public bool AutoObjectParentSync = true; + internal readonly HashSet Observers = new HashSet(); /// @@ -209,6 +214,11 @@ public bool IsNetworkVisibleTo(ulong clientId) return Observers.Contains(clientId); } + private void Awake() + { + SetCachedParent(transform.parent); + } + /// /// Shows a previously hidden object to a client /// @@ -406,7 +416,7 @@ private void SpawnInternal(Stream spawnPayload, bool destroyWithScene, ulong? ow { if (!NetworkManager.IsListening) { - throw new NotListeningException($"{nameof(NetworkManager)} isn't listening, start a server or host before spawning objects."); + throw new NotListeningException($"{nameof(NetworkManager)} is not listening, start a server or host before spawning objects"); } if (!NetworkManager.IsServer) @@ -504,6 +514,260 @@ internal void InvokeBehaviourOnGainedOwnership() } } + internal void InvokeBehaviourOnNetworkObjectParentChanged(NetworkObject parentNetworkObject) + { + for (int i = 0; i < ChildNetworkBehaviours.Count; i++) + { + ChildNetworkBehaviours[i].OnNetworkObjectParentChanged(parentNetworkObject); + } + } + + private bool m_IsReparented; // Did initial parent (came from the scene hierarchy) change at runtime? + private ulong? m_LatestParent; // What is our last set parent NetworkObject's ID? + private Transform m_CachedParent; // What is our last set parent Transform reference? + + internal void SetCachedParent(Transform parentTransform) + { + m_CachedParent = parentTransform; + } + + internal static void WriteNetworkParenting(NetworkWriter writer, bool isReparented, ulong? latestParent) + { + writer.WriteBool(isReparented); + if (isReparented) + { + var isLatestParentSet = latestParent != null && latestParent.HasValue; + writer.WriteBool(isLatestParentSet); + if (isLatestParentSet) + { + writer.WriteUInt64Packed(latestParent.Value); + } + } + } + + internal static (bool IsReparented, ulong? LatestParent) ReadNetworkParenting(NetworkReader reader) + { + ulong? latestParent = null; + bool isReparented = reader.ReadBool(); + if (isReparented) + { + var isLatestParentSet = reader.ReadBool(); + if (isLatestParentSet) + { + latestParent = reader.ReadUInt64Packed(); + } + } + + return (isReparented, latestParent); + } + + internal (bool IsReparented, ulong? LatestParent) GetNetworkParenting() => (m_IsReparented, m_LatestParent); + + internal void SetNetworkParenting(bool isReparented, ulong? latestParent) + { + m_IsReparented = isReparented; + m_LatestParent = latestParent; + } + + public bool TrySetParent(Transform parent, bool worldPositionStays = true) + { + return TrySetParent(parent.GetComponent(), worldPositionStays); + } + + public bool TrySetParent(GameObject parent, bool worldPositionStays = true) + { + return TrySetParent(parent.GetComponent(), worldPositionStays); + } + + public bool TrySetParent(NetworkObject parent, bool worldPositionStays = true) + { + if (!AutoObjectParentSync) + { + return false; + } + + if (NetworkManager == null || !NetworkManager.IsListening) + { + return false; + } + + if (!NetworkManager.IsServer) + { + return false; + } + + if (!IsSpawned) + { + return false; + } + + if (parent == null) + { + return false; + } + + if (!parent.IsSpawned) + { + return false; + } + + transform.SetParent(parent.transform, worldPositionStays); + return true; + } + + private void OnTransformParentChanged() + { + if (!AutoObjectParentSync) + { + return; + } + + if (transform.parent == m_CachedParent) + { + return; + } + + if (NetworkManager == null || !NetworkManager.IsListening) + { + transform.parent = m_CachedParent; + Debug.LogException(new NotListeningException($"{nameof(NetworkManager)} is not listening, start a server or host before reparenting")); + return; + } + + if (!NetworkManager.IsServer) + { + transform.parent = m_CachedParent; + Debug.LogException(new NotServerException($"Only the server can reparent {nameof(NetworkObject)}s")); + return; + } + + if (!IsSpawned) + { + transform.parent = m_CachedParent; + Debug.LogException(new SpawnStateException($"{nameof(NetworkObject)} can only be reparented after being spawned")); + return; + } + + var parentTransform = transform.parent; + if (parentTransform != null) + { + var parentObject = transform.parent.GetComponent(); + if (parentObject == null) + { + transform.parent = m_CachedParent; + Debug.LogException(new InvalidParentException($"Invalid parenting, {nameof(NetworkObject)} moved under a non-{nameof(NetworkObject)} parent")); + return; + } + + if (!parentObject.IsSpawned) + { + transform.parent = m_CachedParent; + Debug.LogException(new SpawnStateException($"{nameof(NetworkObject)} can only be reparented under another spawned {nameof(NetworkObject)}")); + return; + } + + m_LatestParent = parentObject.NetworkObjectId; + } + else + { + m_LatestParent = null; + } + + m_IsReparented = true; + ApplyNetworkParenting(); + + using (var buffer = PooledNetworkBuffer.Get()) + { + using (var writer = PooledNetworkWriter.Get(buffer)) + { + writer.WriteUInt64Packed(NetworkObjectId); + WriteNetworkParenting(writer, m_IsReparented, m_LatestParent); + } + + for (int i = 0; i < NetworkManager.ConnectedClientsList.Count; i++) + { + var targetClientId = NetworkManager.ConnectedClientsList[i].ClientId; + if (Observers.Contains(targetClientId)) + { + NetworkManager.MessageSender.Send(targetClientId, NetworkConstants.PARENT_SYNC, NetworkChannel.Internal, buffer); + } + } + } + } + + // We're keeping this set called OrphanChildren which contains NetworkObjects + // because at the time we initialize/spawn NetworkObject locally, we might not have its parent replicated from the other side + // + // For instance, if we're spawning NetworkObject 5 and its parent is 10, what should happen if we do not have 10 yet? + // let's say 10 is on the way to be replicated in a few frames and we could fix that parent-child relationship later. + // + // If you couldn't find your parent, we put you into OrphanChildren set and everytime we spawn another NetworkObject locally due to replication, + // we call CheckOrphanChildren() method and quickly iterate over OrphanChildren set and see if we can reparent/adopt one. + internal static HashSet OrphanChildren = new HashSet(); + + internal bool ApplyNetworkParenting() + { + if (!AutoObjectParentSync) + { + return false; + } + + if (!IsSpawned) + { + return false; + } + + if (!m_IsReparented) + { + return true; + } + + if (m_LatestParent == null || !m_LatestParent.HasValue) + { + m_CachedParent = null; + transform.parent = null; + + InvokeBehaviourOnNetworkObjectParentChanged(null); + return true; + } + + if (!NetworkManager.SpawnManager.SpawnedObjects.ContainsKey(m_LatestParent.Value)) + { + if (OrphanChildren.Add(this)) + { + if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) + { + NetworkLog.LogWarning($"{nameof(NetworkObject)} ({name}) cannot find its parent, added to {nameof(OrphanChildren)} set"); + } + } + return false; + } + + var parentObject = NetworkManager.SpawnManager.SpawnedObjects[m_LatestParent.Value]; + + m_CachedParent = parentObject.transform; + transform.parent = parentObject.transform; + + InvokeBehaviourOnNetworkObjectParentChanged(parentObject); + return true; + } + + internal static void CheckOrphanChildren() + { + var objectsToRemove = new List(); + foreach (var orphanObject in OrphanChildren) + { + if (orphanObject.ApplyNetworkParenting()) + { + objectsToRemove.Add(orphanObject); + } + } + foreach (var networkObject in objectsToRemove) + { + OrphanChildren.Remove(networkObject); + } + } + internal void InvokeBehaviourNetworkSpawn(Stream stream) { for (int i = 0; i < ChildNetworkBehaviours.Count; i++) @@ -666,6 +930,11 @@ internal void SerializeSceneObject(NetworkWriter writer, ulong targetClientId) writer.WriteBool(false); } + { + var (isReparented, latestParent) = GetNetworkParenting(); + WriteNetworkParenting(writer, isReparented, latestParent); + } + // Write whether we are including network variable data writer.WriteBool(NetworkManager.NetworkConfig.EnableNetworkVariable); @@ -728,9 +997,9 @@ internal static NetworkObject DeserializeSceneObject(NetworkBuffer objectStream, parentNetworkId = reader.ReadUInt32Packed(); } - var isSceneObject = reader.ReadBool(); + bool isSceneObject = reader.ReadBool(); - var prefabHash = reader.ReadUInt32Packed(); + uint globalObjectIdHash = reader.ReadUInt32Packed(); Vector3? position = null; Quaternion? rotation = null; @@ -741,8 +1010,12 @@ internal static NetworkObject DeserializeSceneObject(NetworkBuffer objectStream, rotation = Quaternion.Euler(reader.ReadSinglePacked(), reader.ReadSinglePacked(), reader.ReadSinglePacked()); } + var (isReparented, latestParent) = ReadNetworkParenting(reader); + //Attempt to create a local NetworkObject - var networkObject = networkManager.SpawnManager.CreateLocalNetworkObject(isSceneObject, prefabHash, ownerClientId, parentNetworkId, position, rotation); + var networkObject = networkManager.SpawnManager.CreateLocalNetworkObject(isSceneObject, globalObjectIdHash, ownerClientId, parentNetworkId, position, rotation, isReparented); + + networkObject?.SetNetworkParenting(isReparented, latestParent); // Determine if this NetworkObject has NetworkVariable data to read var networkVariableDataIsIncluded = reader.ReadBool(); @@ -758,7 +1031,7 @@ internal static NetworkObject DeserializeSceneObject(NetworkBuffer objectStream, if (networkObject == null) { // Log the error that the NetworkObject failed to construct - Debug.LogError($"Failed to spawn {nameof(NetworkObject)} for Hash {prefabHash}."); + Debug.LogError($"Failed to spawn {nameof(NetworkObject)} for Hash {globalObjectIdHash}."); // If we failed to load this NetworkObject, then skip past the network variable data objectStream.Position += networkVariableDataSize; diff --git a/com.unity.multiplayer.mlapi/Runtime/Exceptions/InvalidParentException.cs b/com.unity.multiplayer.mlapi/Runtime/Exceptions/InvalidParentException.cs new file mode 100644 index 0000000000..14961877c4 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Runtime/Exceptions/InvalidParentException.cs @@ -0,0 +1,14 @@ +using System; + +namespace MLAPI.Exceptions +{ + /// + /// Exception thrown when the new parent candidate of the NetworkObject is not valid + /// + public class InvalidParentException : Exception + { + public InvalidParentException() { } + public InvalidParentException(string message) : base(message) { } + public InvalidParentException(string message, Exception innerException) : base(message, innerException) { } + } +} diff --git a/com.unity.multiplayer.mlapi/Runtime/Exceptions/InvalidParentException.cs.meta b/com.unity.multiplayer.mlapi/Runtime/Exceptions/InvalidParentException.cs.meta new file mode 100644 index 0000000000..12b58cc424 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Runtime/Exceptions/InvalidParentException.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: abe1766318991412cb1aba96c4dbcc4e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageHandler.cs b/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageHandler.cs index 72de7e6bef..82a8be7f1e 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageHandler.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Messaging/InternalMessageHandler.cs @@ -161,10 +161,13 @@ public void HandleAddObject(ulong clientId, Stream stream) rot = Quaternion.Euler(reader.ReadSinglePacked(), reader.ReadSinglePacked(), reader.ReadSinglePacked()); } + var (isReparented, latestParent) = NetworkObject.ReadNetworkParenting(reader); + var hasPayload = reader.ReadBool(); var payLoadLength = hasPayload ? reader.ReadInt32Packed() : 0; - var networkObject = NetworkManager.SpawnManager.CreateLocalNetworkObject(softSync, prefabHash, ownerClientId, parentNetworkId, pos, rot); + var networkObject = NetworkManager.SpawnManager.CreateLocalNetworkObject(softSync, prefabHash, ownerClientId, parentNetworkId, pos, rot, isReparented); + networkObject.SetNetworkParenting(isReparented, latestParent); NetworkManager.SpawnManager.SpawnNetworkObjectLocally(networkObject, networkId, softSync, isPlayerObject, ownerClientId, stream, hasPayload, payLoadLength, true, false); Queue bufferQueue = NetworkManager.BufferManager.ConsumeBuffersForNetworkId(networkId); diff --git a/com.unity.multiplayer.mlapi/Runtime/Profiling/InternalMessageHandlerProfilingDecorator.cs b/com.unity.multiplayer.mlapi/Runtime/Profiling/InternalMessageHandlerProfilingDecorator.cs index 2613a2d70e..b3c76d30b1 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Profiling/InternalMessageHandlerProfilingDecorator.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Profiling/InternalMessageHandlerProfilingDecorator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using MLAPI.Messaging; using MLAPI.Messaging.Buffering; @@ -25,9 +25,9 @@ internal class InternalMessageHandlerProfilingDecorator : IInternalMessageHandle private readonly ProfilerMarker m_RpcReceiveQueueItemServerRpc = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(RpcReceiveQueueItem)}.{nameof(RpcQueueContainer.QueueItemType.ServerRpc)}"); private readonly ProfilerMarker m_RpcReceiveQueueItemClientRpc = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(RpcReceiveQueueItem)}.{nameof(RpcQueueContainer.QueueItemType.ClientRpc)}"); private readonly ProfilerMarker m_HandleAllClientsSwitchSceneCompleted = new ProfilerMarker($"{nameof(InternalMessageHandler)}.{nameof(HandleAllClientsSwitchSceneCompleted)}"); - + private readonly IInternalMessageHandler m_MessageHandler; - + internal InternalMessageHandlerProfilingDecorator(IInternalMessageHandler messageHandler) { m_MessageHandler = messageHandler; @@ -195,4 +195,4 @@ public void HandleAllClientsSwitchSceneCompleted(ulong clientId, Stream stream) m_HandleAllClientsSwitchSceneCompleted.End(); } } -} \ No newline at end of file +} diff --git a/com.unity.multiplayer.mlapi/Runtime/Spawning/NetworkSpawnManager.cs b/com.unity.multiplayer.mlapi/Runtime/Spawning/NetworkSpawnManager.cs index 466c2bc739..593bdd521e 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Spawning/NetworkSpawnManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Spawning/NetworkSpawnManager.cs @@ -8,6 +8,7 @@ using MLAPI.Logging; using MLAPI.Messaging; using MLAPI.SceneManagement; +using MLAPI.Serialization; using MLAPI.Serialization.Pooled; using MLAPI.Transports; using UnityEngine; @@ -157,11 +158,11 @@ internal void ChangeOwnership(NetworkObject networkObject, ulong clientId) /// /// Should only run on the client /// - internal NetworkObject CreateLocalNetworkObject(bool softCreate, uint prefabHash, ulong ownerClientId, ulong? parentNetworkId, Vector3? position, Quaternion? rotation) + internal NetworkObject CreateLocalNetworkObject(bool isSceneObject, uint globalObjectIdHash, ulong ownerClientId, ulong? parentNetworkId, Vector3? position, Quaternion? rotation, bool isReparented = false) { NetworkObject parentNetworkObject = null; - if (parentNetworkId != null) + if (parentNetworkId != null && !isReparented) { if (SpawnedObjects.TryGetValue(parentNetworkId.Value, out NetworkObject networkObject)) { @@ -176,13 +177,13 @@ internal NetworkObject CreateLocalNetworkObject(bool softCreate, uint prefabHash } } - if (!NetworkManager.NetworkConfig.EnableSceneManagement || !softCreate) + if (!NetworkManager.NetworkConfig.EnableSceneManagement || !isSceneObject) { // If the prefab hash has a registered INetworkPrefabInstanceHandler derived class - if (NetworkManager.PrefabHandler.ContainsHandler(prefabHash)) + if (NetworkManager.PrefabHandler.ContainsHandler(globalObjectIdHash)) { // Let the handler spawn the NetworkObject - var networkObject = NetworkManager.PrefabHandler.HandleNetworkPrefabSpawn(prefabHash, ownerClientId, position.GetValueOrDefault(Vector3.zero), rotation.GetValueOrDefault(Quaternion.identity)); + var networkObject = NetworkManager.PrefabHandler.HandleNetworkPrefabSpawn(globalObjectIdHash, ownerClientId, position.GetValueOrDefault(Vector3.zero), rotation.GetValueOrDefault(Quaternion.identity)); if (parentNetworkObject != null) { @@ -200,17 +201,17 @@ internal NetworkObject CreateLocalNetworkObject(bool softCreate, uint prefabHash { // See if there is a valid registered NetworkPrefabOverrideLink associated with the provided prefabHash GameObject networkPrefabReference = null; - if (NetworkManager.NetworkConfig.NetworkPrefabOverrideLinks.ContainsKey(prefabHash)) + if (NetworkManager.NetworkConfig.NetworkPrefabOverrideLinks.ContainsKey(globalObjectIdHash)) { - switch (NetworkManager.NetworkConfig.NetworkPrefabOverrideLinks[prefabHash].Override) + switch (NetworkManager.NetworkConfig.NetworkPrefabOverrideLinks[globalObjectIdHash].Override) { default: case NetworkPrefabOverride.None: - networkPrefabReference = NetworkManager.NetworkConfig.NetworkPrefabOverrideLinks[prefabHash].Prefab; + networkPrefabReference = NetworkManager.NetworkConfig.NetworkPrefabOverrideLinks[globalObjectIdHash].Prefab; break; case NetworkPrefabOverride.Hash: case NetworkPrefabOverride.Prefab: - networkPrefabReference = NetworkManager.NetworkConfig.NetworkPrefabOverrideLinks[prefabHash].OverridingTargetPrefab; + networkPrefabReference = NetworkManager.NetworkConfig.NetworkPrefabOverrideLinks[globalObjectIdHash].OverridingTargetPrefab; break; } } @@ -220,7 +221,7 @@ internal NetworkObject CreateLocalNetworkObject(bool softCreate, uint prefabHash { if (NetworkLog.CurrentLogLevel <= LogLevel.Error) { - NetworkLog.LogError($"Failed to create object locally. [{nameof(prefabHash)}={prefabHash}]. {nameof(NetworkPrefab)} could not be found. Is the prefab registered with {nameof(NetworkManager)}?"); + NetworkLog.LogError($"Failed to create object locally. [{nameof(globalObjectIdHash)}={globalObjectIdHash}]. {nameof(NetworkPrefab)} could not be found. Is the prefab registered with {nameof(NetworkManager)}?"); } return null; } @@ -246,16 +247,16 @@ internal NetworkObject CreateLocalNetworkObject(bool softCreate, uint prefabHash else { // SoftSync them by mapping - if (!PendingSoftSyncObjects.TryGetValue(prefabHash, out NetworkObject networkObject)) + if (!PendingSoftSyncObjects.TryGetValue(globalObjectIdHash, out NetworkObject networkObject)) { if (NetworkLog.CurrentLogLevel <= LogLevel.Error) { - NetworkLog.LogError($"{nameof(NetworkPrefab)} hash was not found! In-Scene placed {nameof(NetworkObject)} soft synchronization failure for Hash: {prefabHash}!"); + NetworkLog.LogError($"{nameof(NetworkPrefab)} hash was not found! In-Scene placed {nameof(NetworkObject)} soft synchronization failure for Hash: {globalObjectIdHash}!"); } return null; } - PendingSoftSyncObjects.Remove(prefabHash); + PendingSoftSyncObjects.Remove(globalObjectIdHash); if (parentNetworkObject != null) { @@ -332,6 +333,10 @@ internal void SpawnNetworkObjectLocally(NetworkObject networkObject, ulong netwo } } + networkObject.SetCachedParent(networkObject.transform.parent); + networkObject.ApplyNetworkParenting(); + NetworkObject.CheckOrphanChildren(); + if (readPayload) { using (var payloadBuffer = PooledNetworkBuffer.Get()) @@ -375,7 +380,7 @@ internal void SendSpawnCallForObject(ulong clientId, NetworkObject networkObject rpcQueueContainer.AddToInternalMLAPISendQueue(queueItem); } - internal void WriteSpawnCallForObject(Serialization.NetworkBuffer buffer, ulong clientId, NetworkObject networkObject, Stream payload) + internal void WriteSpawnCallForObject(NetworkBuffer buffer, ulong clientId, NetworkObject networkObject, Stream payload) { using (var writer = PooledNetworkWriter.Get(buffer)) { @@ -419,6 +424,11 @@ internal void WriteSpawnCallForObject(Serialization.NetworkBuffer buffer, ulong writer.WriteBool(false); } + { + var (isReparented, latestParent) = networkObject.GetNetworkParenting(); + NetworkObject.WriteNetworkParenting(writer, isReparented, latestParent); + } + writer.WriteBool(payload != null); if (payload != null) @@ -597,26 +607,41 @@ internal void ClientCollectSoftSyncSceneObjectSweep(NetworkObject[] networkObjec } } - internal void OnDespawnObject(ulong networkId, bool destroyGameObject) + internal void OnDespawnObject(ulong networkObjectId, bool destroyGameObject) { if (NetworkManager == null) { return; } - //Removal of spawned object - if (!SpawnedObjects.TryGetValue(networkId, out NetworkObject networkObject)) + // Removal of spawned object + if (!SpawnedObjects.TryGetValue(networkObjectId, out NetworkObject networkObject)) { - Debug.LogWarning($"Trying to destroy object {networkId} but it doesn't seem to exist anymore!"); + Debug.LogWarning($"Trying to destroy object {networkObjectId} but it doesn't seem to exist anymore!"); return; } + // Move child NetworkObjects to the root when parent NetworkObject is destroyed + foreach (var spawnedNetObj in SpawnedObjectsList) + { + var (isReparented, latestParent) = spawnedNetObj.GetNetworkParenting(); + if (isReparented && latestParent == networkObjectId) + { + spawnedNetObj.gameObject.transform.parent = null; + + if (NetworkLog.CurrentLogLevel <= LogLevel.Normal) + { + NetworkLog.LogWarning($"{nameof(NetworkObject)} #{spawnedNetObj.NetworkObjectId} moved to the root because its parent {nameof(NetworkObject)} #{networkObjectId} is destroyed"); + } + } + } + if (!networkObject.IsOwnedByServer && !networkObject.IsPlayerObject && NetworkManager.Singleton.ConnectedClients.TryGetValue(networkObject.OwnerClientId, out NetworkClient networkClient)) { //Someone owns it. for (int i = networkClient.OwnedObjects.Count - 1; i > -1; i--) { - if (networkClient.OwnedObjects[i].NetworkObjectId == networkId) + if (networkClient.OwnedObjects[i].NetworkObjectId == networkObjectId) { networkClient.OwnedObjects.RemoveAt(i); } @@ -632,7 +657,7 @@ internal void OnDespawnObject(ulong networkId, bool destroyGameObject) { ReleasedNetworkObjectIds.Enqueue(new ReleasedNetworkId() { - NetworkId = networkId, + NetworkId = networkObjectId, ReleaseTime = Time.unscaledTime }); } @@ -648,13 +673,13 @@ internal void OnDespawnObject(ulong networkId, bool destroyGameObject) var buffer = PooledNetworkBuffer.Get(); using (var writer = PooledNetworkWriter.Get(buffer)) { - writer.WriteUInt64Packed(networkId); + writer.WriteUInt64Packed(networkObjectId); var queueItem = new RpcFrameQueueItem { UpdateStage = NetworkUpdateStage.PostLateUpdate, QueueItemType = RpcQueueContainer.QueueItemType.DestroyObject, - NetworkId = networkId, + NetworkId = networkObjectId, NetworkBuffer = buffer, NetworkChannel = NetworkChannel.Internal, ClientNetworkIds = NetworkManager.ConnectedClientsList.Select(c => c.ClientId).ToArray() @@ -674,7 +699,7 @@ internal void OnDespawnObject(ulong networkId, bool destroyGameObject) if (NetworkManager.PrefabHandler.ContainsHandler(networkObject)) { NetworkManager.PrefabHandler.HandleNetworkPrefabDestroy(networkObject); - OnDespawnObject(networkId, false); + OnDespawnObject(networkObjectId, false); } else { @@ -685,7 +710,7 @@ internal void OnDespawnObject(ulong networkId, bool destroyGameObject) // for some reason, we can get down here and SpawnedObjects for this // networkId will no longer be here, even as we check this at the start // of the function - if (SpawnedObjects.Remove(networkId)) + if (SpawnedObjects.Remove(networkObjectId)) { SpawnedObjectsList.Remove(networkObject); } diff --git a/com.unity.multiplayer.mlapi/Tests/Editor/DummyMessageHandler.cs b/com.unity.multiplayer.mlapi/Tests/Editor/DummyMessageHandler.cs index 54f9d94f22..f6a28be50f 100644 --- a/com.unity.multiplayer.mlapi/Tests/Editor/DummyMessageHandler.cs +++ b/com.unity.multiplayer.mlapi/Tests/Editor/DummyMessageHandler.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using MLAPI.Messaging; using MLAPI.Messaging.Buffering; @@ -49,4 +49,4 @@ private void VerifyCalled(string method) Debug.Log(method); } } -} \ No newline at end of file +} diff --git a/com.unity.multiplayer.mlapi/Tests/Editor/Profiling/InternalMessageHandlerProfilingDecoratorTests.cs b/com.unity.multiplayer.mlapi/Tests/Editor/Profiling/InternalMessageHandlerProfilingDecoratorTests.cs index 2d60f99b09..bbe369642c 100644 --- a/com.unity.multiplayer.mlapi/Tests/Editor/Profiling/InternalMessageHandlerProfilingDecoratorTests.cs +++ b/com.unity.multiplayer.mlapi/Tests/Editor/Profiling/InternalMessageHandlerProfilingDecoratorTests.cs @@ -1,4 +1,4 @@ -using MLAPI.Messaging; +using MLAPI.Messaging; using MLAPI.Profiling; using NUnit.Framework; using UnityEngine; @@ -144,4 +144,4 @@ public void HandleAllClientsSwitchSceneCompleted() LogAssert.Expect(LogType.Log, nameof(m_Decorator.HandleAllClientsSwitchSceneCompleted)); } } -} \ No newline at end of file +} diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/GlobalObjectIdHash/NetworkObjectGlobalObjectIdHashTests.cs b/com.unity.multiplayer.mlapi/Tests/Runtime/GlobalObjectIdHash/NetworkObjectGlobalObjectIdHashTests.cs index e9ff195a02..c1b52cf410 100644 --- a/com.unity.multiplayer.mlapi/Tests/Runtime/GlobalObjectIdHash/NetworkObjectGlobalObjectIdHashTests.cs +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/GlobalObjectIdHash/NetworkObjectGlobalObjectIdHashTests.cs @@ -32,6 +32,7 @@ public IEnumerator Setup() var scenePath = Path.Combine(packagePath, $"Tests/Runtime/GlobalObjectIdHash/{nameof(NetworkObjectGlobalObjectIdHashTests)}.unity"); yield return EditorSceneManager.LoadSceneAsyncInPlayMode(scenePath, new LoadSceneParameters(LoadSceneMode.Additive)); + Assert.That(m_TestScene.isLoaded, Is.True); } [UnityTearDown] @@ -48,8 +49,6 @@ public IEnumerator Teardown() [Test] public void VerifyUniquenessOfNetworkObjects() { - Assert.That(m_TestScene.isLoaded, Is.True); - var hashSet = new HashSet(); foreach (var rootObject in m_TestScene.GetRootGameObjects()) { diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting.meta b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting.meta new file mode 100644 index 0000000000..63a52b767a --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4b0e72312f6c8404891c5cb3f2a3f36d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/BlueColMat.mat b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/BlueColMat.mat new file mode 100644 index 0000000000..f56846b713 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/BlueColMat.mat @@ -0,0 +1,79 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: BlueColMat + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0, g: 0, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/BlueColMat.mat.meta b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/BlueColMat.mat.meta new file mode 100644 index 0000000000..6df17a3b9b --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/BlueColMat.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 52c34e1beacd44c9bb0f6375c891b4cf +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GrayColMat.mat b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GrayColMat.mat new file mode 100644 index 0000000000..fba9482df6 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GrayColMat.mat @@ -0,0 +1,79 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: GrayColMat + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.2, g: 0.2, b: 0.2, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GrayColMat.mat.meta b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GrayColMat.mat.meta new file mode 100644 index 0000000000..35533b8924 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GrayColMat.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 03e094ab168544996a7d1d6dcdc60058 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GreenColMat.mat b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GreenColMat.mat new file mode 100644 index 0000000000..f4f7e2b5d3 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GreenColMat.mat @@ -0,0 +1,79 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: GreenColMat + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0, g: 1, b: 0, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GreenColMat.mat.meta b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GreenColMat.mat.meta new file mode 100644 index 0000000000..6cc05ba8f0 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/GreenColMat.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d8e0487da5b3d4659909d18d138cff5a +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.cs b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.cs new file mode 100644 index 0000000000..3a4608b674 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.cs @@ -0,0 +1,288 @@ +using System.Collections; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text.RegularExpressions; +using NUnit.Framework; +using UnityEditor.PackageManager; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.TestTools; + +namespace MLAPI.RuntimeTests +{ + public class NetworkObjectParentingTests + { + private const int k_ClientInstanceCount = 1; + + private NetworkManager m_ServerNetworkManager; + private NetworkManager[] m_ClientNetworkManagers; + + private Transform[] m_Dude_NetObjs; + private Transform[] m_Dude_LeftArm_NetObjs; + private Transform[] m_Dude_RightArm_NetObjs; + private Transform[] m_Dude_LeftLeg_NetObjs; + private Transform[] m_Dude_RightLeg_NetObjs; + private Transform[] m_Cube_NetObjs; + private ReparentingCubeNetBhv[] m_Cube_NetBhvs; + private Transform[] m_Pickup_NetObjs; + private Transform[] m_Pickup_Back_NetObjs; + + private Scene m_InitScene; + private Scene m_TestScene; + + private void OnSceneLoaded(Scene scene, LoadSceneMode mode) + { + if (scene.name == nameof(NetworkObjectParentingTests)) + { + m_TestScene = scene; + } + } + + [UnitySetUp] + public IEnumerator Setup() + { + SceneManager.sceneLoaded += OnSceneLoaded; + + var execAssembly = Assembly.GetExecutingAssembly(); + var packagePath = PackageInfo.FindForAssembly(execAssembly).assetPath; + var scenePath = Path.Combine(packagePath, $"Tests/Runtime/ObjectParenting/{nameof(NetworkObjectParentingTests)}.unity"); + + m_InitScene = SceneManager.GetActiveScene(); + yield return EditorSceneManager.LoadSceneAsyncInPlayMode(scenePath, new LoadSceneParameters(LoadSceneMode.Additive)); + Assert.That(m_TestScene.isLoaded, Is.True); + SceneManager.SetActiveScene(m_TestScene); + + const int setCount = k_ClientInstanceCount + 1; + + Assert.That(MultiInstanceHelpers.Create(k_ClientInstanceCount, out m_ServerNetworkManager, out m_ClientNetworkManagers)); + Assert.That(m_ServerNetworkManager, Is.Not.Null); + Assert.That(m_ClientNetworkManagers, Is.Not.Null); + Assert.That(m_ClientNetworkManagers.Length, Is.EqualTo(k_ClientInstanceCount)); + + m_Dude_NetObjs = new Transform[setCount]; + m_Dude_LeftArm_NetObjs = new Transform[setCount]; + m_Dude_RightArm_NetObjs = new Transform[setCount]; + m_Dude_LeftLeg_NetObjs = new Transform[setCount]; + m_Dude_RightLeg_NetObjs = new Transform[setCount]; + m_Cube_NetObjs = new Transform[setCount]; + m_Cube_NetBhvs = new ReparentingCubeNetBhv[setCount]; + m_Pickup_NetObjs = new Transform[setCount]; + m_Pickup_Back_NetObjs = new Transform[setCount]; + + var serverSet = m_TestScene.GetRootGameObjects().FirstOrDefault(g => g.name == "Set"); + Assert.That(serverSet, Is.Not.Null); + + SetupSet(serverSet.transform, 0, m_ServerNetworkManager); + serverSet.name = "Set0 (Server)"; + + for (int setIndex = 0; setIndex < k_ClientInstanceCount; setIndex++) + { + var clientSet = Object.Instantiate(serverSet); + SetupSet(clientSet.transform, setIndex + 1, m_ClientNetworkManagers[setIndex]); + clientSet.name = $"Set{setIndex + 1} (Client)"; + } + + // Start server and client NetworkManager instances + Assert.That(MultiInstanceHelpers.Start(true, m_ServerNetworkManager, m_ClientNetworkManagers)); + + // Wait for connection on client side + yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.WaitForClientsConnected(m_ClientNetworkManagers)); + + // Wait for connection on server side + yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.WaitForClientConnectedToServer(m_ServerNetworkManager)); + } + + public void SetupSet(Transform rootTransform, int setIndex, NetworkManager networkManager) + { + foreach (Transform childTransform0 in rootTransform) + { + if (childTransform0.name == "Dude (NetObj)") + { + m_Dude_NetObjs[setIndex] = childTransform0; + m_Dude_NetObjs[setIndex].GetComponent().NetworkManagerOwner = networkManager; + foreach (Transform childTransform1 in childTransform0) + { + if (childTransform1.name == "Arms") + { + foreach (Transform childTransform2 in childTransform1) + { + if (childTransform2.name == "LeftArm (NetObj)") + { + m_Dude_LeftArm_NetObjs[setIndex] = childTransform2; + m_Dude_LeftArm_NetObjs[setIndex].GetComponent().NetworkManagerOwner = networkManager; + } + else if (childTransform2.name == "RightArm (NetObj)") + { + m_Dude_RightArm_NetObjs[setIndex] = childTransform2; + m_Dude_RightArm_NetObjs[setIndex].GetComponent().NetworkManagerOwner = networkManager; + } + } + } + else if (childTransform1.name == "Legs") + { + foreach (Transform childTransform2 in childTransform1) + { + if (childTransform2.name == "LeftLeg (NetObj)") + { + m_Dude_LeftLeg_NetObjs[setIndex] = childTransform2; + m_Dude_LeftLeg_NetObjs[setIndex].GetComponent().NetworkManagerOwner = networkManager; + } + else if (childTransform2.name == "RightLeg (NetObj)") + { + m_Dude_RightLeg_NetObjs[setIndex] = childTransform2; + m_Dude_RightLeg_NetObjs[setIndex].GetComponent().NetworkManagerOwner = networkManager; + } + } + } + } + } + else if (childTransform0.name == "Cube (NetObj)") + { + m_Cube_NetObjs[setIndex] = childTransform0; + + var networkObject = childTransform0.GetComponent(); + var networkBehaviour = childTransform0.GetComponent(); + + networkObject.NetworkManagerOwner = networkManager; + m_Cube_NetBhvs[setIndex] = networkBehaviour; + } + else if (childTransform0.name == "Pickup (NetObj)") + { + m_Pickup_NetObjs[setIndex] = childTransform0; + m_Pickup_NetObjs[setIndex].GetComponent().NetworkManagerOwner = networkManager; + foreach (Transform childTransform1 in childTransform0) + { + if (childTransform1.name == "Body") + { + foreach (Transform childTransform2 in childTransform1) + { + if (childTransform2.name == "Back (NetObj)") + { + m_Pickup_Back_NetObjs[setIndex] = childTransform2; + m_Pickup_Back_NetObjs[setIndex].GetComponent().NetworkManagerOwner = networkManager; + } + } + } + } + } + } + + Assert.That(m_Dude_NetObjs[setIndex], Is.Not.Null); + Assert.That(m_Dude_LeftArm_NetObjs[setIndex], Is.Not.Null); + Assert.That(m_Dude_RightArm_NetObjs[setIndex], Is.Not.Null); + Assert.That(m_Dude_LeftLeg_NetObjs[setIndex], Is.Not.Null); + Assert.That(m_Dude_RightLeg_NetObjs[setIndex], Is.Not.Null); + Assert.That(m_Cube_NetObjs[setIndex], Is.Not.Null); + Assert.That(m_Cube_NetBhvs[setIndex], Is.Not.Null); + Assert.That(m_Cube_NetBhvs[setIndex].ParentNetworkObject, Is.Null); + Assert.That(m_Pickup_NetObjs[setIndex], Is.Not.Null); + Assert.That(m_Pickup_Back_NetObjs[setIndex], Is.Not.Null); + + LogAssert.Expect(LogType.Exception, new Regex("start a server or host", RegexOptions.IgnoreCase)); + var cachedParent = m_Cube_NetObjs[setIndex].parent; + m_Cube_NetObjs[setIndex].parent = m_Pickup_NetObjs[setIndex]; + Assert.That(m_Cube_NetObjs[setIndex].parent, Is.EqualTo(cachedParent)); + } + + [UnityTearDown] + public IEnumerator Teardown() + { + SceneManager.sceneLoaded -= OnSceneLoaded; + + MultiInstanceHelpers.Destroy(); + + if (m_TestScene.isLoaded) + { + yield return SceneManager.UnloadSceneAsync(m_TestScene); + SceneManager.SetActiveScene(m_InitScene); + } + } + + [UnityTest] + public IEnumerator SetParentDirect() + { + // Server: Set/Cube -> Set/Pickup/Back/Cube + m_Cube_NetObjs[0].parent = m_Pickup_Back_NetObjs[0]; + Assert.That(m_Cube_NetBhvs[0].ParentNetworkObject, Is.EqualTo(m_Pickup_Back_NetObjs[0].GetComponent())); + + int nextFrameNumber = Time.frameCount + 2; + yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber); + + // Client[n]: Set/Cube -> Set/Pickup/Back/Cube + for (int setIndex = 0; setIndex < k_ClientInstanceCount; setIndex++) + { + Assert.That(m_Cube_NetObjs[setIndex + 1].parent, Is.EqualTo(m_Pickup_Back_NetObjs[setIndex + 1])); + Assert.That(m_Cube_NetBhvs[setIndex + 1].ParentNetworkObject, Is.EqualTo(m_Pickup_Back_NetObjs[setIndex + 1].GetComponent())); + } + + + // Server: Set/Pickup/Back -> Root/Cube + m_Cube_NetObjs[0].parent = null; + Assert.That(m_Cube_NetBhvs[0].ParentNetworkObject, Is.EqualTo(null)); + + nextFrameNumber = Time.frameCount + 2; + yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber); + + // Client[n]: Set/Pickup/Back -> Root/Cube + for (int setIndex = 0; setIndex < k_ClientInstanceCount; setIndex++) + { + Assert.That(m_Cube_NetObjs[setIndex + 1].parent, Is.EqualTo(null)); + Assert.That(m_Cube_NetBhvs[setIndex + 1].ParentNetworkObject, Is.EqualTo(null)); + } + + + // Server: Root/Cube -> Set/Dude/Arms/RightArm/Cube + m_Cube_NetObjs[0].parent = m_Dude_RightArm_NetObjs[0]; + Assert.That(m_Cube_NetBhvs[0].ParentNetworkObject, Is.EqualTo(m_Dude_RightArm_NetObjs[0].GetComponent())); + + nextFrameNumber = Time.frameCount + 2; + yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber); + + // Client[n]: Root/Cube -> Set/Dude/Arms/RightArm/Cube + for (int setIndex = 0; setIndex < k_ClientInstanceCount; setIndex++) + { + Assert.That(m_Cube_NetObjs[setIndex + 1].parent, Is.EqualTo(m_Dude_RightArm_NetObjs[setIndex + 1])); + Assert.That(m_Cube_NetBhvs[setIndex + 1].ParentNetworkObject, Is.EqualTo(m_Dude_RightArm_NetObjs[setIndex + 1].GetComponent())); + } + } + + [UnityTest] + public IEnumerator SetParentTryAPI() + { + // Try(Cube -> MainCamera/Cube): false + var serverCachedParent = m_Cube_NetObjs[0].parent; + var clientCachedParents = new Transform[k_ClientInstanceCount]; + for (int setIndex = 0; setIndex < k_ClientInstanceCount; setIndex++) + { + clientCachedParents[setIndex] = m_Cube_NetObjs[setIndex + 1].parent; + } + + Assert.That(!m_Cube_NetObjs[0].GetComponent().TrySetParent(Camera.main.transform)); + + int nextFrameNumber = Time.frameCount + 2; + yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber); + + Assert.That(m_Cube_NetObjs[0].parent, Is.EqualTo(serverCachedParent)); + for (int setIndex = 0; setIndex < k_ClientInstanceCount; setIndex++) + { + Assert.That(m_Cube_NetObjs[setIndex + 1].parent, Is.EqualTo(clientCachedParents[setIndex])); + } + + + // Try(Cube -> Set/Dude/Arms/LeftArm/Cube): true + Assert.That(m_Cube_NetObjs[0].GetComponent().TrySetParent(m_Dude_LeftArm_NetObjs[0])); + Assert.That(m_Cube_NetBhvs[0].ParentNetworkObject, Is.EqualTo(m_Dude_LeftArm_NetObjs[0].GetComponent())); + + nextFrameNumber = Time.frameCount + 2; + yield return new WaitUntil(() => Time.frameCount >= nextFrameNumber); + + for (int setIndex = 0; setIndex < k_ClientInstanceCount; setIndex++) + { + Assert.That(m_Cube_NetObjs[setIndex + 1].parent, Is.EqualTo(m_Dude_LeftArm_NetObjs[setIndex + 1])); + Assert.That(m_Cube_NetBhvs[setIndex + 1].ParentNetworkObject, Is.EqualTo(m_Dude_LeftArm_NetObjs[setIndex + 1].GetComponent())); + } + } + } +} diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.cs.meta b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.cs.meta new file mode 100644 index 0000000000..bcd376301e --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee0fd7f2f6c544c59849f815c90128b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.unity b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.unity new file mode 100644 index 0000000000..7640744d8d --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.unity @@ -0,0 +1,2227 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44657874, g: 0.49641275, b: 0.5748172, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &126426935 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 126426939} + - component: {fileID: 126426938} + - component: {fileID: 126426937} + - component: {fileID: 126426936} + m_Layer: 0 + m_Name: Ground + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!64 &126426936 +MeshCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 126426935} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 4 + m_Convex: 0 + m_CookingOptions: 30 + m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &126426937 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 126426935} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 03e094ab168544996a7d1d6dcdc60058, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &126426938 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 126426935} + m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &126426939 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 126426935} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 10, y: 1, z: 10} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &136229882 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 136229883} + - component: {fileID: 136229886} + - component: {fileID: 136229885} + - component: {fileID: 136229884} + - component: {fileID: 136229887} + m_Layer: 0 + m_Name: LeftArm (NetObj) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &136229883 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 136229882} + m_LocalRotation: {x: 0, y: 0, z: 0.13052616, w: 0.9914449} + m_LocalPosition: {x: 0.6, y: 0.2, z: 0} + m_LocalScale: {x: 0.3, y: 0.8, z: 0.3} + m_Children: [] + m_Father: {fileID: 1233633000} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 15} +--- !u!136 &136229884 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 136229882} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + m_Radius: 0.5 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &136229885 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 136229882} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &136229886 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 136229882} + m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} +--- !u!114 &136229887 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 136229882} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 1291518364 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 +--- !u!1 &223562595 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 223562596} + m_Layer: 0 + m_Name: Legs + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &223562596 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 223562595} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 877191011} + - {fileID: 1646178338} + m_Father: {fileID: 753527895} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &249733529 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 249733530} + - component: {fileID: 249733533} + - component: {fileID: 249733532} + - component: {fileID: 249733531} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &249733530 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 249733529} + m_LocalRotation: {x: -0.42261827, y: 0, z: 0, w: 0.9063079} + m_LocalPosition: {x: 0, y: 1.25, z: 2.5} + m_LocalScale: {x: 4, y: 2.3, z: 1} + m_Children: [] + m_Father: {fileID: 1904043517} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: -50, y: 0, z: 0} +--- !u!65 &249733531 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 249733529} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &249733532 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 249733529} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 52c34e1beacd44c9bb0f6375c891b4cf, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &249733533 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 249733529} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &305396494 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 305396495} + - component: {fileID: 305396498} + - component: {fileID: 305396497} + - component: {fileID: 305396496} + m_Layer: 0 + m_Name: Sphere + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &305396495 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 305396494} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0.1, y: 0.1, z: 0.1} + m_Children: [] + m_Father: {fileID: 2027339602} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!135 &305396496 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 305396494} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Radius: 0.5 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &305396497 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 305396494} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &305396498 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 305396494} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &453914372 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 453914373} + - component: {fileID: 453914376} + - component: {fileID: 453914375} + - component: {fileID: 453914374} + - component: {fileID: 453914377} + m_Layer: 0 + m_Name: RightArm (NetObj) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &453914373 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 453914372} + m_LocalRotation: {x: 0, y: 0, z: -0.13052624, w: 0.9914449} + m_LocalPosition: {x: -0.6, y: 0.2, z: 0} + m_LocalScale: {x: 0.3, y: 0.8, z: 0.3} + m_Children: [] + m_Father: {fileID: 1233633000} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: -15} +--- !u!136 &453914374 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 453914372} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + m_Radius: 0.5 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &453914375 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 453914372} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &453914376 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 453914372} + m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} +--- !u!114 &453914377 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 453914372} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 2501551336 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 +--- !u!1 &534941258 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 534941259} + - component: {fileID: 534941262} + - component: {fileID: 534941261} + - component: {fileID: 534941260} + m_Layer: 0 + m_Name: FrontRightWheel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &534941259 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 534941258} + m_LocalRotation: {x: 0, y: 0, z: 0.7071068, w: 0.7071068} + m_LocalPosition: {x: 2.5, y: -1, z: 3.5} + m_LocalScale: {x: 2, y: 0.5, z: 2} + m_Children: [] + m_Father: {fileID: 1095337960} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 90} +--- !u!136 &534941260 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 534941258} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + m_Radius: 0.5000001 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0.000000059604645, y: 0, z: -0.00000008940697} +--- !u!23 &534941261 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 534941258} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &534941262 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 534941258} + m_Mesh: {fileID: 10206, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &590215650 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 590215651} + - component: {fileID: 590215654} + - component: {fileID: 590215653} + - component: {fileID: 590215652} + m_Layer: 0 + m_Name: BackRightWheel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &590215651 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 590215650} + m_LocalRotation: {x: 0, y: 0, z: 0.7071068, w: 0.7071068} + m_LocalPosition: {x: 2.5, y: -1, z: -3.5} + m_LocalScale: {x: 2, y: 0.5, z: 2} + m_Children: [] + m_Father: {fileID: 1095337960} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 90} +--- !u!136 &590215652 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 590215650} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + m_Radius: 0.5000001 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0.000000059604645, y: 0, z: -0.00000008940697} +--- !u!23 &590215653 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 590215650} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &590215654 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 590215650} + m_Mesh: {fileID: 10206, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &598123439 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 598123441} + - component: {fileID: 598123440} + m_Layer: 0 + m_Name: DirectionalLight + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &598123440 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 598123439} + m_Enabled: 1 + serializedVersion: 10 + m_Type: 1 + m_Shape: 0 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &598123441 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 598123439} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &753527891 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 753527895} + - component: {fileID: 753527894} + - component: {fileID: 753527893} + - component: {fileID: 753527892} + - component: {fileID: 753527896} + m_Layer: 0 + m_Name: Dude (NetObj) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!136 &753527892 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 753527891} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + m_Radius: 0.5 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &753527893 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 753527891} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &753527894 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 753527891} + m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &753527895 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 753527891} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 779041968} + - {fileID: 1233633000} + - {fileID: 223562596} + m_Father: {fileID: 1618484849} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &753527896 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 753527891} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 3039817976 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 +--- !u!1 &779041967 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 779041968} + - component: {fileID: 779041971} + - component: {fileID: 779041970} + - component: {fileID: 779041969} + m_Layer: 0 + m_Name: Head + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &779041968 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 779041967} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1.4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 753527895} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!135 &779041969 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 779041967} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Radius: 0.5 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &779041970 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 779041967} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &779041971 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 779041967} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &877191010 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 877191011} + - component: {fileID: 877191015} + - component: {fileID: 877191014} + - component: {fileID: 877191013} + - component: {fileID: 877191012} + m_Layer: 0 + m_Name: LeftLeg (NetObj) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &877191011 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 877191010} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.3, y: -1.4, z: 0} + m_LocalScale: {x: 0.30000004, y: 0.8, z: 0.3} + m_Children: [] + m_Father: {fileID: 223562596} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &877191012 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 877191010} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 4012496145 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 +--- !u!136 &877191013 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 877191010} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + m_Radius: 0.5 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &877191014 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 877191010} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &877191015 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 877191010} + m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &1042922634 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1042922635} + - component: {fileID: 1042922638} + - component: {fileID: 1042922637} + - component: {fileID: 1042922636} + m_Layer: 0 + m_Name: BackLeftWheel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1042922635 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042922634} + m_LocalRotation: {x: 0, y: 0, z: 0.7071068, w: 0.7071068} + m_LocalPosition: {x: -2.5, y: -1, z: -3.5} + m_LocalScale: {x: 2, y: 0.5, z: 2} + m_Children: [] + m_Father: {fileID: 1095337960} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 90} +--- !u!136 &1042922636 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042922634} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + m_Radius: 0.5000001 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0.000000059604645, y: 0, z: -0.00000008940697} +--- !u!23 &1042922637 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042922634} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1042922638 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042922634} + m_Mesh: {fileID: 10206, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &1095337959 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1095337960} + m_Layer: 0 + m_Name: Wheels + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1095337960 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1095337959} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2102441317} + - {fileID: 534941259} + - {fileID: 1042922635} + - {fileID: 590215651} + m_Father: {fileID: 1907713851} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1139821555 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1139821556} + - component: {fileID: 1139821559} + - component: {fileID: 1139821558} + - component: {fileID: 1139821557} + m_Layer: 0 + m_Name: Main + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1139821556 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1139821555} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 5, y: 2, z: 10} + m_Children: [] + m_Father: {fileID: 1904043517} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &1139821557 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1139821555} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1139821558 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1139821555} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 52c34e1beacd44c9bb0f6375c891b4cf, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1139821559 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1139821555} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &1233632999 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1233633000} + m_Layer: 0 + m_Name: Arms + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1233633000 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1233632999} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 136229883} + - {fileID: 453914373} + m_Father: {fileID: 753527895} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1346726830 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1346726835} + - component: {fileID: 1346726834} + - component: {fileID: 1346726833} + - component: {fileID: 1346726832} + - component: {fileID: 1346726831} + - component: {fileID: 1346726836} + m_Layer: 0 + m_Name: Cube (NetObj) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1346726831 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1346726830} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 4270594269 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 +--- !u!65 &1346726832 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1346726830} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1346726833 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1346726830} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: d8e0487da5b3d4659909d18d138cff5a, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1346726834 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1346726830} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1346726835 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1346726830} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 3, y: 0.5, z: 3} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1618484849} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1346726836 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1346726830} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9b9fb5b91091c4036bb4b0321b79f6c8, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1463134322 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1463134325} + - component: {fileID: 1463134324} + - component: {fileID: 1463134323} + m_Layer: 0 + m_Name: MainCamera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &1463134323 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1463134322} + m_Enabled: 1 +--- !u!20 &1463134324 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1463134322} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &1463134325 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1463134322} + m_LocalRotation: {x: 0.2588191, y: 0, z: 0, w: 0.9659258} + m_LocalPosition: {x: 0, y: 10, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 30, y: 0, z: 0} +--- !u!1 &1522146278 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1522146279} + - component: {fileID: 1522146282} + - component: {fileID: 1522146281} + - component: {fileID: 1522146280} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1522146279 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1522146278} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1.75, z: 1} + m_LocalScale: {x: 4.5, y: 1.5, z: 2} + m_Children: [] + m_Father: {fileID: 1904043517} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!65 &1522146280 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1522146278} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1522146281 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1522146278} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 52c34e1beacd44c9bb0f6375c891b4cf, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1522146282 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1522146278} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &1618484848 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1618484849} + m_Layer: 0 + m_Name: Set + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1618484849 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1618484848} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 753527895} + - {fileID: 1346726835} + - {fileID: 1907713851} + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1646178337 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1646178338} + - component: {fileID: 1646178342} + - component: {fileID: 1646178341} + - component: {fileID: 1646178340} + - component: {fileID: 1646178339} + m_Layer: 0 + m_Name: RightLeg (NetObj) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1646178338 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1646178337} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -0.3, y: -1.4, z: 0} + m_LocalScale: {x: 0.30000004, y: 0.8, z: 0.3} + m_Children: [] + m_Father: {fileID: 223562596} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1646178339 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1646178337} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 1239503228 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 +--- !u!136 &1646178340 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1646178337} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + m_Radius: 0.5 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1646178341 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1646178337} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1646178342 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1646178337} + m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} +--- !u!1 &1904043516 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1904043517} + m_Layer: 0 + m_Name: Body + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1904043517 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1904043516} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1139821556} + - {fileID: 1522146279} + - {fileID: 249733530} + - {fileID: 2027339602} + m_Father: {fileID: 1907713851} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1907713849 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1907713851} + - component: {fileID: 1907713850} + m_Layer: 0 + m_Name: Pickup (NetObj) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1907713850 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1907713849} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 2387167595 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 +--- !u!4 &1907713851 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1907713849} + m_LocalRotation: {x: -0, y: 0.5, z: -0, w: 0.8660254} + m_LocalPosition: {x: 0, y: 2, z: 10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1904043517} + - {fileID: 1095337960} + m_Father: {fileID: 1618484849} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 60, z: 0} +--- !u!1 &2027339601 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2027339602} + - component: {fileID: 2027339603} + m_Layer: 0 + m_Name: Back (NetObj) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2027339602 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2027339601} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -2} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 305396495} + m_Father: {fileID: 1904043517} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &2027339603 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2027339601} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 805918072 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 +--- !u!1 &2102441316 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2102441317} + - component: {fileID: 2102441320} + - component: {fileID: 2102441319} + - component: {fileID: 2102441318} + m_Layer: 0 + m_Name: FrontLeftWheel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2102441317 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2102441316} + m_LocalRotation: {x: 0, y: 0, z: 0.7071068, w: 0.7071068} + m_LocalPosition: {x: -2.5, y: -1, z: 3.5} + m_LocalScale: {x: 2, y: 0.5, z: 2} + m_Children: [] + m_Father: {fileID: 1095337960} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 90} +--- !u!136 &2102441318 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2102441316} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + m_Radius: 0.5000001 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0.000000059604645, y: 0, z: -0.00000008940697} +--- !u!23 &2102441319 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2102441316} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &2102441320 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2102441316} + m_Mesh: {fileID: 10206, guid: 0000000000000000e000000000000000, type: 0} diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.unity.meta b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.unity.meta new file mode 100644 index 0000000000..73144b7868 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/NetworkObjectParentingTests.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7522f8723c5674939a3c24acfd83a688 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/PlayerPrefab.prefab b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/PlayerPrefab.prefab new file mode 100644 index 0000000000..d326e03f6f --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/PlayerPrefab.prefab @@ -0,0 +1,49 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &8133991607019124060 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8133991607019124062} + - component: {fileID: 8133991607019124063} + m_Layer: 0 + m_Name: GhostPlayer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8133991607019124062 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8133991607019124060} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8133991607019124063 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8133991607019124060} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3} + m_Name: + m_EditorClassIdentifier: + GlobalObjectIdHash: 951099334 + AlwaysReplicateAsRoot: 0 + DontDestroyWithOwner: 0 + AutoObjectParentSync: 1 diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/PlayerPrefab.prefab.meta b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/PlayerPrefab.prefab.meta new file mode 100644 index 0000000000..c0781023b2 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/PlayerPrefab.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 421bcf732fe69486d8abecfa5eee63bb +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/ReparentingCubeNetBhv.cs b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/ReparentingCubeNetBhv.cs new file mode 100644 index 0000000000..2f0061a566 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/ReparentingCubeNetBhv.cs @@ -0,0 +1,12 @@ +namespace MLAPI.RuntimeTests +{ + public class ReparentingCubeNetBhv : NetworkBehaviour + { + public NetworkObject ParentNetworkObject { get; private set; } + + public override void OnNetworkObjectParentChanged(NetworkObject parentNetworkObject) + { + ParentNetworkObject = parentNetworkObject; + } + } +} diff --git a/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/ReparentingCubeNetBhv.cs.meta b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/ReparentingCubeNetBhv.cs.meta new file mode 100644 index 0000000000..3d405245c3 --- /dev/null +++ b/com.unity.multiplayer.mlapi/Tests/Runtime/ObjectParenting/ReparentingCubeNetBhv.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9b9fb5b91091c4036bb4b0321b79f6c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Scenes/SampleScene.unity b/testproject/Assets/Scenes/SampleScene.unity index 97db527944..fa5231a972 100644 --- a/testproject/Assets/Scenes/SampleScene.unity +++ b/testproject/Assets/Scenes/SampleScene.unity @@ -3474,3 +3474,4 @@ MeshFilter: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2036456027} m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} + \ No newline at end of file diff --git a/testproject/Assets/Scripts/ScalingCube.cs b/testproject/Assets/Scripts/ScalingCube.cs index 637db73bb5..4ec6249915 100644 --- a/testproject/Assets/Scripts/ScalingCube.cs +++ b/testproject/Assets/Scripts/ScalingCube.cs @@ -1,5 +1,3 @@ -using System.Collections; -using System.Collections.Generic; using MLAPI; using UnityEngine; @@ -7,10 +5,11 @@ public class ScalingCube : MonoBehaviour { private void Update() { - if (!NetworkManager.Singleton.IsServer) + if (NetworkManager.Singleton == null || !NetworkManager.Singleton.IsServer) { return; } + transform.localScale = new Vector3(Mathf.Repeat(Time.time * 2, 3f), transform.localScale.y, transform.localScale.z); } } diff --git a/testproject/Assets/Scripts/testproject.asmdef b/testproject/Assets/Scripts/testproject.asmdef index 8ad2974762..a181237134 100644 --- a/testproject/Assets/Scripts/testproject.asmdef +++ b/testproject/Assets/Scripts/testproject.asmdef @@ -2,6 +2,7 @@ "name": "TestProject", "references": [ "Unity.Multiplayer.MLAPI.Runtime", - "Unity.Multiplayer.MLAPI.Editor" + "Unity.Multiplayer.MLAPI.Editor", + "Unity.Multiplayer.MLAPI.Prototyping" ] } \ No newline at end of file