private void UpdateOtherAstronauts()
    {
        // Get the other astronauts
        var otherAstronauts = _world.OtherAstronauts;

        // Update the astronauts
        foreach (var gameAstronaut in otherAstronauts)
        {
            // Get the local astronaut
            if (!_localAstronauts.TryGetValue(gameAstronaut.Guid, out var localAstronaut))
            {
                // Create remotely controlled astronaut
                localAstronaut = Instantiate(AstronautPrefab);

                // Add to dictionary
                _localAstronauts[gameAstronaut.Guid] = localAstronaut;
            }

            // Update astronaut
            localAstronaut.transform.position = Astronaut.To3DPosition(gameAstronaut.Position).ToVector3();
            localAstronaut.transform.LookAt(Vector3.zero);

            var controller = localAstronaut.GetComponent <AstronautController>();
            controller.Piloting = gameAstronaut.Mode == AstronautMode.Pilot ||
                                  gameAstronaut.Mode == AstronautMode.PilotShielding;
            controller.Healing = gameAstronaut.Mode == AstronautMode.AstronautHealing;
            controller.Name    = _world.Players.Players.FirstOrDefault(p => p.Guid == gameAstronaut.Guid)?.Name ?? string.Empty;
        }

        // Remove deleted astronauts
        foreach (var oldAstronaut in _localAstronauts.Where(la => otherAstronauts.All(ga => ga.Guid != la.Key)).ToList())
        {
            Destroy(oldAstronaut.Value);
            _localAstronauts.Remove(oldAstronaut.Key);
        }
    }
    private void UpdatePlayer()
    {
        // Get the current player type
        var playerType = _world.LocalPlayer.Type;

        // Delete alien player controller if no-longer needed
        if (_alienPlayerController != null && (playerType != PlayerType.Alien && playerType != PlayerType.Observer))
        {
            Camera.main.transform.SetParent(WorldRoot);
            Destroy(_alienPlayerController);
            _alienPlayerController = null;
        }

        // Delete astronaut player controller if no-longer needed
        if (_astronautPlayerControl != null && playerType != PlayerType.Astronaut)
        {
            Camera.main.transform.SetParent(WorldRoot);
            Destroy(_astronautPlayerControl);
            _astronautPlayerControl = null;
        }

        // Create alien player if needed
        if (_alienPlayerController == null && (playerType == PlayerType.Alien || playerType == PlayerType.Observer))
        {
            _alienPlayerController = Instantiate(PlayerAlienPrefab);
            _alienPlayerController.transform.SetParent(WorldRoot);


            Camera.main.transform.SetParent(_alienPlayerController.transform);
            Camera.main.transform.position = new Vector3(0, 0, distanceFromAlienPlayer);
            Camera.main.transform.LookAt(Vector3.zero);
        }

        // Create astronaut player controller if needed
        if (_astronautPlayerControl == null && playerType == PlayerType.Astronaut)
        {
            _astronautPlayerControl = Instantiate(PlayerAstronautPrefab);
            _astronautPlayerControl.transform.SetParent(WorldRoot);

            Camera.main.transform.SetParent(_astronautPlayerControl.transform);
            Camera.main.transform.position = new Vector3(0, 0, distanceFromAstronautPlayer);
            Camera.main.transform.LookAt(Vector3.zero);
        }

        // Handle alien actions
        if (_alienPlayerController != null && playerType == PlayerType.Alien)
        {
            _asteroidFireWait -= Time.deltaTime;

            if ((InputManagerData.PrimaryButtonClicked || InputManagerData.SecondaryButtonClicked) && _asteroidFireWait <= 0f)
            {
                _world.FireAsteroid(
                    _alienPlayerController.transform.position.ToVec3(),
                    _alienPlayerController.transform.TransformVector(Vector3.forward * 10).ToVec3()
                    );
                var controller = _alienPlayerController.GetComponent <AlienPlayerController>();
                controller.fireSfx.Play();
                _asteroidFireWait = AsteroidFireWaitTotal;
            }
        }

        // Handle astronaut actions
        if (_astronautPlayerControl != null)
        {
            // Read 2D position from controller
            var controller = _astronautPlayerControl.GetComponent <AstronautPlayerController>();
            _world.LocalAstronaut.Position = controller.Position;

            // Update 3D position from 2D position
            _astronautPlayerControl.transform.position = Astronaut.To3DPosition(_world.LocalAstronaut.Position).ToVector3();
            _astronautPlayerControl.transform.LookAt(Vector3.zero);

            int wingNear = ship.getNearWing();

            switch (_world.LocalAstronaut.Mode)
            {
            case AstronautMode.Astronaut:
                // Check controls
                if (InputManagerData.PrimaryButtonDown && ship.isNearControlModule())
                {
                    _world.LocalAstronaut.Mode = AstronautMode.Pilot;
                }
                else if (InputManagerData.PrimaryButtonDown && wingNear > 0)
                {
                    _world.LocalAstronaut.Mode = AstronautMode.AstronautHealing;
                }
                break;

            case AstronautMode.Pilot:
                // Check controls
                if (InputManagerData.SecondaryButtonDown || Input.GetButtonDown("Cancel") || Input.touchCount > 1)
                {
                    _world.LocalAstronaut.Mode = AstronautMode.Astronaut;
                }
                else if (InputManagerData.PrimaryButtonDown && _sheildDelay < 0f)
                {
                    _world.LocalAstronaut.Mode = AstronautMode.PilotShielding;
                }
                break;

            case AstronautMode.AstronautHealing:
                // Check controls
                if (InputManagerData.PrimaryButtonDown)
                {
                    _world.LocalAstronaut.Mode = AstronautMode.Astronaut;
                }
                break;

            case AstronautMode.PilotShielding:
                // Check controls
                if (!InputManagerData.PrimaryButtonDown || _sheildSeconds < 0)
                {
                    _world.LocalAstronaut.Mode = AstronautMode.Pilot;
                    _sheildDelay = SheildDelayTotal;
                }
                break;
            }

            controller.Piloting = _world.LocalAstronaut.Mode == AstronautMode.Pilot ||
                                  _world.LocalAstronaut.Mode == AstronautMode.PilotShielding;
            controller.Healing = _world.LocalAstronaut.Mode == AstronautMode.AstronautHealing;
            controller.Name    = _world.LocalPlayer.Name;
            // TODO camera
        }
    }