UGUI点击事件使用的是UIEventListener方式,通过继承接口IPointerClickHandler,IPointerDownHandler。。。等来实现点击,移动效果。这里稍稍做了一下修改,可以实现一个物体实现多种效果,即可以点击,又可以移动。废话不多说,直接上代码。
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using System.Collections.Generic;
using UnityEngine.UI;
using System;
public delegate void VoidDelegate(GameObject go, PointerEventData data);
public delegate void VoidDelegateEx(GameObject go, PointerEventData data, params object[] args);
public delegate void VoidCollisionDelegate(Collision2D coll, PointerEventData data); //用于碰撞的
/*
*为减少同时多事件注册后覆盖原本引擎事件导致的失效
*用法与原有方法一样,无需任何变动
*每个注册事件只挂载对应的关联事件
*如需要多个事件同时注册那同时注册即可
*注意点:
*当前的注册事件只能获取当前注册事件的Data内容
*如:onClick注册事件 的Data回调内部不包含drag事件,反之一样
*/
public class UIEventListener : MonoBehaviour
{
#region 定义
public VoidDelegate onClick
{
get
{
return m_onClick;
}
set
{
m_onClick = value;
UIEventPointerClick uie = transform.GetComponent() ? transform.GetComponent() : transform.gameObject.AddComponent();
uie.onClick = m_onClick;
}
}
public VoidDelegate onPress
{
get
{
return m_onPress;
}
set
{
m_onPress = value;
UIEventPointerDown uie = transform.GetComponent<UIEventPointerDown>() ? transform.GetComponent<UIEventPointerDown>() : transform.gameObject.AddComponent<UIEventPointerDown>();
uie.onPress = m_onPress;
}
}
public VoidDelegate onBeginDrag
{
get
{
return m_onBeginDrag;
}
set
{
m_onBeginDrag = value;
UIEventPointerDrop uie = transform.GetComponent<UIEventPointerDrop>() ? transform.GetComponent<UIEventPointerDrop>() : transform.gameObject.AddComponent<UIEventPointerDrop>();
uie.onBeginDrag = m_onBeginDrag;
}
}
public VoidDelegate onDrag
{
get
{
return m_onDrag;
}
set
{
m_onDrag = value;
UIEventPointerDrop uie = transform.GetComponent<UIEventPointerDrop>() ? transform.GetComponent<UIEventPointerDrop>() : transform.gameObject.AddComponent<UIEventPointerDrop>();
uie.onDrag = m_onDrag;
}
}
public VoidDelegate onEndDrag
{
get
{
return m_onEndDrag;
}
set
{
m_onEndDrag = value;
UIEventPointerDrop uie = transform.GetComponent<UIEventPointerDrop>() ? transform.GetComponent<UIEventPointerDrop>() : transform.gameObject.AddComponent<UIEventPointerDrop>();
uie.onEndDrag = m_onEndDrag;
}
}
public VoidDelegate onDrop
{
get
{
return m_onDrop;
}
set
{
m_onDrop = value;
UIEventPointerDrop uie = transform.GetComponent<UIEventPointerDrop>() ? transform.GetComponent<UIEventPointerDrop>() : transform.gameObject.AddComponent<UIEventPointerDrop>();
uie.onDrop = m_onDrop;
}
}
public VoidDelegate onPointerUp
{
get
{
return m_onPointerUp;
}
set
{
m_onPointerUp = value;
UIEventPointerUp uie = transform.GetComponent<UIEventPointerUp>() ? transform.GetComponent<UIEventPointerUp>() : transform.gameObject.AddComponent<UIEventPointerUp>();
uie.onPointerUp = m_onPointerUp;
}
}
public VoidDelegate onPointerEnter
{
get
{
return m_onPointerEnter;
}
set
{
m_onPointerEnter = value;
UIEventPointerEnter uie = transform.GetComponent<UIEventPointerEnter>() ? transform.GetComponent<UIEventPointerEnter>() : transform.gameObject.AddComponent<UIEventPointerEnter>();
uie.onPointerEnter = m_onPointerEnter;
}
}
public VoidDelegate onPointerExit
{
get
{
return m_onPointerExit;
}
set
{
m_onPointerExit = value;
UIEventPointerExite uie = transform.GetComponent<UIEventPointerExite>() ? transform.GetComponent<UIEventPointerExite>() : transform.gameObject.AddComponent<UIEventPointerExite>();
uie.onPointerExite = m_onPointerExit;
}
}
public VoidDelegateEx onDropEx
{
get
{
return m_onDropEx;
}
set
{
m_onDropEx = value;
UIEventPointerDrop uie = transform.GetComponent<UIEventPointerDrop>() ? transform.GetComponent<UIEventPointerDrop>() : transform.gameObject.AddComponent<UIEventPointerDrop>();
uie.onDropEx = m_onDropEx;
}
}
public VoidDelegate onTrigger
{
get
{
return m_onTrigger;
}
set
{
m_onTrigger = value;
}
}
public VoidDelegate onTriggerExit
{
get
{
return m_onTriggerExit;
}
set
{
m_onTriggerExit = value;
}
}
public VoidCollisionDelegate onCollisionEnter2d
{
get
{
return m_onCollisionEnter;
}
set
{
m_onCollisionEnter = value;
}
}
public VoidCollisionDelegate onCollisionStay2d
{
get
{
return m_onCollisionStay;
}
set
{
m_onCollisionStay = value;
}
}
public VoidCollisionDelegate onCollisionExit2d
{
get
{
return m_onCollisionExit;
}
set
{
m_onCollisionExit = value;
}
}
private VoidDelegate m_onClick;
private VoidDelegate m_onPress;
private VoidDelegate m_onBeginDrag;
private VoidDelegate m_onDrag;
private VoidDelegate m_onEndDrag;
private VoidDelegate m_onDrop;
private VoidDelegate m_onPointerUp;
private VoidDelegate m_onTrigger;
private VoidDelegate m_onTriggerExit;
private VoidDelegate m_onPointerEnter;
private VoidDelegate m_onPointerExit;
private VoidDelegateEx m_onDropEx;
private VoidCollisionDelegate m_onCollisionEnter;
private VoidCollisionDelegate m_onCollisionStay;
private VoidCollisionDelegate m_onCollisionExit;
#endregion
public static UIEventListener Get(GameObject go)
{
//之前可能将该组件上的RayCast给关闭了,这里重新启用
Image image = go.GetComponent<Image>();
if (image != null && !image.raycastTarget) image.raycastTarget = true;
UIEventListener listener = go.GetComponent<UIEventListener>();
if (listener == null) listener = go.AddComponent<UIEventListener>();
return listener;
}
//移除物体上的控件
public static void RemoveListener(GameObject go)
{
UIEventListener listener = go.GetComponent<UIEventListener>();
if (listener != null) GameObject.Destroy(listener);
UIEventPointerClick listener2 = go.GetComponent<UIEventPointerClick>();
if (listener2 != null) GameObject.Destroy(listener2);
UIEventPointerDown listener3 = go.GetComponent<UIEventPointerDown>();
if (listener3 != null) GameObject.Destroy(listener3);
UIEventPointerUp listener4 = go.GetComponent<UIEventPointerUp>();
if (listener4 != null) GameObject.Destroy(listener4);
UIEventPointerEnter listener5 = go.GetComponent<UIEventPointerEnter>();
if (listener5 != null) GameObject.Destroy(listener5);
UIEventPointerExite listener6 = go.GetComponent<UIEventPointerExite>();
if (listener6 != null) GameObject.Destroy(listener6);
UIEventPointerDrop listener7 = go.GetComponent<UIEventPointerDrop>();
if (listener7 != null) GameObject.Destroy(listener7);
}
public static void RemoveListener(Transform parent)
{
if (parent == null) return;
for (int i = 0; i < parent.transform.childCount; ++i)
{
RemoveListener(parent.GetChild(i).gameObject);
}
}
//一次性移除该物体下所有子物体的控件
public static void RemoveAllChildListener(Transform parent)
{
if (parent == null) return;
UIEventListener[] listeners = parent.GetComponentsInChildren<UIEventListener>();
for (int i = 0; i < listeners.Length; ++i)
{
GameObject.DestroyImmediate(listeners[i]);
}
//2018.11.25日后,点击事件重写,需要将UIEventPointerClick脚本也要干掉
UIEventPointerClick[] pointers = parent.GetComponentsInChildren<UIEventPointerClick>();
for (int i = 0; i < pointers.Length; ++i)
{
GameObject.DestroyImmediate(pointers[i]);
}
//为了不修改之前的功能,上面的代码不注释,新增下面的代码
for(int i=0;i< parent.childCount;++i)
{
RemoveListener(parent.GetChild(i));
}
}
//仅仅移除已经注册的事件,单并不移除UIEventListener控件
public static void RemoveEvent(VoidDelegate myDelegate)
{
if (myDelegate != null) myDelegate = null;
}
//禁用物体的触发器2D
public static void BanTrigger(GameObject go, bool isCanAccepEvent = false)
{
if (go == null) return;
BoxCollider2D box2D = go.GetComponent<BoxCollider2D>();
if (box2D != null)
{
box2D.enabled = isCanAccepEvent;
}
}
//暂时禁用这个物体的点击,可拖动事件
public static void BanEvent(GameObject go, bool isCanAccepEvent = false)
{
if (go == null) return;
Image image = go.GetComponent<Image>();
Text text = go.GetComponent<Text>();
if (image != null)
{
image.raycastTarget = isCanAccepEvent;
}
if (text != null)
{
text.raycastTarget = isCanAccepEvent;
}
}
//禁用/开启这个脚本,通常使用上面那个,遇到DoTween时,如果禁用Raycast也能接受点击,则使用这个禁用
public static void BanLisener(GameObject go, bool isCanAccepEvent = false)
{
if (go == null)
{
return;
}
BanEvent(go, isCanAccepEvent);
UIEventListener lister = go.GetComponent<UIEventListener>();
if (lister != null)
{
lister.enabled = isCanAccepEvent;
}
//新增
UIEventPointerClick point = go.GetComponent<UIEventPointerClick>();
if (point != null)
{
point.enabled = isCanAccepEvent;
}
UIEventPointerDrop drop = go.GetComponent<UIEventPointerDrop>();
if (drop != null)
{
drop.enabled = isCanAccepEvent;
}
}
//批量绑定界面上的按钮
public static void BindClick(GameObject uiPrefab, VoidDelegate onButtonClick)
{
UIEventListener[] btns = uiPrefab.transform.GetComponentsInChildren<UIEventListener>();
for (int i = 0; i < btns.Length; ++i)
{
Get(btns[i].gameObject).onClick = onButtonClick;
}
}
//批量绑定集合中的按钮
public static void BindClick(List<GameObject> uiBtnList, VoidDelegate onButtonClick)
{
for (int i = 0; i < uiBtnList.Count; ++i)
{
Get(uiBtnList[i].gameObject).onClick = onButtonClick;
}
}
public static void BindClick(Transform btnParent, VoidDelegate onButtonClick)
{
for (int i = 0; i < btnParent.childCount; ++i)
{
Get(btnParent.GetChild(i).gameObject).onClick = onButtonClick;
}
}
//批量关闭所有的子物体的点击事件
public static void BanAllChildClick(Transform btnParent, bool isCan = false)
{
for (int i = 0; i < btnParent.childCount; ++i)
{
BanEvent(btnParent.GetChild(i).gameObject, isCan);
}
}
//批量绑定可拖动物体,松手时检测
public static void BindOnDrop(Transform btnParent, VoidDelegate itemDrop)
{
for (int i = 0; i < btnParent.childCount; ++i)
{
Get(btnParent.GetChild(i).gameObject).onDrop = itemDrop;
}
}
//批量绑定课拖动物体,移动
public static void BindOnDrag(Transform btnParent, VoidDelegate itemDrag)
{
for (int i = 0; i < btnParent.childCount; ++i)
{
Get(btnParent.GetChild(i).gameObject).onDrag = itemDrag;
}
}
public static void BindOnBeginDrag(Transform btnParent, VoidDelegate itemBeginDrag)
{
for (int i = 0; i < btnParent.childCount; ++i)
{
Get(btnParent.GetChild(i).gameObject).onBeginDrag = itemBeginDrag;
}
}
public void OnTriggerEnter2D(Collider2D coll)
{
if (onTrigger != null) onTrigger(coll.gameObject, null);
}
public void OnTriggerExit2D(Collider2D coll)
{
if (onTriggerExit != null) onTriggerExit(coll.gameObject, null);
}
public void OnCollisionEnter2D(Collision2D coll)
{
if (onCollisionEnter2d != null) onCollisionEnter2d(coll, null);
}
public void OnCollisionStay2D(Collision2D coll)
{
if (onCollisionStay2d != null) onCollisionStay2d(coll, null);
}
public void OnCollisionExit2D(Collision2D coll)
{
if (onCollisionExit2d != null) onCollisionExit2d(coll, null);
}
#region
/*
public override void OnPointerClick(PointerEventData eventData)
{
if (onClick != null) onClick(gameObject, eventData);
}
public override void OnPointerDown(PointerEventData eventData)
{
if (onPress != null) onPress(gameObject, eventData);
}
public override void OnPointerUp(PointerEventData eventData)
{
if (onPointerUp != null) onPointerUp(gameObject, eventData);
}
public override void OnBeginDrag(PointerEventData eventData)
{
if (onBeginDrag != null) onBeginDrag(gameObject, eventData);
}
public override void OnDrag(PointerEventData eventData)
{
if (onDrag != null) onDrag(gameObject, eventData);
}
public override void OnEndDrag(PointerEventData eventData)
{
if (onEndDrag != null) onEndDrag(gameObject, eventData);
//自定义封装的ondrop
PointerEventData currentSystem = new PointerEventData(EventSystem.current);
currentSystem.position = Input.mousePosition;
currentSystem.pressPosition = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(currentSystem, results);
if (onDrop != null) onDrop(results.Count > 1 ? results[1].gameObject : null, eventData);
if (onDropEx != null) onDropEx(results.Count > 1 ? results[1].gameObject : null, eventData, results);
}
public override void OnPointerEnter(PointerEventData eventData)
{
if (onPointerEnter != null) onPointerEnter(gameObject, eventData);
}
public override void OnPointerExit(PointerEventData eventData)
{
if (onPointerExit != null) onPointerExit(gameObject, eventData);
}
**/
#endregion
#region 标志位
private int m_iData = 0;
private int m_iData1 = 0;
private string m_strData = null;
private string m_strData1 = null;
public int IData
{
get
{
return m_iData;
}
set
{
m_iData = value;
}
}
public int IData1
{
get
{
return m_iData1;
}
set
{
m_iData1 = value;
}
}
public string StrData
{
get
{
return m_strData;
}
set
{
m_strData = value;
}
}
public string StrData1
{
get
{
return m_strData1;
}
set
{
m_strData1 = value;
}
}
//存放图片,用于UI制作,动态切换图片,不用使用属性,否则Inspector面板不显示
public List<Sprite> Images;
#endregion
}
#region 对应单个注册事件
public class UIEventPointerClick : MonoBehaviour, IPointerClickHandler
{
public VoidDelegate onClick;
public void OnPointerClick(PointerEventData eventData)
{
if (onClick != null)
{
onClick(gameObject, eventData);
UIEventListener iData = gameObject.GetComponent<UIEventListener>();
if (iData == null)
{
return;
}
//记录备注参数
string param = string.IsNullOrEmpty(iData.StrData) ? "" : iData.StrData;
string element = string.IsNullOrEmpty(iData.StrData1) ? "" : iData.StrData1;
ClientDataCollection.Instance.AddHandle(param, element);
}
}
}
public class UIEventPointerDown : MonoBehaviour, IPointerDownHandler
{
public VoidDelegate onPress;
public void OnPointerDown(PointerEventData eventData)
{
if (onPress != null) onPress(gameObject, eventData);
}
}
public class UIEventPointerUp : MonoBehaviour, IPointerUpHandler
{
public VoidDelegate onPointerUp;
public void OnPointerUp(PointerEventData eventData)
{
if (onPointerUp != null) onPointerUp(gameObject, eventData);
}
}
public class UIEventPointerEnter : MonoBehaviour, IPointerEnterHandler
{
public VoidDelegate onPointerEnter;
public void OnPointerEnter(PointerEventData eventData)
{
if (onPointerEnter != null) onPointerEnter(gameObject, eventData);
}
}
public class UIEventPointerExite : MonoBehaviour, IPointerExitHandler
{
public VoidDelegate onPointerExite;
public void OnPointerExit(PointerEventData eventData)
{
if (onPointerExite != null) onPointerExite(gameObject, eventData);
}
}
public class UIEventPointerDrop : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public VoidDelegate onBeginDrag;
public VoidDelegate onDrag;
public VoidDelegate onEndDrag;
public VoidDelegate onDrop;
public VoidDelegateEx onDropEx;
public void OnBeginDrag(PointerEventData eventData)
{
if (onBeginDrag != null) onBeginDrag(gameObject, eventData);
}
public void OnDrag(PointerEventData eventData)
{
if (onDrag != null) onDrag(gameObject, eventData);
}
public void OnEndDrag(PointerEventData eventData)
{
if (onEndDrag != null) onEndDrag(gameObject, eventData);
//自定义封装的ondrop
PointerEventData currentSystem = new PointerEventData(EventSystem.current);
currentSystem.position = Input.mousePosition;
currentSystem.pressPosition = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(currentSystem, results);
if (onDrop != null) onDrop(results.Count > 1 ? results[1].gameObject : null, eventData);
if (onDropEx != null) onDropEx(results.Count > 1 ? results[1].gameObject : null, eventData, results);
}
}
#endregion