protected void OnPlayerNameReceive(TinyNetMessageReader netMsg) { netMsg.ReadMessage(stringMsg); //This only works because this game uses only one controller per connection! ((ExamplePlayerController)netMsg.tinyNetConn.GetFirstPlayerController()).userName = stringMsg.value; }
/// <summary> /// Called when the initial spawning of objects have been started and when it finishes. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectSpawnFinishedMessage"/>.</param> void OnObjectSpawnFinished(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TineNetObjectSpawnFinishedMessage); if (TinyNetLogLevel.logDebug) { TinyLogger.Log("SpawnFinished: " + s_TineNetObjectSpawnFinishedMessage.state); } // when 0, means we already started receiving the spawn messages but we have yet to receive them all. if (s_TineNetObjectSpawnFinishedMessage.state == 0) { PrepareToSpawnSceneObjects(); _isSpawnFinished = false; return; } // when 1, means we have received every single spawn message! foreach (TinyNetIdentity tinyNetId in LocalIdentityObjects.Values) { if (tinyNetId.isClient) { tinyNetId.OnStartClient(); } } _isSpawnFinished = true; }
/// <summary> /// Called when a <see cref="TinyNetRemovePlayerMessage"/> is received. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetRemovePlayerMessage"/>.</param> protected virtual void OnRemovePlayerMessage(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetRemovePlayerMessage); //netMsg.tinyNetConn.RemovePlayerController(s_TinyNetRemovePlayerMessage.playerControllerId); RemovePlayerControllerFromConnection(netMsg.tinyNetConn, s_TinyNetRemovePlayerMessage.playerControllerId); }
/// <summary> /// Redirects an <see cref="TinyNetInputMessage"/> to the correct player controller. /// </summary> /// <param name="netMsg">The <see cref="TinyNetInputMessage"/>.</param> public void GetPlayerInputMessage(TinyNetMessageReader netMsg) { TinyNetPlayerController netPlayerController = GetPlayerController(TinyNetInputMessage.PeekAtPlayerControllerId(netMsg)); if (netPlayerController != null) { netPlayerController.GetInputMessage(netMsg); } }
/* * public virtual void SendStateUpdateToAllConnections(TinyNetBehaviour netBehaviour, DeliveryMethod sendOptions) { * recycleWriter.Reset(); * * recycleWriter.Put(TinyNetMsgType.StateUpdate); * recycleWriter.Put(netBehaviour.NetworkID); * * netBehaviour.TinySerialize(recycleWriter, false); * * for (int i = 0; i < tinyNetConns.Count; i++) { * tinyNetConns[i].Send(recycleWriter, sendOptions); * } * }*/ //============ TinyNetMessages Handlers =============// // default ready handler. /// <summary> /// Called when we receive a client ready message. /// </summary> /// <param name="netMsg">The net MSG.</param> void OnClientReadyMessage(TinyNetMessageReader netMsg) { if (TinyNetLogLevel.logDev) { TinyLogger.Log("Default handler for ready message from " + netMsg.tinyNetConn); } SetClientReady(netMsg.tinyNetConn); }
/// <summary> /// Called when a scene object is spawned and we are a Listen Server. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectSpawnSceneMessage"/>.</param> void OnLocalClientObjectSpawnScene(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetObjectSpawnSceneMessage); TinyNetIdentity localObject = GetTinyNetIdentityByNetworkID(s_TinyNetObjectSpawnSceneMessage.networkID); if (localObject != null) { localObject.OnGiveLocalVisibility(); } }
/// <summary> /// Called when a scene object is spawned and we are a Listen Server. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectSpawnSceneMessage"/>.</param> void OnLocalClientObjectSpawnScene(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetObjectSpawnSceneMessage); TinyNetIdentity localObject = _localIdentityObjects[s_TinyNetObjectSpawnSceneMessage.networkID]; if (localObject != null) { localObject.OnSetLocalVisibility(true); } }
protected void OnPawnRequestMessage(TinyNetMessageReader netMsg) { netMsg.ReadMessage(shortMessage); ExamplePawn newPawn = Instantiate(GameManager.instance.pawnPrefab, SpawnPointManager.GetSpawnPoint(), Quaternion.identity); newPawn.ownerPlayerControllerId = shortMessage.value; newPawn.PlayerName = ((ExamplePlayerController)netMsg.tinyNetConn.GetFirstPlayerController()).userName; serverManager.SpawnWithClientAuthority(newPawn.gameObject, netMsg.tinyNetConn); }
public override void GetInputMessage(TinyNetMessageReader netMsg) { TinyBirdUtils.TinyLogger.Log("ExamplePlayerController::GetInputMessage called"); netMsg.ReadMessage(inputMessageReader); if (pawn != null) { pawn.ServerSyncPosFromOwner(inputMessageReader.xPos, inputMessageReader.zPos, inputMessageReader.dir); return; } TinyBirdUtils.TinyLogger.Log("ExamplePlayerController::GetInputMessage no pawn?"); }
//============ TinyNetEvents ========================// /// <summary> /// Called when a connection message is received. /// </summary> /// <param name="netMsg">The net message.</param> protected virtual void OnConnectMessage(TinyNetMessageReader netMsg) { if (TinyNetGameManager.instance.isClient && TinyNetClient.instance.connToHost.ConnectId == netMsg.tinyNetConn.ConnectId) { return; } if (TinyNetGameManager.networkSceneName != null && TinyNetGameManager.networkSceneName != "") { TinyNetStringMessage msg = new TinyNetStringMessage(TinyNetGameManager.networkSceneName); msg.msgType = TinyNetMsgType.Scene; netMsg.tinyNetConn.Send(msg, DeliveryMethod.ReliableOrdered); } }
//============ TinyNetMessages Handlers =============// /// <summary> /// Called when an RPC message is received. /// TODO FIX THIS! /// </summary> /// <param name="netMsg">The net message.</param> protected virtual void OnRPCMessage(TinyNetMessageReader netMsg) { /*netMsg.ReadMessage(s_TinyNetRPCMessage); * * ITinyNetComponent iObj = GetTinyNetObjectByNetworkID(s_TinyNetRPCMessage.networkID); * * if (iObj == null) { * if (TinyNetLogLevel.logError) { TinyLogger.LogError("TinyNetScene::OnRPCMessage No ITinyNetObject with the HNetworkID: " + s_TinyNetRPCMessage.networkID); } * return; * } * * recycleMessageReader.reader.SetSource(s_TinyNetRPCMessage.parameters); * iObj.InvokeRPC(s_TinyNetRPCMessage.rpcMethodIndex, recycleMessageReader.reader);*/ }
//============ Scenes Methods =======================// /// <summary> /// Handler for a scene change message. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetStringMessage"/> containing the scene name.</param> protected virtual void OnClientChangeSceneMessage(TinyNetMessageReader netMsg) { if (TinyNetLogLevel.logDebug) { TinyLogger.Log("TinyNetClient:OnClientChangeSceneMessage"); } string newSceneName = netMsg.reader.GetString(); if (isConnected && !TinyNetGameManager.instance.isServer) { TinyNetGameManager.instance.ClientChangeScene(newSceneName, true); } }
/// <summary> /// Called when we receive an Authorithy message from the server. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetClientAuthorityMessage"/>.</param> void OnClientAuthorityMessage(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetClientAuthorityMessage); if (TinyNetLogLevel.logDebug) { TinyLogger.Log("TinyNetClient::OnClientAuthority for connectionId=" + netMsg.tinyNetConn.ConnectId + " netId: " + s_TinyNetClientAuthorityMessage.networkID); } TinyNetIdentity tni = GetTinyNetIdentityByNetworkID(s_TinyNetClientAuthorityMessage.networkID); if (tni != null) { tni.HandleClientAuthority(s_TinyNetClientAuthorityMessage.authority); } }
/// <summary> /// Called when an object is hidden and we are a Listen Server. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectHideMessage"/>.</param> void OnLocalClientObjectHide(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetObjectHideMessage); if (TinyNetLogLevel.logDebug) { TinyLogger.Log("TinyNetClient::OnLocalObjectObjHide netId:" + s_TinyNetObjectHideMessage.networkID); } TinyNetIdentity localObject = GetTinyNetIdentityByNetworkID(s_TinyNetObjectHideMessage.networkID); if (localObject != null) { localObject.OnRemoveLocalVisibility(); } }
//============ TinyNetMessages Handlers =============// /// <summary> /// Called when an object is destroyed and we are a Listen Server. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectDestroyMessage"/>.</param> void OnLocalClientObjectDestroy(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetObjectDestroyMessage); if (TinyNetLogLevel.logDebug) { TinyLogger.Log("TinyNetClient::OnLocalObjectObjDestroy netId:" + s_TinyNetObjectDestroyMessage.networkID); } // Removing from the tinynetidentitylist is already done at OnNetworkDestroy() at the TinyNetIdentity. /*TinyNetIdentity localObject = _localIdentityObjects[s_TinyNetObjectSpawnMessage.networkID]; * if (localObject != null) { * RemoveTinyNetIdentityFromList(localObject); * } else { * if (TinyNetLogLevel.logError) { TinyLogger.LogError("You tried to call OnLocalClientObjectDestroy on a non localIdentityObjects, how?"); } * }*/ }
/// <summary> /// Calls TinyDeserialize in all Components that we received updates for. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetMsgType.StateUpdate"/> message.</param> void OnStateUpdateMessage(TinyNetMessageReader netMsg) { LastServerTick = netMsg.reader.GetUShort(); if (TinyNetLogLevel.logDev) { TinyLogger.Log("TinyNetClient::OnStateUpdateMessage frame: " + LastServerTick + " channel: " + netMsg.channelId); } while (netMsg.reader.AvailableBytes > 0) { int networkID = netMsg.reader.GetInt(); int rSize = netMsg.reader.GetInt(); _stateUpdateReader.Clear(); //Debug.Log("OnStateUpdate: RawDataSize: " + netMsg.reader.RawDataSize + ", Position: " + netMsg.reader.Position + ", rSize: " + rSize); _stateUpdateReader.SetSource(netMsg.reader.RawData, netMsg.reader.Position, rSize + netMsg.reader.Position); _stateUpdateReader.SetFrameTick(LastServerTick); //Debug.Log("OnStateUpdate: _stateUpdateReader " + _stateUpdateReader.RawDataSize + ", Position: " + _stateUpdateReader.Position); TinyNetIdentity localObject = GetTinyNetIdentityByNetworkID(networkID); if (localObject != null) { localObject.TinyDeserialize(_stateUpdateReader, false); } else { if (TinyNetLogLevel.logWarn) { TinyLogger.LogWarning("Did not find target for sync message for " + networkID); } } // We jump the reader position to the amount of data we read. //netMsg.reader.SetSource(netMsg.reader.RawData, netMsg.reader.Position + rSize, netMsg.reader.RawDataSize); netMsg.reader.SkipBytes(rSize); } foreach (TinyNetIdentity tinyNetId in LocalIdentityObjects.Values) { tinyNetId.OnStateUpdate(); } }
/// <summary> /// Called when an object is spawned and we are a Listen Server. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectSpawnMessage"/>.</param> void OnLocalClientObjectSpawn(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetObjectSpawnMessage); TinyNetIdentity localObject = GetTinyNetIdentityByNetworkID(s_TinyNetObjectSpawnMessage.networkID); if (localObject != null) { localObject.OnStartClient(); localObject.OnGiveLocalVisibility(); } else { if (TinyNetLogLevel.logDebug) { TinyLogger.Log("TinyNetClient::OnLocalClientObjectSpawn called but object has never been spawned to client netId:" + s_TinyNetObjectSpawnMessage.networkID); } } }
/// <summary> /// Called when a <see cref="TinyNetRequestRemovePlayerMessage"/> is received. /// </summary> /// <param name="netMsg">The net message.</param> void OnRequestRemovePlayerMessage(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetRequestRemovePlayerMessage); if (s_TinyNetRequestRemovePlayerMessage.playerControllerId <= 0) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("OnRequestRemovePlayerMessage() called with playerControllerId <= 0"); } return; } RemovePlayerControllerFromConnection(netMsg.tinyNetConn, s_TinyNetRequestRemovePlayerMessage.playerControllerId); // Tell the origin client to remove them too! s_TinyNetRemovePlayerMessage.playerControllerId = s_TinyNetRequestRemovePlayerMessage.playerControllerId; SendMessageByChannelToTargetConnection(s_TinyNetRemovePlayerMessage, DeliveryMethod.ReliableOrdered, netMsg.tinyNetConn); }
public override void GetInputMessage(TinyNetMessageReader netMsg) { //if (TinyNetLogLevel.logDev) { TinyBirdUtils.TinyLogger.Log("ExamplePlayerController::GetInputMessage called"); } netMsg.ReadMessage(inputMessageReader); Vector2 axis = new Vector2(); if ((inputMessageReader.keys & MovementKeys.Up) != 0) { axis.y = 1f; } if ((inputMessageReader.keys & MovementKeys.Down) != 0) { axis.y = -1f; } if ((inputMessageReader.keys & MovementKeys.Left) != 0) { axis.x = -1f; } if ((inputMessageReader.keys & MovementKeys.Right) != 0) { axis.x = 1f; } bool bFire = (inputMessageReader.keys & MovementKeys.Fire) != 0; InsertInput(axis, bFire); if (bFire && pawn == null) { AskForPawn(); } /*if (pawn != null) { * * //pawn.ServerSyncPosFromOwner(inputMessageReader.xPos, inputMessageReader.zPos, inputMessageReader.dir); * return; * }*/ //if (TinyNetLogLevel.logDev) { TinyBirdUtils.TinyLogger.Log("ExamplePlayerController::GetInputMessage no pawn?"); } }
/// <summary> /// Called when an object is destroyed. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectDestroyMessage"/>.</param> void OnObjectDestroy(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetObjectDestroyMessage); if (TinyNetLogLevel.logDebug) { TinyLogger.Log("TinyNetClient::OnObjDestroy networkID:" + s_TinyNetObjectDestroyMessage.networkID); } TinyNetIdentity localObject = GetTinyNetIdentityByNetworkID(s_TinyNetObjectDestroyMessage.networkID); if (localObject != null) { RemoveTinyNetIdentityFromList(localObject); localObject.OnNetworkDestroy(); if (!TinyNetGameManager.instance.InvokeUnSpawnHandler(localObject.assetGUID, localObject.gameObject)) { // default handling if (localObject.sceneID == 0) { Object.Destroy(localObject.gameObject); } else { // scene object.. disable it in scene instead of destroying localObject.gameObject.SetActive(false); _sceneIdentityObjectsToSpawn[localObject.sceneID] = localObject; } } } else { if (TinyNetLogLevel.logDebug) { TinyLogger.LogWarning("Did not find target for destroy message for " + s_TinyNetObjectDestroyMessage.networkID); } } }
/// <summary> /// Called when a <see cref="TinyNetRequestAddPlayerMessage"/> is received. /// </summary> /// <param name="netMsg">The net message.</param> void OnRequestAddPlayerMessage(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetRequestAddPlayerMessage); if (s_TinyNetRequestAddPlayerMessage.amountOfPlayers <= 0) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("OnRequestAddPlayerMessage() called with amountOfPlayers <= 0"); } return; } // Check here if you should create another player controller for that connection. int playerId = TinyNetGameManager.instance.NextPlayerID; //netMsg.tinyNetConn.playerControllers.Count; AddPlayerControllerToConnection(netMsg.tinyNetConn, playerId); // Tell the origin client to add them too! s_TinyNetAddPlayerMessage.playerControllerId = (short)playerId; SendMessageByChannelToTargetConnection(s_TinyNetAddPlayerMessage, DeliveryMethod.ReliableOrdered, netMsg.tinyNetConn); }
/// <summary> /// By default it will deserialize the <see cref="TinyNetSyncVar"/> properties. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectStateUpdate"/> message.</param> void OnStateUpdateMessage(TinyNetMessageReader netMsg) { int networkID = netMsg.reader.GetInt(); if (TinyNetLogLevel.logDev) { TinyLogger.Log("TinyNetClient::OnUpdateVarsMessage " + networkID + " channel:" + netMsg.channelId); } ITinyNetObject localObject = _localNetObjects[networkID]; if (localObject != null) { localObject.TinyDeserialize(netMsg.reader, false); } else { if (TinyNetLogLevel.logWarn) { TinyLogger.LogWarning("Did not find target for sync message for " + networkID); } } }
/// <summary> /// Called when a scene object is spawned. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectSpawnSceneMessage"/>.</param> void OnObjectSpawnScene(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetObjectSpawnSceneMessage); if (TinyNetLogLevel.logDebug) { TinyLogger.Log("Client spawn scene handler instantiating [networkID: " + s_TinyNetObjectSpawnSceneMessage.networkID + " sceneId: " + s_TinyNetObjectSpawnSceneMessage.sceneId + " pos: " + s_TinyNetObjectSpawnSceneMessage.position); } TinyNetIdentity localTinyNetIdentity = GetTinyNetIdentityByNetworkID(s_TinyNetObjectSpawnSceneMessage.networkID); if (localTinyNetIdentity != null) { // this object already exists (was in the scene) ApplyInitialState(localTinyNetIdentity, s_TinyNetObjectSpawnSceneMessage.position, s_TinyNetObjectSpawnSceneMessage.initialState, s_TinyNetObjectSpawnSceneMessage.networkID, localTinyNetIdentity.gameObject, s_TinyNetObjectSpawnSceneMessage.frameTick); return; } TinyNetIdentity spawnedId = SpawnSceneObject(s_TinyNetObjectSpawnSceneMessage.sceneId); if (spawnedId == null) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("Spawn scene object not found for " + s_TinyNetObjectSpawnSceneMessage.sceneId); } return; } if (TinyNetLogLevel.logDebug) { TinyLogger.Log("Client spawn for [networkID :" + s_TinyNetObjectSpawnSceneMessage.networkID + "] [sceneId: " + s_TinyNetObjectSpawnSceneMessage.sceneId + "] obj: " + spawnedId.gameObject.name); } ApplyInitialState(spawnedId, s_TinyNetObjectSpawnSceneMessage.position, s_TinyNetObjectSpawnSceneMessage.initialState, s_TinyNetObjectSpawnSceneMessage.networkID, spawnedId.gameObject, s_TinyNetObjectSpawnSceneMessage.frameTick); }
/// <summary> /// Called when an AddPlayerMessage is received. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetAddPlayerMessage"/>.</param> protected virtual void OnAddPlayerMessage(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetAddPlayerMessage); AddPlayerControllerToConnection(netMsg.tinyNetConn, s_TinyNetAddPlayerMessage.playerControllerId); }
/// <summary> /// Called when an AddPlayerMessage is received and we are a Listen Server. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetAddPlayerMessage"/>.</param> protected virtual void OnLocalAddPlayerMessage(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetAddPlayerMessage); CreatePlayerAndAdd(netMsg.tinyNetConn, s_TinyNetAddPlayerMessage.playerControllerId); }
/// <summary> /// Redirects an <see cref="TinyNetInputMessage"/> to the correct player controller. /// </summary> /// <param name="netMsg">The <see cref="TinyNetInputMessage"/>.</param> public void GetPlayerInputMessage(TinyNetMessageReader netMsg) { GetPlayerController(TinyNetInputMessage.PeekAtPlayerControllerId(netMsg)).GetInputMessage(netMsg); }
/// <summary> /// Receives an input message /// </summary> /// <param name="netMsg">The message reader.</param> public virtual void GetInputMessage(TinyNetMessageReader netMsg) { }
//============ Players Methods ======================// /// <summary> /// Called when a <see cref="TinyNetInputMessage"/> is received. /// </summary> /// <param name="netMsg">The net message.</param> void OnPlayerInputMessage(TinyNetMessageReader netMsg) { netMsg.tinyNetConn.GetPlayerInputMessage(netMsg); }
/// <summary> /// Called when an object is spawned. /// </summary> /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectSpawnMessage"/>.</param> void OnObjectSpawn(TinyNetMessageReader netMsg) { netMsg.ReadMessage(s_TinyNetObjectSpawnMessage); if (s_TinyNetObjectSpawnMessage.assetIndex < 0 || s_TinyNetObjectSpawnMessage.assetIndex > int.MaxValue || s_TinyNetObjectSpawnMessage.assetIndex > TinyNetGameManager.instance.GetAmountOfRegisteredAssets()) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("OnObjSpawn networkID: " + s_TinyNetObjectSpawnMessage.networkID + " has invalid asset Id"); } return; } if (TinyNetLogLevel.logDev) { TinyLogger.Log("Client spawn handler instantiating [networkID:" + s_TinyNetObjectSpawnMessage.networkID + " asset ID:" + s_TinyNetObjectSpawnMessage.assetIndex + " pos:" + s_TinyNetObjectSpawnMessage.position + "]"); } TinyNetIdentity localTinyNetIdentity = GetTinyNetIdentityByNetworkID(s_TinyNetObjectSpawnMessage.networkID); // Check if this object was already registered in the scene: if (localTinyNetIdentity != null) { // this object already exists (was in the scene), just apply the update to existing object. ApplyInitialState(localTinyNetIdentity, s_TinyNetObjectSpawnMessage.position, s_TinyNetObjectSpawnMessage.initialState, s_TinyNetObjectSpawnMessage.networkID, null, s_TinyNetObjectSpawnMessage.frameTick); return; } GameObject prefab; SpawnDelegate handler; prefab = TinyNetGameManager.instance.GetPrefabFromAssetId(s_TinyNetObjectSpawnMessage.assetIndex); // Check if the prefab is registered in the list of spawnable prefabs. if (prefab != null) { var obj = (GameObject)Object.Instantiate(prefab, s_TinyNetObjectSpawnMessage.position, Quaternion.identity); localTinyNetIdentity = obj.GetComponent <TinyNetIdentity>(); if (localTinyNetIdentity == null) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("Client object spawned for " + s_TinyNetObjectSpawnMessage.assetIndex + " does not have a TinyNetidentity"); } return; } ApplyInitialState(localTinyNetIdentity, s_TinyNetObjectSpawnMessage.position, s_TinyNetObjectSpawnMessage.initialState, s_TinyNetObjectSpawnMessage.networkID, obj, s_TinyNetObjectSpawnMessage.frameTick); // If not, check if the prefab have a spawn handler registered. } else if (TinyNetGameManager.instance.GetSpawnHandler(s_TinyNetObjectSpawnMessage.assetIndex, out handler)) { GameObject obj = handler(s_TinyNetObjectSpawnMessage.position, s_TinyNetObjectSpawnMessage.assetIndex); if (obj == null) { if (TinyNetLogLevel.logWarn) { TinyLogger.LogWarning("Client spawn handler for " + s_TinyNetObjectSpawnMessage.assetIndex + " returned null"); } return; } localTinyNetIdentity = obj.GetComponent <TinyNetIdentity>(); if (localTinyNetIdentity == null) { if (TinyNetLogLevel.logError) { TinyLogger.LogError("Client object spawned for " + s_TinyNetObjectSpawnMessage.assetIndex + " does not have a network identity"); } return; } localTinyNetIdentity.SetDynamicAssetGUID(TinyNetGameManager.instance.GetAssetGUIDFromAssetId(s_TinyNetObjectSpawnMessage.assetIndex)); ApplyInitialState(localTinyNetIdentity, s_TinyNetObjectSpawnMessage.position, s_TinyNetObjectSpawnMessage.initialState, s_TinyNetObjectSpawnMessage.networkID, obj, s_TinyNetObjectSpawnMessage.frameTick); // If also not, we literally cannot spawn this object and you should feel bad. } else { if (TinyNetLogLevel.logError) { TinyLogger.LogError("Failed to spawn server object, assetId=" + s_TinyNetObjectSpawnMessage.assetIndex + " networkID=" + s_TinyNetObjectSpawnMessage.networkID); } } }