Hello everyone,
I am currently doing the Mirror RTS Multiplayer Course and I am using Mirror 89.0.0
I am currently on lecture 20. Storing our units and I realized that when I join as a host on the editor and as a client on the build, I can’t move my player 2 when I go to play on the build, but moving player 1 on the editor works perfectly fine. Here is my code:
using Mirror;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace RTS.Core
{
public class Unit : NetworkBehaviour
{
//unity events to toggle the selected sprite on/off
[SerializeField] private UnityEvent OnSelected = null;
[SerializeField] private UnityEvent OnDeselected = null;
[SerializeField] private UnitMovement unitMovement = null;
//events to be called on the server when a unit spawns/despawns
//it is static because the server does not need to have a reference to what unit it was exactly, at least for now
public static event Action<Unit> ServerOnUnitSpawned;
public static event Action<Unit> ServerOnUnitDespawned;
public static event Action<Unit> ClientAuthorityOnUnitSpawned;
public static event Action<Unit> ClientAuthorityOnUnitDespawned;
#region Server
//a unit has been spawned into the server; happens AFTER the RTS Player has been spawned into the server
public override void OnStartServer()
{
ServerOnUnitSpawned?.Invoke(this);
}
//a unit has been despawned from the server; happens BEFORE the RTS Player has been despawned from the server
public override void OnStopServer()
{
ServerOnUnitDespawned?.Invoke(this);
}
#endregion
#region Client
[Client]
public void Select()
{
if (!isOwned) return;
OnSelected?.Invoke();
}
[Client]
public void Deselect()
{
if(!isOwned) return;
OnDeselected?.Invoke();
}
public UnitMovement GetUnitMovement()
{
return unitMovement;
}
//used to store the units for each unique client in the game
public override void OnStartClient()
{
if (!isClientOnly || !isOwned) return;
ClientAuthorityOnUnitSpawned?.Invoke(this);
}
public override void OnStopClient()
{
if (!isClientOnly || !isOwned) return;
ClientAuthorityOnUnitDespawned?.Invoke(this);
}
#endregion
}
}
using Mirror;
using UnityEngine;
using UnityEngine.AI;
namespace RTS.Core
{
public class UnitMovement : NetworkBehaviour
{
[SerializeField] NavMeshAgent playerNavMesh = null;
#region Server
[Command]
public void CmdMovePlayerToPosition(Vector3 position)
{
if (!NavMesh.SamplePosition(position, out NavMeshHit navMeshHit, 1f, NavMesh.AllAreas)) return;
playerNavMesh.SetDestination(navMeshHit.position);
}
#endregion
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
namespace RTS.Core
{
public class UnitCommandGiver : MonoBehaviour
{
[SerializeField] private UnitSelectionHandler unitSelectionHandler = null;
[SerializeField] private LayerMask layerMask = new LayerMask();
private Camera mainCamera;
private void Start()
{
mainCamera = Camera.main;
}
private void Update()
{
if (!Mouse.current.rightButton.wasPressedThisFrame) return;
Ray ray = mainCamera.ScreenPointToRay(Mouse.current.position.ReadValue());
if (!Physics.Raycast(ray, out RaycastHit raycastHit, Mathf.Infinity,layerMask)) return;
TryMove(raycastHit.point);
}
private void TryMove(Vector3 point)
{
foreach (Unit unit in unitSelectionHandler.SelectedUnits)
{
Debug.LogError(unitSelectionHandler.SelectedUnits.Count);
unit.GetUnitMovement().CmdMovePlayerToPosition(point);
}
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
namespace RTS.Core
{
public class UnitSelectionHandler : MonoBehaviour
{
public List<Unit> SelectedUnits { get; } = new List<Unit>();
private Camera mainCamera;
[SerializeField] private LayerMask layerMask = new LayerMask();
private void Start()
{
mainCamera = Camera.main;
}
private void Update()
{
if (Mouse.current.leftButton.wasPressedThisFrame)
{
StartSelectionArea();
}
else if (Mouse.current.leftButton.wasReleasedThisFrame)
{
ClearSelectionArea();
}
}
private void StartSelectionArea()
{
//deselect a unit
foreach (Unit unit in SelectedUnits)
{
unit.Deselect();
}
SelectedUnits.Clear();
}
private void ClearSelectionArea()
{
//select and enable the sprite on a clicked unit
Ray ray = mainCamera.ScreenPointToRay(Mouse.current.position.ReadValue());
if (!Physics.Raycast(ray, out RaycastHit raycastHit, Mathf.Infinity,layerMask)) return;
if (!raycastHit.collider.TryGetComponent<Unit>(out Unit unit)) return;
if (!unit.isOwned) return;
SelectedUnits.Add(unit);
foreach (Unit selectedUnit in SelectedUnits)
{
selectedUnit.Select();
}
}
}
}
Help or advice on this would be much appreciated