【Unity3D】UGUI组件的监听

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

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

【Unity3D】UGUI组件的监听_第1张图片

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

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

【Unity3D】UGUI组件的监听_第2张图片

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

【Unity3D】UGUI组件的监听_第3张图片

一、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组件的监听_第4张图片

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

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

【Unity3D】UGUI组件的监听_第5张图片

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

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 unityAction1)
    {//第一个参数是Unity3D的舞台对象GameObject,第二个参数是监听事件类型,最后一个是监听的回调函数

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

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

}

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

【Unity3D】UGUI组件的监听_第6张图片


以上就是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 unityAction1)
    {//第一个参数是Unity3D的舞台对象GameObject,第二个参数是监听事件类型,最后一个是监听的回调函数

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

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

}

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

【Unity3D】UGUI组件的监听_第7张图片

你可能感兴趣的:(Unity3D)