Unity新UI-动态更改GUI元素调用的功能


17

希望动态更改按钮OnClick和滑块On Value Changed中的值 例子1 例子2

如果我不得不猜测如何完成此操作,请获取对button / gui元素的引用。接下来,获取Button脚本组件,并访问该函数调用列表。但是我不确定如何修改该列表。有人有想法么?

可能有帮助的更多详细信息:

  • 所调用的函数是自定义脚本组件的一部分
  • 对滑块使用“动态”变量选项
  • 可用于创建动态按钮

Answers:


23

有一种更改事件的超级简单方法:

编辑

请参阅我的其他答案,以快速,轻松地为事件添加OnClick事件。对于其他事件,OnDrag请参见下文。


此外,如果您不仅仅需要默认提供的事件,建议EventTrigger您将a附加到您的游戏对象上。这使我们可以访问BaseEventData从事件返回的对象,从而告诉我们诸如创建事件的对象之类的东西。然后,您可以执行以下操作:

//Create an event delegate that will be used for creating methods that respond to events
public delegate void EventDelegate(UnityEngine.EventSystems.BaseEventData baseEvent);

然后,我们可以创建一个用于处理事件的方法,签名必须与我们的委托的签名匹配。因此,它需要返回void并接受BaseEventData作为其第一个也是唯一的参数:

public void DropEventMethod(UnityEngine.EventSystems.BaseEventData baseEvent) {
    Debug.Log(baseEvent.selectedObject.name + " triggered an event!");
    //baseEvent.selectedObject is the GameObject that triggered the event,
    // so we can access its components, destroy it, or do whatever.
}

最后,要动态添加事件:

//Get the event trigger attached to the UI object
EventTrigger eventTrigger = buttonObject.GetComponent<EventTrigger>();

//Create a new entry. This entry will describe the kind of event we're looking for
// and how to respond to it
EventTrigger.Entry entry = new EventTrigger.Entry();

//This event will respond to a drop event
entry.eventID = EventTriggerType.Drop;

//Create a new trigger to hold our callback methods
entry.callback = new EventTrigger.TriggerEvent();

//Create a new UnityAction, it contains our DropEventMethod delegate to respond to events
UnityEngine.Events.UnityAction<BaseEventData> callback =
    new UnityEngine.Events.UnityAction<BaseEventData>(DropEventMethod);

//Add our callback to the listeners
entry.callback.AddListener(callback);

//Add the EventTrigger entry to the event trigger component
eventTrigger.delegates.Add(entry);

如果您使用的是5.3.3或更高版本,请使用此行而不是上面的最后一行,代表已弃用

eventTrigger.triggers.Add(entry); 

看来,当您动态添加处理程序时,它似乎没有出现在检查器中。抽屉仍然显示代表的“空列表”
vexe 2014年

没错 从代码添加的处理程序与检查器中显示的“持久”处理程序是分开的;此外,您负责清理这些处理程序(与持久性处理程序不同,Unity会为您负责)。
乔·斯特劳

11

这个词是delegate{}我在上一个答案中找到的语法已过时,还有另一种使用lambda表示法的方法:

void buttonSetup(Button button) {
    //Remove the existing events
    button.onClick.RemoveAllListeners();
    //Add your new event using lambda notation
    button.onClick.AddListener (handleButton);
}

void handleButton() {
    Debug.Log("Button pressed!");
}

或者,您可以传递按钮使事情变得更加动态:

void buttonSetup(Button button) {
    button.onClick.RemoveAllListeners();
    //Add your new event
    button.onClick.AddListener(() => handleButton(button));
}

void handleButton(Button b) {
    Debug.Log("Button '" + b.name + "' pressed!");
}

请记住,此策略仅适用于OnClick事件。为了动态添加其他事件,您需要按照我的其他答案中的说明进行操作。
MichaelHouse

0

根据以下内容创建一个新脚本:

public class EventHandler : MonoBehaviour, IPointerClickHandler
{
    public void OnPointerClick(PointerEventData eventData)
    {
        Debug.Log("Element: " +
                   eventData.selectedObject.name +
                   " was clicked at " +
                   eventData.position.ToString());
    }
}

该脚本在IPointerClickHandler接口中实现(在许多其他可用接口中)。只需将此脚本附加到UI元素,即可使该脚本拦截点击事件(或实现接口的任何事件)。

下一步是简单地将此脚本作为组件动态添加到所需的UI元素:

myButton.AddComponent<EventHandler>();

这会将脚本作为一个组件添加到其中myButton,并且下次单击该按钮时,将获得有关单击哪个按钮以及单击发生位置的信息。

与我的其他答案相比,这提供了有关事件的最多信息。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.