CmdSetTarget doesn't run

it looks like when i right click on an “Enemy” unit the CmdSetTarget doesn’t get called.
i’ve made many builds and logged at eaceh stage of the code but i get the console message error at CmdSetTarget.
Immagine 2023-06-24 190951
UnitCommandGiver:

public class UnitCommandGiver : MonoBehaviour
{
    [SerializeField] private UnitSlectionHandler unitSlectionHandler = 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 hit, Mathf.Infinity, layerMask)) { return; }

        if(hit.collider.TryGetComponent<Targetable>(out Targetable target))
        {
            if (target.isOwned)
            {
                TryMove(hit.point);
                return;
            }

            TryTarget(target);
            return;
        }

        TryMove(hit.point);
    }

    private void TryMove(Vector3 point)
    {
        foreach (Unit unit in unitSlectionHandler.SelectedUnits)
        {
            unit.GetUnitMovement().CmdMove(point);
        }
    }
    private void TryTarget(Targetable target)
    {
        foreach (Unit unit in unitSlectionHandler.SelectedUnits)
        {
            unit.GetTargeter().CmdSetTarget(target.gameObject);
        }
    }
}

Targeter:

public class Targeter : NetworkBehaviour
{
    [SerializeField] private Targetable target;


    #region Server
    [Command]
    public void CmdSetTarget(GameObject targetGameObject)
    {
        if (!targetGameObject.TryGetComponent<Targetable>(out Targetable newTarget)) { return; }

        target = newTarget;
    }
    [Server]
    public void ClearTarget()
    {
        target = null;
    }

    #endregion

    #region Client
    #endregion


}

Can anyone help?

ok, my bad. i didn’t add reference of the targeter script in the unit script in the unit prefab.
now it kinda works. it looks like if i host the game on the game build i don’t get the reference on the script of the targeted unit. can anyone explain why this happens?

@Yitzchak_Cohen

So you were able to resolve the null reference you showed? What is the new error that is occurring? Which unit reference is missing now?

Double check that your list of units in the RTSPlayer script is being populated correctly on the host. That is often a source of error in selection.

yes, i’ve resolve the null reference by adding reference of the targeter in the unit script as the image below


as you suggestet it looks like the player list of unit doesn’t get populated.
how do i solve this problem?

The first place to look is the event subscriptions for adding units to the list. Make sure all the "+"s and "-"s are correct and that is says spawn and despawn in the correct lines. Often when copy and pasting these, they are not updated correctly and it causes the unit lists to be incorrect.

i think my RTSPlayerScript id fine:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
using System;

public class RTSPlayerScript : NetworkBehaviour
{
    [SerializeField] private List<Unit> myUnits = new List<Unit>();

    public List<Unit> GetUnits()
    {
        return myUnits;
    }

    #region Server
    public override void OnStartServer()
    {
        Unit.ServerOnUnitSpawned += ServerHandleUnitSpawned;
        Unit.ServerOnUnitDespawned += ServerHandleUnitDespawned;
    }

    public override void OnStopServer()
    {
        Unit.ServerOnUnitSpawned -= ServerHandleUnitSpawned;
        Unit.ServerOnUnitDespawned -= ServerHandleUnitDespawned;
    }

    private void ServerHandleUnitSpawned(Unit unit)
    {
        if(unit.connectionToClient.connectionId != connectionToClient.connectionId) { return; }

        myUnits.Add(unit);
    }

    private void ServerHandleUnitDespawned(Unit unit)
    {
        if (unit.connectionToClient.connectionId != connectionToClient.connectionId) { return; }

        myUnits.Remove(unit);
    }
    #endregion

    #region Client
    public override void OnStartClient()
    {
        if (!isClientOnly) { return; }

        Unit.AuthorityOnUnitSpawned += AuthorityHandleUnitSpawned;
        Unit.AuthorityOnUnitDespawned += AuthorityHandleUnitDespawned;
    }

    public override void OnStopClient()
    {
        if (!isClientOnly) { return; }

        Unit.AuthorityOnUnitSpawned -= AuthorityHandleUnitSpawned;
        Unit.AuthorityOnUnitDespawned -= AuthorityHandleUnitDespawned;
    }
    private void AuthorityHandleUnitDespawned(Unit unit)
    {
        if (!isOwned) { return; }

        myUnits.Add(unit);
    }

    private void AuthorityHandleUnitSpawned(Unit unit)
    {
        if (!isOwned) { return; }

        myUnits.Remove(unit);
    }

    #endregion

Looks all right to me. Perhaps you can add some further debug statements into the event handler methods to double check they are adding and removing the units.

as i continue in the lecture it looks like everything works fin, yet i don’t understand why this happens:

Are you missing the the client’s target on the host? Or the host’s target on the host?

Privacy & Terms