Trouble with moving players on the newest version of Mirror

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

Hi there,
I just had another student with this issue. I think in the latest Mirror they have updated the Network Transform to be only one direction. Either sync client to server or server to client. Make sure your prefabs have their Network Transforms all set to sync from server to client so the server can control the movement for all of the units.

Let me know if that helps!

Thank you very much, it worked! The issue was indeed in the Network Transforms of the Units, they were set to Client to Server, I changed them to Server to Client and it works fine now.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms