Networking and NavMesh

Good day!

Need help pliss, I am doing a game with navmesh navigation, i want send navMeshAgent.destination to server and in the server to all player, for “prefect syncro”, but not work good, the players move only in server.

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class ClassPlayerMovement : NetworkBehaviour
{
    public GameObject prefabBullet;
    public Transform bulletTransform;
    [SyncVar]
    NavMeshAgent navMeshAgent;

    void Awake()
    {
        navMeshAgent = GetComponent<NavMeshAgent>();
    }
   
    // Use this for initialization
    void Start ()
    {
   
    }
   
    // Update is called once per frame
    void Update ()
    {
        if(isLocalPlayer)
        {
            if(Input.GetMouseButton(1))
            {
                RaycastHit tempHit;
                Ray tempRay = Camera.main.ScreenPointToRay(Input.mousePosition);

                if(Physics.Raycast(tempRay, out tempHit, 100, LayerMask.GetMask("layerPlatform")))
                {
                    CmdScrClickAndMove(tempHit.point);
                }
            }

            if(Input.GetKeyDown(KeyCode.Q))
            {
                RaycastHit tempHit;

                Ray tempRay = Camera.main.ScreenPointToRay(Input.mousePosition);
                Physics.Raycast(tempRay, out tempHit, 100, LayerMask.GetMask("layerPlatform"));

                CmdScrPowerQActive(new Vector3(tempHit.point.x, bulletTransform.position.y, tempHit.point.z));
            }
        }
    }

    [Command]
    void CmdScrClickAndMove(Vector3 destination)
    {
        navMeshAgent.SetDestination(destination);
    }

    [Command]
    void CmdScrPowerQActive(Vector3 direction)
    {
        var tempBullet = (GameObject) Instantiate(prefabBullet, bulletTransform.position, Quaternion.identity);

        tempBullet.transform.LookAt(direction);
        tempBullet.GetComponent<Rigidbody>().velocity = tempBullet.transform.forward*8;
        Destroy(tempBullet, 0.45f);

        NetworkServer.Spawn(tempBullet);
    }
}

The players are network identity, an local player autority.

How solve this problem?

Thanks uniters!

It’s only working on the server because you’re not propagating it back out to clients.

Step A - Player chooses were to move and sends that destination to the server via a Command.
Step B - Server verifies that’s a valid place to move, and sends the destination out to all clients including the one that sent it via a ClientRpc.
Step C - The server and clients move the player to where it’s supposed to be.

1 Like

thanks!

I make the script, and after comment if it’s work.

Thanks for your algorimt! this solution to works:

if(Input.GetMouseButton(1))
{
        RaycastHit tempHit;
        Ray tempRay = Camera.main.ScreenPointToRay(Input.mousePosition);

        if(Physics.Raycast(tempRay, out tempHit, 100, LayerMask.GetMask("layerPlatform")))
        {//Step A
                CmdScrPlayerSetDestination(tempHit.point);
        }
}

[Command]
public void CmdScrPlayerSetDestination(Vector3 argPosition)
{//Step B, I do simple work, I not verifi a valid position in server, I only send to all clients
        RpcScrPlayerSetDestination(argPosition);     
}

[ClientRpc]
public void RpcScrPlayerSetDestination(Vector3 argPosition)
{//Step C, only the clients move
        navMeshAgent.SetDestination(argPosition); 
}
1 Like

Nice. Just make sure you execute the navMeshAgent.SetDestination() in the command as well so that the players move on the server as well.

Couldn’t you just make argPosition a [syncvar] and forego the RPC? - reassigning the destination/argposition on update?

What are the disadvantages to this approach?