IEnumerator PerformFlap(FlapAnimation flap) { _currentFlap = flap; GameObject actor = flap.Actor; Vector3 targetLocation = flap.TargetLocation; Vector3 rotationPoint = Math.Between(actor.transform.position, targetLocation); Vector3 direction = (targetLocation - actor.transform.position).normalized; Vector3 rotationAxis = new Vector3(direction.z, 0f, -direction.x); float turnedDegrees = 0f; float degreesPerSecond = 360f; while (true) { float degreesUpdate = Time.deltaTime * degreesPerSecond; float degreesLeft = 180f - turnedDegrees; if (degreesLeft < degreesUpdate) { actor.transform.RotateAround(point: rotationPoint, axis: rotationAxis, degreesLeft); break; } turnedDegrees += degreesUpdate; actor.transform.RotateAround(point: rotationPoint, axis: rotationAxis, degreesUpdate); yield return(null); } actor.transform.position = targetLocation; _currentFlap = null; }
void SingleplayerUpdate() { MouseRaycast(out bool hitAnything, out Vector3 hitPosition, out GameObject hitDiskActor); UpdateDiskGhost(hitAnything, hitPosition); Disk selectedDisk = HandleSelectionInput(hitDiskActor); if (Input.GetMouseButtonDown(1)) { if (selectedDisk != null && selectedDisk.RemainingMoves > 0) { selectedDisk.RemainingMoves -= 1; selectedDisk.Position = _diskGhost.transform.position; Material ghostMaterial = _diskGhost.GetComponent <Renderer>().material; Color ghostColor = selectedDisk.RemainingMoves > 0 ? Color.blue : Color.red; ghostColor.a = ghostMaterial.color.a; ghostMaterial.color = ghostColor; GameObject actor = _actorByID[selectedDisk.ID]; FlapAnimation flapAnimation = new FlapAnimation { Actor = actor, TargetLocation = selectedDisk.Position }; _flapQueue.Enqueue(flapAnimation); } } if (_flapQueue.Any() && _currentFlap == null) { FlapAnimation flap = _flapQueue.Dequeue(); StartCoroutine(PerformFlap(flap)); } }
void ClientUpdate() { MouseRaycast(out bool hitAnything, out Vector3 hitPosition, out GameObject hitDiskActor); UpdateDiskGhost(hitAnything, hitPosition); Disk selectedDisk = HandleSelectionInput(hitDiskActor); if (Input.GetMouseButtonDown(1)) { if (selectedDisk != null && selectedDisk.RemainingMoves > 0) { Material ghostMaterial = _diskGhost.GetComponent <Renderer>().material; Color ghostColor = selectedDisk.RemainingMoves > 0 ? Color.blue : Color.red; ghostColor.a = ghostMaterial.color.a; ghostMaterial.color = ghostColor; NetworkMessage message = new NetworkMessage(); message.type = NetworkMessage.Type.DiskMove; message.diskMove.targetLocation = _diskGhost.transform.position; message.diskMove.diskID = selectedDisk.ID; SendNetworkMessage(message); } } if (_flapQueue.Any() && _currentFlap == null) { FlapAnimation flap = _flapQueue.Dequeue(); StartCoroutine(PerformFlap(flap)); } }
async void ReadClientMessagesAsync() { StreamReader reader = new StreamReader(_networkStream); while (_networkListening) { Task <string> readTask = reader.ReadLineAsync(); await readTask; string json = readTask.Result; if (string.IsNullOrWhiteSpace(json)) { continue; } Debug.Log(json); NetworkMessage message = JsonUtility.FromJson <NetworkMessage>(json); switch (message.type) { case NetworkMessage.Type.Chat: Debug.Log(message.chat.message); break; case NetworkMessage.Type.DiskMove: Disk disk = _disks[message.diskMove.diskID]; disk.Position = message.diskMove.targetLocation; disk.RemainingMoves -= 1; message.diskMove.remainingMoves = disk.RemainingMoves; GameObject actor = _actorByID[disk.ID]; FlapAnimation flapAnimation = new FlapAnimation { Actor = actor, TargetLocation = disk.Position }; _flapQueue.Enqueue(flapAnimation); SendNetworkMessage(message); break; case NetworkMessage.Type.PlayerTurnUpdateMessage: EndTurnServer(); break; default: Debug.LogError($"{message.type} is not a valid value for {typeof(NetworkMessage.Type)}."); break; } } }
async void ReadServerMessagesAsync() { StreamReader reader = new StreamReader(_networkStream); while (_networkListening) { Task <string> readTask = reader.ReadLineAsync(); await readTask; string json = readTask.Result; if (string.IsNullOrWhiteSpace(json)) { continue; } Debug.Log(json); NetworkMessage message = JsonUtility.FromJson <NetworkMessage>(json); switch (message.type) { case NetworkMessage.Type.Chat: Debug.Log(message.chat.message); break; case NetworkMessage.Type.DiskSpawn: SpawnDisk(message.diskSpawn.diskName, message.diskSpawn.player); break; case NetworkMessage.Type.DiskMove: Disk disk = _disks[message.diskMove.diskID]; disk.Position = message.diskMove.targetLocation; disk.RemainingMoves = message.diskMove.remainingMoves; GameObject actor = _actorByID[disk.ID]; FlapAnimation flapAnimation = new FlapAnimation { Actor = actor, TargetLocation = disk.Position }; _flapQueue.Enqueue(flapAnimation); break; case NetworkMessage.Type.InitializeClient: _playerID = message.initializeClient.playerID; break; case NetworkMessage.Type.PlayerTurnUpdateMessage: _currentPlayer = message.playerTurnUpdate.currentPlayer; _currentPlayerDisplay.text = _currentPlayer == _playerID ? "It's your turn!" : $"Player {_currentPlayer}'s turn"; if (_currentPlayer == _playerID) { _diskGhost.SetActive(true); } break; default: Debug.LogError($"{message.type} is not a valid value for {typeof(NetworkMessage.Type)}."); break; } } }