How to set a Selectable's interactable property directly using a UnityEvent type through UnityEditor.Events.UnityEventTools.AddPersistentListener?
In the inspector for a UnityEvent field it is possible to assign the dynamic bool result to the interactable property of a button (or any selectable). I would like to automatically assign this call from a script rather than go through the inspector because I have a large number of such links to create.
Using the AddPersistentListener I know it is possible to call a function of a UnityEngine.Object with a bool parameter, however unfortunately interactable is a property of selectable and there is no 'SetInteractable' function I can assign. I also tried adding an extension method for the Selectable class to create such a method, however it turns out static methods are not allowed in the AddPersistentListener either, nor are lambda expressions, and I do not want to subclass button just to add this tiny wrapper function either. My current workaround is to store a reference to the selectable and add a new method to the class that is calling 'AddPersistentListener' such as this:
public class ButtonLinker: MonoBehaviour
{
public Button button;
public UnityEvent<bool> buttonInteractableCaller;
public void SetButtonInteractable(bool interactable) {
button.interactable = interactable;
}
public void OnValidate() {
#if UNITY_EDITOR
UnityEditor.Events.UnityEventTools.AddPersistentListener(buttonInteractableCaller,SetButtonInteractable);
#endif
}
}
But it would be better if there is some method to assign interactable without having to create this wrapper in the other class. I think unity itself must do something else because the inspector seems to be able to assign a dynamic bool to the interactable property itself without such a wrapper, any ideas how to achieve this?
Answer by ballistic_cowboy · Nov 02, 2020 at 05:35 PM
I figured this out for anyone else who is stuck. You need to include System.Reflection and then get the property set method and finally create an action of the correct type before adding it:
public class ButtonLinker: MonoBehaviour
{
public Button button;
public UnityEvent<bool> buttonInteractableCaller;
public void OnValidate() {
#if UNITY_EDITOR
MethodInfo mInfo = button.GetType().GetProperty("interactable").GetSetMethod();
var action = System.Delegate.CreateDelegate(typeof(UnityAction<bool>),button,mInfo) as UnityAction<bool>;
UnityEditor.Events.UnityEventTools.AddPersistentListener(buttonInteractableCaller,action);
#endif
}
}
Your answer
Follow this Question
Related Questions
Unity UI Events not working for Canvas objects 1 Answer
OnPointerClick only triggers when clicked on the top part of UI Image 1 Answer
Disable current drag of UI.Slider 2 Answers
IDropHandler only trigger when it's SpriteRenderer sortingOder is higher than draggable sortingOder 0 Answers
How to only click on certain objects/buttons and null the rest please help!! 1 Answer