How to deal with lag

How to deal with lag in multiplayer games (using unity + photon). Suppose a turn-based archery game between 2 players.

Player 1 shoots using device 1 and this is to be reflected in player 2 using device 2. How to handle synchronization with minimal latency.

Do unity photon provides some solution?

We tried this but the arrow in the non-shooting device is laggy.

What I'm trying the arrow to be Instantiate over the network using PhotonNetwork.Instantiate and then determining the velocity adding force to the arrow, below is the function


public void InitiateShootArrow(Vector2 inputDirectionParam, float shootPowerParam)

    {

        GameObject initiatedShootArrow = PhotonNetwork.Instantiate(arrow.name, GameController.instance.currentTargetSpawn.players[0].GetComponent<PlayerController>().playerShootPosition.transform.position, Quaternion.Euler(0, 180, shootDirection * -1));


        Vector3 shootDirectionVector = Vector3.Normalize(inputDirectionParam);


        if (GameController.instance.currentTargetSpawn.players[0] == GameController.instance.player1Spawn.players[0])

            shootDirectionVector = new Vector3(Mathf.Clamp(shootDirectionVector.x, 0, 1), Mathf.Clamp(shootDirectionVector.y, 0, 1), shootDirectionVector.z);

        else if (GameController.instance.currentTargetSpawn.players[0] == GameController.instance.player2Spawn.players[0])

            shootDirectionVector = new Vector3(Mathf.Clamp(shootDirectionVector.x, 0, 1), Mathf.Clamp(shootDirectionVector.y, -1, 0), shootDirectionVector.z);

        initiatedShootArrow.GetComponent<MainLauncherController>().playerShootVector = GameController.instance.currentTargetSpawn.players[0].GetComponent<PlayerController>().reverse * (shootDirectionVector * ((shootPowerParam + baseShootPower) / 50));


        CameraController.instance.photonView.RPC("setTargetToFollow", RpcTarget.All, initiatedShootArrow.GetPhotonView().ViewID);

    }


    [PunRPC]

    private void setTargetToFollow(int viewId)

    {

        PhotonView photonView = PhotonView.Find(viewId);

        targetToFollow = photonView.gameObject;

    }


void Update()

    {

        if (targetToFollow)

        {        StartCoroutine(smoothFollow(CameraController.instance.targetToFollow.transform.position));

        }

    }


 [Range(0, 0.5f)]

    public float followSpeedDelay = 0.01f;

    private float xVelocity = 0.0f;

    private float yVelocity = 0.0f;

    [PunRPC]

    IEnumerator smoothFollow(Vector3 p)

    {

        float posX = Mathf.SmoothDamp(

            CameraController.instance.transform.position.x,

            p.x,

            ref CameraController.instance.xVelocity,

            CameraController.instance.followSpeedDelay

        );

        float posY = Mathf.SmoothDamp(

            CameraController.instance.transform.position.y,

            p.y - 2,

            ref CameraController.instance.yVelocity,

            CameraController.instance.followSpeedDelay

        );

        CameraController.instance.transform.position = new Vector3(posX, posY, CameraController.instance.transform.position.z);

        CameraController.instance.cameraCurrentPos = transform.position;


        yield return 0;

    }