Cannot sync non-player objects in Unity mirror

14 views Asked by At

i am making a multiplayer game using Mirror, the premise of this action is simple : if a player walks in front of a patrolling enemy, the enemy will start following the player, in a single player context it all works fine, however when in a multiplayer setting it all goes bad :

  • The client player walks in front of the patrolling enemy
  • The patrolling enemy goes to the host player's position (this update only happens on the host's POV, nothing changes on the client side) this is my patrolling code :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using Mirror;

public class PatrolNavigation : NetworkBehaviour
{
    private NavMeshAgent agent;
    public FieldOfView fov;

    [SerializeField] Transform[] posPoints;

    int posInt;
    Vector3 dest;

    // Boolean that activates the first time you see the player
    public bool hasSeenPlayer = false;

    [SerializeField] float targetTime;
    [SerializeField] float PosTime;
    private Vector3 startPosition;

    public GameObject PatrolPoints;
    private bool hasSpawnedPatrolPoints = false;

    // Start is called before the first frame update
    void Start()
    {
        posInt = Random.Range(0, posPoints.Length);
        agent = GetComponent<NavMeshAgent>();
        startPosition = gameObject.transform.position;

        StartCoroutine(GoPosPoints());
    }

    // Update is called once per frame
    void Update()
    {
        /*if (!isServer)
            return;*/

        if (fov.canSeePlayer)
        {
            GoToPlayer();
            
        }
        else if (hasSeenPlayer && !fov.canSeePlayer)
        {
            Patrol();
            if (targetTime < 0)
            {
                GoBackToSpawn();
            }
        }
    }

    [Command(requiresAuthority = false)]
    private void GoToPlayer()
    {
        GameObject[] players = GameObject.FindGameObjectsWithTag("Player");
        if (players.Length > 0)
        {
            // Set destination to the first player found (you might want to implement logic to select the closest player)
            agent.destination = players[0].transform.position;
            hasSeenPlayer = true;
            targetTime = 10.0f;
            SpawnPatrolPoints();
        }
    }

    [Command(requiresAuthority = false)]
    private void SpawnPatrolPoints()
    {
        if (!hasSpawnedPatrolPoints)
        {
            PatrolPoints.transform.position = agent.destination;
            hasSpawnedPatrolPoints = true;
        }
    }

    [Command(requiresAuthority = false)]
    private void Patrol()
    {
        targetTime -= Time.deltaTime;
        dest = posPoints[posInt].position;
        agent.SetDestination(dest);
        hasSpawnedPatrolPoints = false;
    }

    [Command(requiresAuthority = false)]
    public void GoBackToSpawn()
    {
        agent.SetDestination(startPosition);
    }

    IEnumerator GoPosPoints()
    {
        yield return new WaitForSeconds(PosTime);
        posInt = Random.Range(0, posPoints.Length);
        StartCoroutine(GoPosPoints());
    }
}

Field of view :

using System.Collections;
using UnityEngine;
using Mirror;

public class FieldOfView : NetworkBehaviour
{
    public float radius;
    [Range(0, 360)]
    public float angle;

    public LayerMask targetMask;
    public LayerMask obstructionMask;

    [SyncVar]
    public bool canSeePlayer;

    private void Start()
    {
        StartCoroutine(FOVRoutine());
    }

    private IEnumerator FOVRoutine()
    {
        WaitForSeconds wait = new WaitForSeconds(0.2f);

        while (true)
        {
            yield return wait;
            FieldOfViewCheck();
        }
    }

    private void FieldOfViewCheck()
    {
        Collider[] rangeChecks = Physics.OverlapSphere(transform.position, radius, targetMask);

        if (rangeChecks.Length != 0)
        {
            foreach (Collider col in rangeChecks)
            {
                if (!col.CompareTag("Player"))
                    continue;

                Transform target = col.transform;
                Vector3 directionToTarget = (target.position - transform.position).normalized;

                if (Vector3.Angle(transform.forward, directionToTarget) < angle / 2)
                {
                    float distanceToTarget = Vector3.Distance(transform.position, target.position);

                    if (!Physics.Raycast(transform.position, directionToTarget, distanceToTarget, obstructionMask))
                    {
                        canSeePlayer = true;
                        return; // If the player is seen, exit early
                    }
                }
            }
        }

        canSeePlayer = false; // If no player is seen, update to false
    }
}

i added NetworkIdentity to all the enemies but still nothing changed

0

There are 0 answers