- Home /
Unityaction vs Method
I'm still pretty new to certain subjects of unity, so I don't know if this is a stupid question. XD
I tried to find information on this subject but I couldn't find anything specific. Currently I'm learning to create dynamic menus. To handle the variable processes started by buttons I'm working with unityactions. However, there's something I don't understand.
When adding listeners to an onclick event for example it doesn't seem to make a difference if I'm passing a unityaction or just simply the name of a method.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using System.Collections;
public class test_unityaction : MonoBehaviour {
private UnityAction action;
void Awake() {
action = new UnityAction (Func);
gameObject.GetComponent<Button> ().onClick.AddListener (action);
gameObject.GetComponent<Button> ().onClick.AddListener (Func);
}
void Func() {
print ("Func");
}
}
This is a very basic and easy code example. Add it to a button to test it.
The function is launched twice.
So my question is what is the difference here? Why should I pass a unityaction if I can simply pass the method name? Passing the method directly instead of a unityaction makes the code much more simple. Is there a disadvantage for passing the method directly because it seems to work as intended?
Answer by Hellium · Jun 25, 2015 at 09:17 PM
I have never used UnityActions. I read in the doc that it is a delegate. Then, you could possibly do something like this (didn't tested)
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using System.Collections;
public class test_unityaction : MonoBehaviour {
private UnityAction action;
void Awake() {
action = new UnityAction (Func);
action += Func1 ;
action += Func2 ;
gameObject.GetComponent<Button> ().onClick.AddListener (action);
}
void Func() {
print ("Func");
}
void Func1() {
print ("Func1");
}
void Func2() {
print ("Func2");
}
void Func3() {
print ("Func3");
}
}
Obviously, using UnityAction is clearer.
You could also modify the function called dynamically with something like this :
void Update() {
if (Input.GetKeyDown("space"))
{
gameObject.GetComponent<Button> ().onClick.RemoveListener( action ) ;
action -= Func1 ;
action += Func3 ;
gameObject.GetComponent<Button> ().onClick.AddListener (action);
}
}
Then, your button won't call Func1 anymore but call Func3 instead when you click on your button.
EDIT : I have tested without removing and adding back again the action, it doesn't seem to work.
Everything I did could have been possible without the UnityAction. Just remove the function you don't want anymore and add the one you want.
By the way, since AddListener is wainting for a delegate without any parameter and a return type of void, you could have done this :
gameObject.GetComponent<Button> ().onClick.AddListener ( delegate()
{
Debug.Log("Hello World !") ;
}
)
Or, with anonymous delegate :
gameObject.GetComponent<Button> ().onClick.AddListener ( () =>
{
Debug.Log("Hello World !") ;
}
)
After reading your answer I've done some more testing and indeed all this doesn't seem to make any difference. XD
The only advantage of using a unityaction object seems to be that I have a seperate object I can manage seperately and pass as a parameter for example.
Also the unityaction object has several functions like begininvoke and stuff, which might be useful for asynchronous processes.
However, I discovered that removing a listener method that is also assigned through an action is removed too.
For example this will result in no listeners being assigned at all:
void Awake() {
action = new UnityAction (Func);
action += Funcb;
gameObject.GetComponent<Button> ().onClick.AddListener (action);
gameObject.GetComponent<Button> ().onClick.AddListener (Func);
gameObject.GetComponent<Button> ().onClick.AddListener (Funcb);
gameObject.GetComponent<Button> ().onClick.RemoveListener (Func);
gameObject.GetComponent<Button> ().onClick.RemoveListener (Funcb);
}
Your answer
![](https://koobas.hobune.stream/wayback/20220613201401im_/https://answers.unity.com/themes/thub/images/avi.jpg)