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