欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Unity3D】UGUI组件的监听

程序员文章站 2022-07-12 23:33:58
...

组件的监听在各大编程语言中司空见惯,也就是这个组件一旦出现某种情况就执行某段函数。

在Unity3D中也不例外,在《【Unity3D】场景切换、UGUI组件事件、开始游戏与关闭游戏》(点击打开链接)与《【Unity3D】对话框、隐藏与显示、拖拽》(点击打开链接)之中,其实已经涉及到UGUI组件监听的大部分知识了,但是都是需要在Editor中经过一系列的设置才能让监听顺利进行。如何让UGUI组件的监听,完全写到脚本之中呢?也就是.cs文件直接包办好一切。下面将举三个基本来包揽大部分情况例子还说明这个问题。

【Unity3D】UGUI组件的监听

如上图,点击按钮,与文本框的值改变是基本事件的监听,而点击滚动条是一个非基本事件监听。

所谓的基本事件监听,则是可以Editor对这个组件进行设置的。如按钮的点击,输入框的值改变等。

【Unity3D】UGUI组件的监听

而非基本事件,则需要自己添加一个EventTrigger才可以进行监听的。如Panel的拖拽和这里的滚动条的添加等。

【Unity3D】UGUI组件的监听

一、UGUI组件基本事件监听

1、匿名委托调用,如下代码,则可以对按钮button1的点击进行监听。相信我也不用多说什么了,你就按照这个结构,进行你需要的修改,和安卓的点击事件一个意思。《【Android】利用Java代码布局,按钮添加点击事件》(点击打开链接)。

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class UIListener : MonoBehaviour
{
    public Text text1;
    public Button button1;

    void Start()
    {
        button1.onClick.RemoveAllListeners();//清楚之前的监听,以免冲突
        button1.onClick.AddListener(delegate()
        {
            text1.text = "按钮被点击";
        });
    }
}

2、lambda表达式转换为委托类型

如果你不像将监听的函数直接写在主类、主函数中,而且需要对监听另一起一个函数,让代码更好看,你可以这样写:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;


public class UIListener : MonoBehaviour
{

    public Text text1;
    public InputField inputField1;

    void Start()
    {
        inputField1.onValueChange.RemoveAllListeners();
        inputField1.onValueChange.AddListener((string value) => OnInputFieldValueChange(value));//value就是当前InputField的值
    }

    public void OnInputFieldValueChange(string value)
    {
        text1.text = "输入框的值变成为:" + value;
    }

}

说得lambda表达式好像很高大上似的。其实你也是按着上面的结构照改就行了。至于lambda表达式中要传递的值你可以这样看:

【Unity3D】UGUI组件的监听

二、UGUI组件非基本事件监听

注意到,Scrollbar滚动条原本的事件是值改变,但如果我想对其被点击的事件进行监听,那么原本按照道理,我们需要自行添加一个EventTrigger才可以进行监听的才能进行对其被点击的事件进行监听的。

【Unity3D】UGUI组件的监听

那么,如何纯代码进行实现这一切呢?你可以如下这样写:

using UnityEngine;
using UnityEngine.UI;//用到了UI
using System.Collections;
/*用到了EventTrigger*/
using UnityEngine.EventSystems;
using UnityEngine.Events;
using System.Collections.Generic;//用到了List

public class UIListener : MonoBehaviour
{

    public Text text1;
    public Scrollbar scrollbar1;

    void Start()
    {
        AddTriggersListener(scrollbar1.gameObject, EventTriggerType.PointerClick, ScrollbarOnPointerClick);
    }

