If you’re reading this, there probably aren’t very many posts yet. But don’t worry, you can be the first! Either create a new post or just reply to this one to say ‘hi’.
Hi @Ben,
I’ve come across a bug where the cursor does not change. This happens whenever the cursor points to a non existing layer like Unity’s background (infinity). I’ve modified the code a little so that it also shows the RaycastEndStop-question mark cursor whenever this situation happens:
void Update()
{
foreach (Layer layer in layerPriorities)
{
...
}
objectHit.distance = distanceToBackground;
// Layer did not change since it did not hit any.
// Also check if the previous layer isn't already set to RaycastEndStop to
// prevent unnecessary setting the _layerHit each frame
if (_layerHit != Layer.RaycastEndStop)
{
_layerHit = Layer.RaycastEndStop;
layerChangeObservers (); // call the delegate as well
}
}
Thanks, we’ve not been testing with the backstop much yet.
Just in case, there’s an error you can possibly encounter during the lecture even if you have the exactly same code. This:
NullReferenceException:
CameraRaycaster.Start() (at Assets/Camera & UI/CameraRaycaster.cs:31)
I’m a beginner to delegates, so I might be wrong, but I assume the problem here is that you can’t call layerChangeObservers()
when nothing has subscribed to them (yet). If you aren’t as lucky as Ben and CameraRaycaster.cs
script gets executed before CursorAffordance.cs
(where OnLayerChanged is being registered), you get an error.
This can be fixed either by changing CursorAffordance’s Start to Awake or by altering the Script Execution Order, so the CursorAffordance script gets called first.
…or you can wait for the end of the lecture when it gets fixed by itself by calling layerChangeObservers()
from Update.
I had a similar problem with the code. For what it is worth, here is the code that I used to get the unknown cursor displaying after adding the delegates in Update () :
// return background hit
raycastHit.distance = distanceToBackground;
// this solves problem with Unknown Cursor not displaying
if (layerHit != Layer.RaycastEndStop)
{
layerHit = Layer.RaycastEndStop;
onLayerChange (Layer.RaycastEndStop);
}
}
In my quest to understand delegates it was often mentioned that it’s best practice to use OnEnable()
to subscribe and OnDisable()
to unsubscribe them, to prevent any references hanging around and things getting sloppy.
Is this something you get to later, and I’m just jumping the gun?
Also, I like the fact that you used an empty class to explain a new topic. It helped keep the distractions down and focus only on what was needed. I often find when new concepts are introduced the less complex the example project is the better I understand it. Even more so when an entirely new scene/set of classes is used just for demo purposes. Thank, Ben!
Does it cause any problems if I give the active function in the cursor class the identical name to the delegate type in the raycaster class- ie both are ‘OnLayerChange’? I notice you called the function ‘OnLayerChanged’, with an extra ‘d’ - was that deliberate or does it not matter if they are the same?
BlackPhi it shouldn’t cause an issue but that is probably a bad programming practice. They exist on different objects so it should work. The problem is it causes confusion for you (when you are in a 3rd object which do you need to work with) and it would make it difficult for anyone else to follow the code. Working in teams I would not suggest this pattern.
If you are working on a team you would have a coding standard and naming standards so everyone knows how you name things so things make sense.
If your delegate(event) is LayerChanged
Your subscription or (event handler) could be called OnLayerChanged
Delegates are placeholders for functions. I know that isn’t probably any clearer. But if you think about them as events it might be more helpful. Like an OnClick delegate, or a DataChange. Delegates can be used in other ways but they get a little trickier.
Thanks, Andrew, that makes absolute sense. Also the example of LayerChanged and OnLayerChanged makes the relationship much clearer.
My preference would be to use the naming that makes the most sense. OnLayerChange to me indicates something that is happening (present tense) that I can intercept or influence. It might even typically come with a cancellation flag or token, that if I set it, results in no change happening at all.
OnLayerChanged however indicates something that already happened, there’s no changing to it, I just get the opportunity now to react to that change.
As I learn about delegates. Never seen them before! O_O
They can be EXTREMELY helpful. They allow you to save so much time and effort. Especially line of code. I understand little. But it seems delegates take in the function and spit out the function only when necessary. I think
I understand how important the operator += and -+ are.
Delegates are fast and powerful but must be used carefully.
I still need a better understanding and practice. I’ll get there.
Greetings All,
I’m blown away by the power of Delegates. I mean here I thought we were going to have to write the whole handler for managing the list of observers, and it’s just in there already in C#. It’s built into the system where you can just call the simple functions and it works like magic because of how the language is set up. HUGE power from this tool. Very excited to make use of it. Thank you SO much for teaching this.
Jenn