/// <summary>
    /// Compare previous with current world position of mouse in order to move the Camera by the appropriate amount.
    /// </summary>
    public void OngoingCameraDrag()
    {
        currentPositionInWorld = CameraCalculations.GetMouseWorldCoordinate();
        Vector3 displacement         = currentPositionInWorld - previousPositionInWorld;
        Vector3 moveCameraToPosition = Tr.position - displacement;

        Tr.position = moveCameraToPosition;
    }
    private void LocalClientUpdate()
    {
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            Debug.Log("Mouse0 down");

            if (hasTile)
            {
                Debug.LogError("Already had tile picked up but trying to mouse down. Why wasn't tile dropped?");
                return;
            }

            Tile tileUnderPointer = GetTileUnderPointer();
            if (tileUnderPointer != null)
            {
                CmdPickUpTile(tileUnderPointer.netIdentity);
                if (Application.platform == RuntimePlatform.Android)
                {
                    CmdFlipTile(tileUnderPointer.netIdentity);
                }
            }
        }

        if (Input.GetKeyUp(KeyCode.Mouse0))
        {
            if (hasTile)
            {
                RequestDropTile();
                TileDragEnd?.Invoke();
            }
        }

        if (Input.GetKey(KeyCode.Mouse0))
        {
            if (!hasTile)
            {
                return;
            }

            Vector3 mousePositionInWorld = CameraCalculations.GetMouseWorldCoordinate();
            TileDragOngoing?.Invoke(mousePositionInWorld);
        }

        if (Input.GetKeyDown(KeyCode.Mouse1))
        {
            Tile tileUnderPointer = GetTileUnderPointer();
            if (tileUnderPointer != null)
            {
                CmdFlipTile(tileUnderPointer.netIdentity);
            }
        }
    }
    private void RequestDropTile()
    {
        Vector3    dropPosition        = CameraCalculations.GetMouseWorldCoordinate();
        Vector3Int dropPositionSnapped = new Vector3Int(Mathf.RoundToInt(dropPosition.x), 0, Mathf.RoundToInt(dropPosition.z));

        // Reject placement if there is a tile already under the pointer
        if (GetTileUnderPointer() != null)
        {
            DropCurrentlySelectedTile();
            return;
        }

        CmdDropTile(base.netIdentity, currentlySelectedTile.netIdentity, dropPositionSnapped);
    }
 /// <summary>
 /// Caches the mouse position in world, since it is required in order to determine the magnitude of any ongoing drag calls.
 /// </summary>
 public void StartCameraDrag()
 {
     previousPositionInWorld = CameraCalculations.GetMouseWorldCoordinate();
 }