• UGUI实现NGUI的UIEventListener功能


    在unity中处理UI事件时,习惯了使用NGUI的UIEventListener,虽然UGUI也有AddListener,但是一个组件只能对应一个函数,不能在一个函数中同时处理多个事件,显得有些麻烦

    因为主要平时Button用得比较多,这里以UGUI的Button为例,自己以UGUI的Button的AddListener模仿NGUI的UIEventListener做了一个小封装,能在一个函数处理多个Button

    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    
    public class UGUIButtonEventListener : MonoBehaviour {
    
        public delegate void VoidDelegate(GameObject go);
    
        public VoidDelegate onClick;
    
        public static UGUIButtonEventListener GetClick(Button btn)
        {
            UGUIButtonEventListener listener = btn.GetComponent<UGUIButtonEventListener>();
            if (listener == null)
                listener = btn.gameObject.AddComponent<UGUIButtonEventListener>();
            btn.onClick.AddListener(listener.OnClick);
            return listener;
        }
    
        void OnClick()
        {
            if (onClick != null)
                onClick(gameObject);
        }
    }
    测试代码:

    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    using UnityEngine.EventSystems;
    
    public class test : MonoBehaviour
    {
        public Button[] btns;
        void Start()
        {
            for (int i = 0; i < btns.Length; i++)
                UGUIButtonEventListener.Get(btns[i]).onClick = OnClick;
        }
        
        void OnClick(GameObject go)
        {
            print("name:"+go.name);
        }
    }

    还有人给了另一个Button事件监听的方法,感觉也挺好用

    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    using UnityEngine.EventSystems;
    
    public class test : MonoBehaviour
    {
        public Button[] btns;
        void Start()
        {
            for (int i = 0; i < btns.Length; i++)
    	{	
    	    GameObject btnObj=btns[i].gameObject;
    	    btns[i].onClick.AddListener(delegate(){OnClick(btnObj);});
    	}
        }
        
        void OnClick(GameObject go)
        {
            print("name:"+go.name);
        }
    }

    但是UI事件肯定不止Button的Click事件,如果所有事件都按照上面的方法来封装就显得有些杂乱了。所以自己再去看了看UGUI的一些事件接口,发现通过实现接口,就能封装了,比如IPointerClickHandler,可以实现Click事件,IPointerEnterHandler、IPointerExitHandler可以实现Hover事件。后来再在网上查了一些资料,发现了EventTrigger已经继承了所有接口,正好可以用来封装UIEventListener

    实现代码如下:

    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    using UnityEngine.EventSystems;
    
    public class UGUIEventListener:EventTrigger
    {
        public delegate void VoidDelegate(GameObject go);
        public delegate void BoolDelegate(GameObject go, bool isValue);
        public delegate void FloatDelegate(GameObject go, float fValue);
        public delegate void IntDelegate(GameObject go, int iIndex);
        public delegate void StringDelegate(GameObject go, string strValue);
    
        public VoidDelegate onSubmit;
        public VoidDelegate onClick;
        public BoolDelegate onHover;
        public BoolDelegate onToggleChanged;
        public FloatDelegate onSliderChanged;
        public FloatDelegate onScrollbarChanged;
        public IntDelegate onDrapDownChanged;
        public StringDelegate onInputFieldChanged;
    
        public override void OnSubmit(BaseEventData eventData)
        {
            if (onSubmit != null)
                onSubmit(gameObject);
        }
        public override void OnPointerEnter(PointerEventData eventData)
        {
            if (onHover != null)
                onHover(gameObject, true);
        }
        public override void OnPointerClick(PointerEventData eventData)
        {
            if (onClick != null)
                onClick(gameObject);
            if (onToggleChanged != null)
                onToggleChanged(gameObject, gameObject.GetComponent<Toggle>().isOn);
    
        }
        public override void OnPointerExit(PointerEventData eventData)
        {
            if (onHover != null)
                onHover(gameObject, false);
        }
        public override void OnDrag(PointerEventData eventData)
        {
            if (onSliderChanged != null)
                onSliderChanged(gameObject, gameObject.GetComponent<Slider>().value);
            if (onScrollbarChanged != null)
                onScrollbarChanged(gameObject, gameObject.GetComponent<Scrollbar>().value);
    
        }
        public override void OnSelect(BaseEventData eventData)
        {
            if (onDrapDownChanged != null)
                onDrapDownChanged(gameObject, gameObject.GetComponent<Dropdown>().value);
        }
        public override void OnUpdateSelected(BaseEventData eventData)
        {
            if (onInputFieldChanged != null)
                onInputFieldChanged(gameObject, gameObject.GetComponent<InputField>().text);
        }
        public override void OnDeselect(BaseEventData eventData)
        {
            if (onInputFieldChanged != null)
                onInputFieldChanged(gameObject, gameObject.GetComponent<InputField>().text);
        }
    
        public static UGUIEventListener Get(GameObject go)
        {
            UGUIEventListener listener =go.GetComponent<UGUIEventListener>();
            if(listener==null) listener=go.AddComponent<UGUIEventListener>();
            return listener;
        }
    }

    测试代码如下:
    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    using UnityEngine.EventSystems;
    
    public class test : MonoBehaviour
    {
        public Button[] btns;
        public Scrollbar scrollbar;
        void Start()
        {
            for (int i = 0; i < btns.Length; i++)
                UGUIEventListener.Get(btns[i].gameObject).onClick = OnClick;
            UGUIEventListener.Get(scrollbar.gameObject).onScrollbarChanged = OnScrollbarChanged;
        }
        
        void OnClick(GameObject go)
        {
            print("name:"+go.name);
        }
    
        void OnScrollbarChanged(GameObject go, float value)
        {
            print("name:" + go.name + "  value:" + value);
        }
    }

    最后,还有一个小东西,因为自己在做一些测试的时候,发现UGUI的点击事件与3D物体的射线碰撞,是会发生冲突的,理论上,自己在点击UI的时候,3D物体的射线碰撞检测就会取消,不能让他们同时响应,这里用一个函数就可以判断EventSystem.current.IsPointerOverGameObject()

    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    using UnityEngine.EventSystems;
    
    public class test : MonoBehaviour
    {
        void Update()
        {
    	if (EventSystem.current.IsPointerOverGameObject())
    		Debug.Log("鼠标在UI上");
    	else
    		Debug.Log("鼠标没在UI上");
        }
    }
  • 相关阅读:
    @PathVariable和@RequestParam的区别,@SessionAttributes
    forward和redirect的区别
    JSP页面的静态包含和动态包含
    ConcurrentHashMap源码解析
    Jdk1.6 JUC源码解析(1)-atomic-AtomicXXX
    最小生成树
    tomcat启动项目内存溢出问题
    强引用,弱引用,4种Java引用浅解(涉及jvm垃圾回收)
    CXF 在WAS上报Unmarshalling Error的问题
    CXF处理Date类型的俩种方式
  • 原文地址:https://www.cnblogs.com/liang123/p/6325899.html
Copyright © 2020-2023  润新知