【Unity3D】UGUI组件的监听
组件的监听在各大编程语言中司空见惯,也就是这个组件一旦出现某种情况就执行某段函数。
在Unity3D中也不例外,在《【Unity3D】场景切换、UGUI组件事件、开始游戏与关闭游戏》(点击打开链接)与《【Unity3D】对话框、隐藏与显示、拖拽》(点击打开链接)之中,其实已经涉及到UGUI组件监听的大部分知识了,但是都是需要在Editor中经过一系列的设置才能让监听顺利进行。如何让UGUI组件的监听,完全写到脚本之中呢?也就是.cs文件直接包办好一切。下面将举三个基本来包揽大部分情况例子还说明这个问题。
如上图,点击按钮,与文本框的值改变是基本事件的监听,而点击滚动条是一个非基本事件监听。
所谓的基本事件监听,则是可以Editor对这个组件进行设置的。如按钮的点击,输入框的值改变等。
而非基本事件,则需要自己添加一个EventTrigger才可以进行监听的。如Panel的拖拽和这里的滚动条的添加等。
一、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表达式中要传递的值你可以这样看:
二、UGUI组件非基本事件监听
注意到,Scrollbar滚动条原本的事件是值改变,但如果我想对其被点击的事件进行监听,那么原本按照道理,我们需要自行添加一个EventTrigger才可以进行监听的才能进行对其被点击的事件进行监听的。
那么,如何纯代码进行实现这一切呢?你可以如下这样写:
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是不像对于基本事件一样,直接留个已经封装好的结果给我们,所以我们要自己实现。
以上就是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--碰撞检测(一)
下一篇: Unity3D UGUI原理分析