//syncs all of the synced transforms in transforms to the request public void HandleSyncRequest(MultiSyncRequest request) { //iterate through the transforms in the request for (int i = 0; i < request.tfs.Count; i++) { //copy the transforms from the request to the objects request.tfs[i].CopyToTransform(syncedTransforms[i]); } }
//sends a sync message public void SyncObject() { //only sync to this instance of the object if it's locally owned if (localOwned) { //create sync and base requests MultiSyncRequest syncRequest = new MultiSyncRequest(ID, syncedTransforms); MultiBaseRequest baseRequest = new MultiBaseRequest(MultiPossibleRequest.MultiSyncObject, MessagePackSerializer.Serialize(syncRequest)); //send the message away client.SendMessageToServer(MessagePackSerializer.Serialize(baseRequest)); Debug.Log("Object " + ID.ToString() + " sent sync request"); } //sync again after syncInterval seconds Invoke("SyncObject", syncInterval); }
//listen for requests void messageReceivedListener(byte[] _message) { try { //get the base request object MultiBaseRequest baseRequest = MessagePackSerializer.Deserialize <MultiBaseRequest>(_message); Debug.Log(String.Format("<<<Client>>>: Recieved \"{0}\"", MessagePackSerializer.ConvertToJson(_message))); switch ((MultiPossibleRequest)baseRequest.RT) { //initial data for setup case MultiPossibleRequest.MultiInitialData: MultiInitialData initialData = MessagePackSerializer.Deserialize <MultiInitialData>(baseRequest.R); //store the thread key as the client id, they're the same thing _ClientID = initialData.T; actions.Enqueue(() => StartCoroutine(HandleMultiInitialData(initialData))); break; //the server would like to spawn an object case MultiPossibleRequest.MultiSpawnObject: MultiSpawnRequest multiSpawnRequest = MessagePackSerializer.Deserialize <MultiSpawnRequest>(baseRequest.R); //queue spawning the object actions.Enqueue(() => SpawnObject(multiSpawnRequest.I)); break; //the server would like to sync an object case MultiPossibleRequest.MultiSyncObject: MultiSyncRequest multiSyncRequest = MessagePackSerializer.Deserialize <MultiSyncRequest>(baseRequest.R); //queue the synced object handle actions.Enqueue(() => syncedObjects[multiSyncRequest.ID].HandleSyncRequest(multiSyncRequest)); break; //the server would like to change scenes case MultiPossibleRequest.MultiChangeScene: MultiChangeSceneRequest multiChangeScene = MessagePackSerializer.Deserialize <MultiChangeSceneRequest>(baseRequest.R); //queue the scene change actions.Enqueue(() => SceneManager.LoadScene(possibleScenes[multiChangeScene.N].name)); currentScene = possibleScenes[multiChangeScene.N]; actions.Enqueue(() => { //get all of the systems in this scene GameObject[] systems = GameObject.FindGameObjectsWithTag("GameSystem"); //iterate through them, storing a reference to each of them foreach (GameObject system in systems) { gameSystems.Add(system.GetComponent <GameSystem>().SystemID, system.GetComponent <GameSystem>()); } }); //reset the dictionary of players gamePlayers = new Dictionary <int, GamePlayer>(); //spawn our prefab on the network MultiSpawnPlayer spawnPlayerScene = new MultiSpawnPlayer((int)inputMethod, _ClientID, TeamSystem.Team.A, PlayerName); //FindObjectOfType<TeamSystem>().localTeam); MultiBaseRequest spawnPlayerBaseScene = new MultiBaseRequest(MultiPossibleRequest.MultiSpawnPlayer, MessagePackSerializer.Serialize(spawnPlayerScene)); SendMessageToServer(MessagePackSerializer.Serialize(spawnPlayerBaseScene)); //spawn our prefab here actions.Enqueue(() => { //spawn in the new synced object instance GameObject instance = Instantiate(possibleScenes[multiChangeScene.N].PlayerPrefabs[(int)inputMethod]); GamePlayer player = instance.GetComponent <GamePlayer>(); //store its index and its local status player.LocalOwned = true; //store it gamePlayers[_ClientID] = player; //do setup player.PlayerSetup(_ClientID, TeamSystem.Team.A, PlayerName); //FindObjectOfType<TeamSystem>().localTeam); }); break; //the server would like to sync a scene object case MultiPossibleRequest.MultiSceneSyncObject: MultiSyncRequest multiSceneSync = MessagePackSerializer.Deserialize <MultiSyncRequest>(baseRequest.R); //queue the synced object handle actions.Enqueue(() => sceneSyncedObjects[multiSceneSync.ID].HandleSyncRequest(multiSceneSync)); break; //the server wants us to take host authority case MultiPossibleRequest.MultiHostAuthChange: hostAuthority = true; break; //there's new connection to the game, send a dict of id's and indexes case MultiPossibleRequest.MultiNewConnection: MultiNewConnection newConnection = MessagePackSerializer.Deserialize <MultiNewConnection>(baseRequest.R); //dictionary of the sceneobjects with non negative indices(root objects) Dictionary <int, int> idIndexes = new Dictionary <int, int>(); foreach (int key in syncedObjects.Keys) { idIndexes.Add(key, syncedObjects[key].index); } //Send the request MultiInitialData sceneObjects = new MultiInitialData(newConnection.tN, idIndexes, gamePlayers, possibleScenes.IndexOf(currentScene), syncedObjectsTotal, newConnection.tN); MultiBaseRequest request = new MultiBaseRequest(MultiPossibleRequest.MultiInitialData, MessagePackSerializer.Serialize(sceneObjects)); SendMessageToServer(MessagePackSerializer.Serialize(request)); break; //the server would like us to despawn an object case MultiPossibleRequest.MultiDespawnObject: MultiDespawnObject despawnObject = MessagePackSerializer.Deserialize <MultiDespawnObject>(baseRequest.R); //destroy the object Debug.Log(String.Format("MultiClient.cs:291 Destroying {0}", syncedObjects[despawnObject.ID].gameObject.name)); actions.Enqueue(() => Destroy(syncedObjects[despawnObject.ID].gameObject)); break; case MultiPossibleRequest.MultiGameData: GameSystemData systemData = MessagePackSerializer.Deserialize <GameSystemData>(baseRequest.R); //pass on this data, the game system knows what to do with it actions.Enqueue(() => gameSystems[systemData.S].HandleMessage(systemData)); break; case MultiPossibleRequest.MultiSpawnPlayer: MultiSpawnPlayer spawnPlayer = MessagePackSerializer.Deserialize <MultiSpawnPlayer>(baseRequest.R); //spawn in the player and ensure it knows which client it belongs to actions.Enqueue(() => { GameObject instance = Instantiate(currentScene.PlayerPrefabs[spawnPlayer.T]); GamePlayer gamePlayer = instance.GetComponent <GamePlayer>(); //store it gamePlayers[spawnPlayer.C] = gamePlayer; //do setup gamePlayer.PlayerSetup(spawnPlayer.C, (TeamSystem.Team)spawnPlayer.t, spawnPlayer.P); }); break; case MultiPossibleRequest.MultiSyncPlayer: MultiSyncPlayer syncPlayer = MessagePackSerializer.Deserialize <MultiSyncPlayer>(baseRequest.R); actions.Enqueue(() => gamePlayers[syncPlayer.C].HandleMessage(syncPlayer.S)); break; } } catch (Exception ex) { Debug.LogError(ex); Debug.LogError(_message); } }