private void StartServer() { _isServer = true; LocalTank = AddTank(_publicKey); LocalTank.Follow(); _client.OnMessage += (src, data) => UnityMainThreadDispatcher.Instance().Enqueue(() => { switch (GetMessageType(data)) { case MessageType.JoinEvent: AddTank(src); SendStates(true); break; case MessageType.MovementState: var tank = _tanks[src]; var state = MovementState.FromByteArray(data); var cameraDirection = new Vector3(state.moveX, state.moveY, 0); if (cameraDirection.sqrMagnitude > 0.01f) { var worldUp = Camera.main.transform.TransformDirection(Vector3.up); worldUp.y = 0; worldUp.Normalize(); var worldRight = Camera.main.transform.TransformDirection(Vector3.right); worldRight.y = 0; worldRight.Normalize(); var worldDirection = worldUp * state.moveY + worldRight * state.moveX; var desiredDir = new Vector2(worldDirection.x, worldDirection.z); if (desiredDir.magnitude > 1) { desiredDir.Normalize(); } tank.SetDesiredMovementDirection(new Vector2(state.moveX, state.moveY)); } else { tank.SetDesiredMovementDirection(Vector2.zero); } tank.SetDesiredFirePosition(new Vector3(state.fireX, 0, state.fireY)); tank.SetFireIsHeld(state.fire); break; case MessageType.ChatMessage: var message = ChatMessage.FromByteArray(data); UIChat.ShowMessage(message.Message); break; case MessageType.InitialTankStates: throw new ArgumentOutOfRangeException(); case MessageType.TankStates: throw new ArgumentOutOfRangeException(); default: throw new ArgumentOutOfRangeException(); } }); TankInputModule.Instance.Init(LocalTank); HUDController.Instance.InitHudPlayer(LocalTank.Health); }