    /*EventTriggle的组件创建,由于其创建代码过长,自行打包成一个函数*/
    private void AddTriggersListener(GameObject gameobject1, EventTriggerType eventID, UnityAction<BaseEventData> unityAction1)
    {//第一个参数是Unity3D的舞台对象GameObject,第二个参数是监听事件类型,最后一个是监听的回调函数

        /*看对象本身是否有EventTrigger这个组件,没则创建个*/
        EventTrigger trigger;
        if (gameobject1.GetComponent<EventTrigger>())
        {
            trigger = gameobject1.GetComponent<EventTrigger>();
        }
        else
        {
            trigger = gameobject1.AddComponent<EventTrigger>();
        }
        /*各种初始化EventTrigger动作,不用深究*/
        trigger.delegates = new List<EventTrigger.Entry>();
        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = eventID;//指定监听事件类型
        /*指明监听的回调函数*/
        entry.callback = new EventTrigger.TriggerEvent();
        UnityAction<BaseEventData> callback = new UnityAction<BaseEventData>(unityAction1);//
        entry.callback.AddListener(callback);
        trigger.delegates.Add(entry);
    }

    //Scrollbar的监听函数,其实就这一句而已
    public void ScrollbarOnPointerClick(BaseEventData baseEventData)
    {
        text1.text = "滚动条被点击";
    }

}

之所以弄得这么复杂,主要是大家注意到Unity3D,至少在这个还不算旧的4.x版本,对于UGUI这些非基本事件的监听,Unity3D是不像对于基本事件一样,直接留个已经封装好的结果给我们,所以我们要自己实现。

【Unity3D】UGUI组件的监听


以上就是UGUI的纯脚本实现监听的三大情况。


总结

因此,弄个空物体UIListener,附上以下脚本UIListener.cs,则能够实现上述的效果:

using UnityEngine;
using UnityEngine.UI;//用到了UI
using System.Collections;
/*用到了EventTrigger*/
using UnityEngine.EventSystems;
using UnityEngine.Events;
using System.Collections.Generic;//用到了List

public class UIListener : MonoBehaviour
{

    public Text text1;
    public Button button1;
    public InputField inputField1;
    public Scrollbar scrollbar1;

    void Start()
    {
        button1.onClick.RemoveAllListeners();//清除之前的监听,以免冲突
        button1.onClick.AddListener(delegate()
        {
            text1.text = "按钮被点击";
        });
        inputField1.onValueChange.RemoveAllListeners();
        inputField1.onValueChange.AddListener((string value) => OnInputFieldValueChange(value));//value就是当前InputField的值
        AddTriggersListener(scrollbar1.gameObject, EventTriggerType.PointerClick, ScrollbarOnPointerClick);
    }

    public void OnInputFieldValueChange(string value)
    {
        text1.text = "输入框的值变成为:" + value;
    }

    /*EventTriggle的组件创建,由于其创建代码过长,自行打包成一个函数*/
    private void AddTriggersListener(GameObject gameobject1, EventTriggerType eventID, UnityAction<BaseEventData> unityAction1)
    {//第一个参数是Unity3D的舞台对象GameObject,第二个参数是监听事件类型,最后一个是监听的回调函数

        /*看对象本身是否有EventTrigger这个组件,没则创建个*/
        EventTrigger trigger;
        if (gameobject1.GetComponent<EventTrigger>())
        {
            trigger = gameobject1.GetComponent<EventTrigger>();
        }
        else
        {
            trigger = gameobject1.AddComponent<EventTrigger>();
        }
        /*各种初始化EventTrigger动作,不用深究*/
        trigger.delegates = new List<EventTrigger.Entry>();
        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = eventID;//指定监听事件类型
        /*指明监听的回调函数*/
        entry.callback = new EventTrigger.TriggerEvent();
        UnityAction<BaseEventData> callback = new UnityAction<BaseEventData>(unityAction1);//
        entry.callback.AddListener(callback);
        trigger.delegates.Add(entry);
    }

    //Scrollbar的监听函数,其实就这一句而已
    public void ScrollbarOnPointerClick(BaseEventData baseEventData)
    {
        text1.text = "滚动条被点击";
    }

}

并在Editor指定好各个组件是啥。当然你可以纯粹在脚本通过GameObject.Find来指定各个对象是啥。

【Unity3D】UGUI组件的监听