Cursor Affordance Not Working (Layer Priority Issue)

At around the time we completed the cursor affordance script, I noticed that I wasn’t getting a change when mousing over or clicking on an object on the enemy layer. I triple checked all my scripts and inspector values and couldn’t find the issue, but saw that we were going to do more work on it, so plodded ahead. I’ve now completed through Lecture 23, and it still doesn’t work. Additionally, the unknown cursor has stopped working. I’m using Unity 5.5.4

The enemy

DynamicCursor.cs (cursor affordance script)

[RequireComponent(typeof(CameraRaycaster))]
public class DynamicCursor : MonoBehaviour
{
    [SerializeField] Texture2D WalkCursor = null;
    [SerializeField] Texture2D EnemyCursor = null;
    [SerializeField] Texture2D UnknownCursor = null;
    [SerializeField] Vector2 CursorHotspot = new Vector2(0,0);

    private CameraRaycaster _cameraRaycaster;

    void Start ()
    {
        _cameraRaycaster = GetComponent<CameraRaycaster>();
        _cameraRaycaster.LayerChangeObservers += OnLayerChange;
    }

    void OnLayerChange (Layer newLayer) {
        switch (newLayer)
        {
            case Layer.Walkable:
                Cursor.SetCursor(WalkCursor, CursorHotspot, CursorMode.Auto);
                break;
            case Layer.RaycastEndStop:
                Cursor.SetCursor(UnknownCursor, CursorHotspot, CursorMode.Auto);
                break;
            case Layer.Enemy:
                Cursor.SetCursor(EnemyCursor, CursorHotspot, CursorMode.Auto);
                break;
            default:
                Debug.LogWarning("Unknown layer hit by mouse cursor!");
                return;
        }
    }
}

CameraRaycaster.cs

public class CameraRaycaster : MonoBehaviour
{
    public Layer[] LayerProperties =
    {
        Layer.Walkable,
        Layer.Enemy
    };

    [SerializeField] float _distanceToBackground = 100f;
    private Camera _viewCamera;

    private RaycastHit _raycastHit;
    public RaycastHit Hit
    {
        get { return _raycastHit; }
    }

    private Layer _layerHit;
    public Layer CurrentLayerHit
    {
        get { return _layerHit; }
    }

    public delegate void OnLayerChange(Layer newLayer);
    public event OnLayerChange LayerChangeObservers;

    void Awake () {
        _viewCamera = Camera.main;
    }
    
    void Update () {
        foreach (Layer layer in LayerProperties)
        {
            var hit = RaycastForLayer(layer);

            if (hit.HasValue)
            {
                _raycastHit = hit.Value;

                if (_layerHit != layer)
                {
                    _layerHit = layer;
                    if (LayerChangeObservers != null) LayerChangeObservers(layer);
                }
                _layerHit = layer;
                return;
            }
        }

        _raycastHit.distance = _distanceToBackground;
        _layerHit = Layer.RaycastEndStop;
    }

    RaycastHit? RaycastForLayer(Layer layer)
    {
        int layerMask = 1 << (int) layer;
        Ray ray = _viewCamera.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        bool HasHit = Physics.Raycast(ray, out hit, _distanceToBackground, layerMask);

        if (HasHit)
        {
            return hit;
        }

        return null;
    }
}

Please let me know if there’s anything else you’d like to see. I appreciate any extra eyes on this, I’ve been over it too many times to see it anymore :sweat_smile:

EDIT: Thought I should mention, when I mouse over or click off the ground plane (eg. off the edge of the “world”), both the RaycastEndStop and default cases trigger and log tot he console. They do not trigger when mousing over or clicking on geometry that is not assigned to a layer.

Make sure you have the “Walkable” and “Enemy” layers set on the appropriate items.

Thanks for your reply, but as you can see from the screenshot I posted, I have the Enemy layer set. The same is true for all Walkable objects (that is, they have their layer set to Walkable).

Sorry, I couldn’t see the screenshot earlier.

In one of the videos in Section 2, Ben is having problems with that too. In his case, the cursors kept getting un-assigned in the inspector and it was a problem with his GIT setup.

You might double check that all the 3 cursors are still assigned like they should be. Also, make sure that your camera arm prefab has all the changes applied. It could be that the camera arm you have in one scene is fine, but the prefab isn’t, so when you use it in another scene, it’s not working?

I only have one scene, and I haven’t noticed the cursors being unassigned at all. Here’s some screens of my camera set up. You’ll have to click on the second one to see it in it’s entirety.

camera arm

After completing through Lecture 45, where we write the custom raycast editor script, the cursor affordance is now working properly. I never did find any typos, other coding errors, or editor errors, so I believe this likely had to do with layer priorities not being set properly. Ben mentions this in Lecture 44 or 45.

I’m marking this thread as solved.