- Unity Button Onclick Parameter
- Unity Button Onclick Not Working
- Add Listener Unity C#
- Unity Addlistener With Parameter
- Unity Addlistener Not Working
Author: Ilya Suzdalnitski
|
Description
This is an advanced version of a messaging system for C#.It will automatically clean up its event table after a new level has been loaded. This will prevent the programmer from accidentally invoking destroyed methods and thus will help prevent many MissingReferenceExceptions.This messaging system is based on Rod Hyde's CSharpMessenger and Magnus Wolffelt's CSharpMessenger Extended.
Based on this question on the Unity forum, I've made this code to instantiate a button and add an onClick event. // Setting some other component properties right of the prefab. Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. AddListener: Add a non persistent listener to the UnityEvent. Invoke: Invoke all registered callbacks (runtime and persistent). Get code examples like 'unity button.onclick.addlistener' instantly right from your google search results with the Grepper Chrome Extension. Implementing a custom event system in Unity with C#. Usage: EventUtil.AddListener ('Event Name, Callback Method'// Add Event Listener EventUtil.RemoveListener ('Event Name, Callback Method'//Remove Event Listener EventUtil.DispatchEvent ('Event Name', 'Uncertain Length Parameter'// Dispatch Event).
Foreword
Upon introduction of a messaging system into our project (CSharpMessenger Extended) we started facing very strange bugs. Unity3d would throw MissingReferenceExceptions every time a message was broadcasted. It would say that the class, where the message handler was declared in, was destroyed. The problem came out of nowhere and there was not a reasonable explanation behind it. However placing the message handler code within try-catch blocks solved the problem. We understood that it was not a good solution to have hundreds of try-catch blocks in our code.It took us some time to finally figure out where was the problem.
Cause behind the MissingReferenceException and solution
It turned out, that the MissingReferenceException bug appeared, when a new level was loaded (or current one was reloaded). For example, we have a message 'start game', declared as follows:
At first glance, there's no problem at all, but after the level has been reloaded, Unity3d will throw an exception, saying that MainMenu has been destroyed. However there's no code that would EVER destroy the MainMenu script.
What actually happened is:
- We added a 'start game' message listener to our Messenger.
- StartGameButtonPressed was called which in turn broadcasted the 'start game' message.
- We reloaded the level with Application.LoadLevel.
- Step 1 repeated.
- Step 2 repeated.
Here's how eventTable of the messenger looks like at corresponding steps:
- At step 1: { 'start game', mainMenu1- > StartGame(); }
- At step 4: { 'start game', mainMenu1- > StartGame(); } { 'start game', mainMenu2- > StartGame(); }
So at step 4 we have two message handler for the same 'start game' message - the first one is for the destroyed MainMenu object (got destroyed when reloaded a level), and the second one it for the current valid MainMenu object.It turns out that when we broadcast the 'start game' message after reloading the level, the messenger invokes both - the destroyed and the valid message handlers. This is where the MissingReferenceException came from.
So the solution is obvious - clear the eventTable after unloading a level. There's nothing else the programmer has to do on his side to clean up the table, it's being done automatically.
We're happy to present you an advanced version of C# messaging system.
Usage
Event listener
Registering an event listener
Unregistering an event listener
Broadcasting an event
Cleaning up the messenger
The messenger cleans up its eventTable automatically when a new level loads. This will ensure that the eventTable of the messenger gets cleaned up and will save us from unexpected MissingReferenceExceptions.In case you want to clean up manager's eventTable manually, there's such an option by calling Messenger.Cleanup();
Permanent messages
If you want a certain message to survive the Cleanup, mark it with Messenger.MarkAsPermanent(string). This may be required if a certain class responds to messages broadcasted from across different levels.
Misc
Log all messages
For debugging purposes, you can set the shouldLogAllMessages flag in Messenger to true. This will log all calls to the Messenger.
Transition from other messengers
To quickly change all calls to messaging system from older CSharpMessenger's to the advanced, do the following steps:
- In MonoDevelop go to Search => Replace in files
- In Find field enter: Messenger<([^<>]+)>.([A-Za-z0-9_]+)
- In Replace field enter: Messenger.$2<$1>
- Select scope: Whole solution.
- Check the Regex search check box.
- Press the Replace button
Code
There're two files required for the messenger to work - Callback.cs and Messenger.cs.
Callback.cs
Messenger.cs
Friday, May 17, 2019
Unity Button Onclick Parameter
In this article we will do a little setup and then spend the majority of time focusing on dealing with user input, in our case both pointer up and pointer down, as it relates to our draggable behavior. We will first see how we wire up our event handlers using the Unity editor and once we have a better understanding of that process we will proceed to wire them up programatically so that we do not have to do the manual steps everytime we add our draggable behavior to an object.
Parts
- Part 1: Draggable Pointer Events
Project Start
- Assets
- UserInterface
- Scenes
- DraggableScene.unity
- DraggableBehavior.cs
- Scenes
- UserInterface
We will start by creating the UserInterface
folder within our Unity project. Once that is done we will create an additional Scenes
folder that will contain our scenes and we will create a new scene within it. Last up is to create our first script which we will name DraggableBehavior.cs
and is shown in (a).
Now that our script is created we will return to Unity and create a DraggableScene
and within that scene we will add UI Panel. Once tha panel is added will need to set the anchors and the pivot to (0.5, 0.5), the position to (0, 0) and height and width to 150 each. Next up we can add our DraggableBehavior
script to our panel either by dragging the the script into the inspector on the right or by using the add component button. Once that is done we should have everything set up as shown in (b).
DraggableBehavior
script to the panel. How about a pretty green color?
Unity Button Onclick Not Working
- Assets
- UserInterface
- DraggableBehavior.cs
- UserInterface
Add Listener Unity C#
My intention is to have the ability to drag a ui component around whenever our draggable behavior is active. To indicate to the user that they can in fact drag something our first job is to define a color that will be shown when our component is active and to have that color applied automatically for us (c). The property that we are calling Handle
represents the game object that will be able to click and drag on to move the object. In the end we will end up with the ability to drag around an ancestor container by clicking and dragging on a child. But for now we will focus on just dragging our single panel around.
Once that is done and we return to Unity if we play our scene we should see that our panel is colored with the appropriate color as shown in (d).
Manual Event Handling
- Assets
- UserInterface
- DraggableBehavior.cs
- UserInterface
Next up we will add some event handling to our script. First up is just to add a couple of methods that we can use to wire up the event handling within the Unity editor (e).
Now that we have the methods defined we can turn back to the Unity editor and add an Event Trigger
component and within it add our two entries, one each for pointer up and pointer down, and point them to the methods we just created (f). With that done if he play our scene we should see information printed to the console if we click on the panel.
Event Trigger
component and adding entries to it, in this case for pointer up and pointer down. Doing things manually is for the birds
- Assets
- UserInterface
- DraggableBehavior.cs
- UserInterface
I am a big believer in having things work with as close to zero configuration as possible and to that end we will add our event handling within our script instead of having to wire things up manually inside of the Unity editor any time we want to add our dragging behavior. First thing to do is to remove the Event Trigger
component from our panel. Next up is to modify our script to add the Event Trigger
component and to wire up our entries (g).
If we check again by playing our scene and click on our panel we should see once again that we have the information being displayed in the debug console.
Unity Addlistener With Parameter
Enter the extension method
- Assets
- Utilities
- UiUtilities.cs
- Utilities
Adding the event handlers to our panel is a bit on the verbose side for me. And since this is an operation that we will do multiple times we might as well make it a bit easier on us to do. To do this we will create our first extension method (h).
Unity Addlistener Not Working
Updating our behavior
- Assets
- UserInterface
- DraggableBehavior.cs
- UserInterface
With our extension method in place we can update our draggable behavior to use it as shown in (i).