Sprite only showing on host

The sprite only shows below the unit on the host window. Both of the players’ sprites show in this window, but the client’s doesn’t disappear when you click off of it. Does anyone have an idea why? (The movement works perfectly though).
Thanks in advance.

Here is an image of the problem that I’m experiencing:

Here are my scripts:

Unit:

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

public class Unit : NetworkBehaviour
{
    [SerializeField] private unitMovement movementScript;
    [SerializeField] private UnityEvent onSelected;
    [SerializeField] private UnityEvent onDeselected;

    public unitMovement GetUnitMovement()
    {
        return movementScript;   
    }

    [Client]
    #region Client
    public void Select()
    {
        if (!hasAuthority) return;
        onSelected?.Invoke();
    }

    [Client]
    public void Deselect()
    {
        if (!hasAuthority) return;
        onDeselected?.Invoke();
    }

    #endregion

}

UnitSelectionHandler:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class UnitSelectionHandler : MonoBehaviour
{
    [SerializeField] private LayerMask layerMask;
    
    private Camera mainCamera;

    public List<Unit> SelectedUnits { get; } = new List<Unit>();
    private List<Unit> deSelectedUnits = new List<Unit>();


    private void Start()
    {
        mainCamera = Camera.main;
    }

    private void Update()
    {
        if(Mouse.current.leftButton.wasPressedThisFrame)
        {
            StartSelectedUnits();
        }
        else if (Mouse.current.leftButton.wasReleasedThisFrame)
        {
            ClearSelectionArea();
        }
    }

    private void StartSelectedUnits()
    {

        foreach (Unit thisUnit in SelectedUnits)
        {
            thisUnit.Deselect();
        }

        SelectedUnits.Clear();

    }

    private void ClearSelectionArea()
    {
        Ray ray = mainCamera.ScreenPointToRay(Mouse.current.position.ReadValue());

        if (!Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity, layerMask)) return;
        /*
          Trygetcomponent: Tries to get the "Unit" component. If it does, it will output a new unit (The unit that it hit).
          If there is no "Unit" script on the hit, it will return.
        */
        if (!hit.collider.TryGetComponent<Unit>(out Unit unit)) return;
        if (!unit.hasAuthority) return;

        SelectedUnits.Add(unit);

        foreach(Unit selectedUnit in SelectedUnits)
        {
            selectedUnit.Select();
        }
    }
}

UnitCommandGiver:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class UnitCommandGiver : MonoBehaviour
{
    [SerializeField] private UnitSelectionHandler unitSelectionHandler;
    [SerializeField] private LayerMask layerMask = new LayerMask();
    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;

        TryMove(hit.point);
    }

    private void TryMove(Vector3 point)
    {
        foreach(Unit unit in unitSelectionHandler.SelectedUnits)
        {
            unit.GetUnitMovement().CmdMove(point);
        }
    }
}

unitMovement :

using UnityEngine;
using Mirror;
using UnityEngine.AI;

public class unitMovement : NetworkBehaviour
{
    [SerializeField] private NavMeshAgent navMesh;

    #region Server

    //See "myNetworkPlayer" for explanation
    [Command]
    public void CmdMove(Vector3 position)
    {
        //NavMesh.SamplePosition: finds nearest point on navmesh, even if the position is off of the navmesh.
        //Hit: The resulting location.
        if (!NavMesh.SamplePosition(position, out NavMeshHit hit, 1f, NavMesh.AllAreas)) return;
        else navMesh.SetDestination(hit.position);
    }

    #endregion

}

Hi There,

Did you updated your events in the inspector to activate/deactivate the gameObjects instead of enabling/disabling the spriteRenderer? This was recently added to the lecture.

To be clear, you can move the units even though the selection sprite is not enabled?

Yes, I did set it to activate/deactivate the game objects. Yes I can move them like they are moved in the lecture.

Thanks for your help.

I just tested it by setting the SpriteRenderer to enable or disable. I now see the sprite in the client’s window as well, but I still see both sprites in the host’s window. Any idea why?
Thanks.

Hi, is it possible to put it back to the gameObjects version and then show the what it looks like in the inspector? Also put some debug.log statements in Select and Deselect on the unit.cs and see if those are getting called.

Both are set as game object.
The debug.log statements are printing.

Window in editor as client:

Built window as client:

What if you put the debug statements after the authority checks?
Your getting different behaviour if the client is in the build vs the editor? I don’t know what it would have to do with the sprites, but in the past if the input system was set to old or new and not both it caused different behaviour in the build vs the editor. So maybe double check if the input system is set to both.

I think that they are after the authority checks, I don’t get different behaviour, I just wanted you to see the debug Logs for both the client and the Server. Don’t worry too much about this question though, since it doesn’t really affect my learning from the course.

Thanks for your help so far.

@Yitzchak_Cohen, wow I feel dumb, the sprite renderer was set to inactive all this time lol. But anyways, the problem is now fixed.

1 Like

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

Privacy & Terms