Problem calling Delegate from Cursor Affordance script

For some reason, which I haven’t been able to figure out, my attempts to call OnDelegateCalled() are not working.

CameraRaycaster:

public delegate void OnLayerChange(); //Declare new delegate type
public OnLayerChange layerChangeObservers; //Instatiate Observer set

void SomeLayerChangeHandler()
{
    print ("SomeLayerChangeHandler() I handled it!");
}



void Start()
{
    viewCamera = Camera.main;

    layerChangeObservers += SomeLayerChangeHandler; // Add to set of handling functions

    layerChangeObservers(); // Call the delegates
}

CursorAffordance:

CameraRaycaster cameraRaycaster;

// Use this for initialization
void Start () {
    cameraRaycaster = GetComponent<CameraRaycaster>();
    cameraRaycaster.layerChangeObservers += OnDelegateCalled;
}

//  Is called when layer changes
void OnDelegateCalled()
{
    print("OnDelegateCalled has worked");
    switch (cameraRaycaster.currentLayerHit)
    {
        case Layer.Walkable:
            Cursor.SetCursor(walkCursor, cursorHotspot, CursorMode.Auto);
            break;
        case Layer.Enemy:
            Cursor.SetCursor(targetCursor, cursorHotspot, CursorMode.Auto);
            break;
        case Layer.RaycastEndStop:
            Cursor.SetCursor(unknownCursor, cursorHotspot, CursorMode.Auto);
            break;
        default:
            Debug.LogError("Don't know what cursor to show");
            return;
    }
    
}

I also created a test script, the test script does work as intended.

TestScript:

public class DelegateTest : MonoBehaviour {

CameraRaycaster cameraRaycaster;

// Use this for initialization
void Start () {
    cameraRaycaster = GetComponent<CameraRaycaster>();
    cameraRaycaster.layerChangeObservers += TestMethod;

}

// Update is called once per frame
void TestMethod () {
    print("Test method has been run");
}

I get the print of “SomeLayerChangeHandler() I handled it!”, and, “Test method has been run”, but not, “OnDelegateCalled has worked”

Any help would be appreciated!

Thanks.

Ok, so I have found that by changing Start() to Awake() in CursorAffordance, I no longer have this problem. Is this something to do with the order the scripts are running?

My Test script works fine using the Start(), my CursorAffordance script only works properly when Start() is changed to Awake(). In this course lesson you are using Start() without having this issue.

If anyone can let me know why I’m having this happen I’d appreciate it.

Thanks.

1 Like

See, in terms of virtual method calls in monobehavior scripts, as you must be aware, Awake gets called first, then start.
Amongst the start methods of each script, which one will get called before which one is not predefined and can vary from unity to unity, machine to machine, scenario to scenario, unless you specify script execution order. Forget about that for now.

What is happening in your case is that CursorAffordance is subscribing to the cameraRaycaster.layerChangeObservers delegate in start. That start must be getting called after the start of CameraRaycaster itself. So, the delegate is already fired when you were not listening to it. Later when you listen to it, it is not firing and hence you are not getting your desired output.

What happens if you shift the code of CursorAffordance::Start to CursorAffordance::Awake is that now Awake is guaranteed to be called before any start method on any script, so you method CursorAffordance::OnDelegateCalled() is getting correctly subscribed to the desired delegate first and then in subsequent CameraRaycaster::Start(), when the delegate s fired, you are getting your output.

What worked with Ben’s system is not guaranteed that you fire delegate in one start method and acquire the notification of that delegate fire in another start method. I would not suggest you go that route. Instead, subscribing to delegates and events in Awake or OnEnable is much more guaranteed to be successful.

3 Likes

Just to add to Sourav’s excellent response, here’s the Execution of Event Functions diagram from the Unity documentation which may also be of some use;


Click to enlarge


See also;

1 Like

I’m having the same issue. I think a step was left out of the lecture.

Hi Sourav,

Thanks you very much for the information. I too was having the same issue from the lecture. I changed my code from occuring in the Start function to the Awake function and now my print statement is being applied from a different script.

Tim

Privacy & Terms