【UGUI】屏幕区域点击检测
来源:互联网 发布:淘宝上的原创女装品牌 编辑:程序博客网 时间:2024/05/19 10:09
此处直接代码:
using System.Collections;using System.Collections.Generic;using UnityEngine;namespace Asstes.UI{ /// <summary> /// Introduction: 屏幕区域点击判断 /// Author: /// Time: /// </summary> public class AreaClick { private static AreaClick m_instance; public static AreaClick Instance { get { if (m_instance == null) m_instance = new AreaClick(); return m_instance; } } private int m_index; private List<AreaRect> m_rects; private List<AreaRect> m_removes; private List<int> m_deletes; public AreaClick() { m_index = 0; m_rects = new List<AreaRect>(); m_removes = new List<AreaRect>(); m_deletes = new List<int>(); InputManager.Instance.AddListener(InputType.OnClick, OnClickScreen); InputManager.Instance.AddListener(InputType.OnEndLongPress, OnClickScreen); } private void OnClickScreen(Vector2 param) { m_removes.Clear(); for (int i = 0; i < m_rects.Count; i++)//移除已删除的点 { if(m_deletes.Contains(m_rects[i].id)) m_removes.Add(m_rects[i]); } for (int i = 0; i < m_removes.Count; i++) { m_rects.Remove(m_removes[i]); } m_deletes.Clear(); for (int i = 0; i < m_rects.Count; i++) { m_rects[i].OnClick(param); } } /// <summary> /// 添加检测 /// </summary> /// <param name="area"></param> /// <returns></returns> public int AddCheck(AreaRect area) { area.id = m_index++; m_rects.Add(area); return area.id; } /// <summary> /// 移除检测 /// </summary> /// <param name="id"></param> public void CancelCheck(int id) { if(!m_deletes.Contains(id)) m_deletes.Add(id); } } public class AreaRect { private Rect m_rect; private bool m_allNotice; private bool m_onlyOnce; private Callback_1<bool> m_callback; internal int id; /// <summary> /// 是否只使用一次 /// </summary> public bool UseOnce { get { return m_onlyOnce; } set { m_onlyOnce = value; } } /// <summary> /// 普通构造函数 /// </summary> /// <param name="rect">在屏幕上的区域</param> /// <param name="allNotice">通知点中和未点中</param> /// <param name="callback">回调</param> public AreaRect(Rect rect, bool allNotice, Callback_1<bool> callback) { m_rect = rect; m_allNotice = allNotice; m_callback = callback; } /// <summary> /// 可缩放区域 /// </summary> /// <param name="rect">设计时所选区域,如UI设计时的rect</param> /// <param name="designSize">UI设计时屏幕分辨率</param> /// <param name="allNotice">通知点中和未点中</param> /// <param name="callback">回调</param> public AreaRect(Rect rect, Vector2 designSize, bool allNotice, Callback_1<bool> callback) { float sx = Screen.width/designSize.x; float sy = Screen.height/designSize.y; Rect newRect = new Rect() { x = rect.x*sx, y = rect.y*sy, width = rect.width*sx, height = rect.height*sy }; m_rect = newRect; m_allNotice = allNotice; m_callback = callback; } /// <summary> /// UI区域 /// </summary> /// <param name="transform">RectTransform</param> /// <param name="allNotice">通知点中和未点中</param> /// <param name="callback">回调</param> public AreaRect(Transform transform, bool allNotice, Callback_1<bool> callback) { RectTransform rectTransform = transform as RectTransform; /*m_rect = rectTransform.rect; //没有考虑到缩放问题,当缩放后rect的长宽并未改变 m_rect.center = rectTransform.position;*/ //没有考虑到中心点影响,center并非world position float w = rectTransform.sizeDelta.x * rectTransform.lossyScale.x;//消除缩放影响 float h = rectTransform.sizeDelta.y * rectTransform.localScale.y; float x = rectTransform.position.x - rectTransform.pivot.x * w; //消除中心点并非pivot非(0.5,0.5)影响 float y = rectTransform.position.y - rectTransform.pivot.y * h; m_rect.center = new Vector2(x, y); m_rect.width = w; m_rect.height = h; m_allNotice = allNotice; m_callback = callback; } /// <summary> /// 是否在区域中 /// </summary> /// <param name="pos"></param> /// <returns></returns> public bool IsContain(Vector3 pos) { return m_rect.Contains(pos); } public void OnClick(Vector2 pos) { if (IsContain(pos)) { m_callback(true); if(m_onlyOnce) AreaClick.Instance.CancelCheck(id); } else if(m_allNotice) { m_callback(false); } } }}
其中InputManager是我自己实现的一个在多平台上判断点击事件的工具,
InputManager.Instance.AddListener(InputType.OnClick, OnClickScreen);InputManager.Instance.AddListener(InputType.OnEndLongPress, OnClickScreen);可直接用
Input.GetMouseButtonDown(0) 和Input.GetTouch(0)***************代替判断
一个很平常的需求、点击空白处关闭界面,以前自己的做法是给它做个全透明的图片托底(当时自己也没有想其他方法),当判断到点击是图片后关闭。但最近时遇到一个不能用这个方法的,因为你不能遮住其他的UI点击事件,故写了个工具,并做了个小扩展,目前只支持矩形区域的硬检测。目前可用到所有的屏幕区域检测和RectTransform检测。
由于最近用到在拖动时,如果在某个区域则相应拖动事件,如果超过这个区域则停止移动,于是改了一下代码:
using System.Collections;using System.Collections.Generic;using UnityEngine;namespace Assets.UI{ /// <summary> /// Introduction: 屏幕区域点击移动判断 /// Author: Cheng /// Time: /// </summary> public class AreaCheck { private static AreaCheck m_instance; public static AreaCheck Instance { get { if (m_instance == null) m_instance = new AreaCheck(); return m_instance; } } private int m_index; private List<AreaRect> m_rects; private List<AreaRect> m_removes; private List<int> m_deletes; public AreaCheck() { m_index = 0; m_rects = new List<AreaRect>(); m_removes = new List<AreaRect>(); m_deletes = new List<int>(); InputManager.Instance.AddListener(InputType.OnTouchBegin, OnTouchBegin); InputManager.Instance.AddListener(InputType.OnMoveBegin, OnMoveBrgin); InputManager.Instance.AddListener(InputType.OnMove, OnMove); InputManager.Instance.AddListener(InputType.OnMoveEnd, OnMoveEnd); InputManager.Instance.AddListener(InputType.OnClick, OnClickScreen); InputManager.Instance.AddListener(InputType.OnEndLongPress, OnClickScreen); } private void OnTouchBegin(Vector2 param) { m_removes.Clear(); for (int i = 0; i < m_rects.Count; i++)//移除已删除的点 { if (m_deletes.Contains(m_rects[i].id)) m_removes.Add(m_rects[i]); } for (int i = 0; i < m_removes.Count; i++) { m_rects.Remove(m_removes[i]); } m_deletes.Clear(); } private void OnClickScreen(Vector2 param) { for (int i = 0; i < m_rects.Count; i++) { m_rects[i].OnClick(param); } } private void OnMoveBrgin(Vector2 param) { for (int i = 0; i < m_rects.Count; i++) { m_rects[i].OnMoveBegin(param); } } private void OnMove(Vector2 param) { for (int i = 0; i < m_rects.Count; i++) { m_rects[i].OnMove(param); } } private void OnMoveEnd(Vector2 param) { for (int i = 0; i < m_rects.Count; i++) { m_rects[i].OnMoveEnd(param); } } /**********因lua重载的callback只检测luafunction,改重载为重命名 T_T ************************/ public int AddClickCheckRect(Rect rect, bool noticeAll, Callback_1<bool> callback) { AreaRect area = new AreaRect(rect) { CheckClick = true, ClickAllNotice = noticeAll, ClickCallback = callback }; return AddCheck(area); } public int AddClickCheckResizeRect(Rect rect, Vector2 designSize, bool noticeAll, Callback_1<bool> callback) { AreaRect area = new AreaRect(rect, designSize) { CheckClick = true, ClickAllNotice = noticeAll, ClickCallback = callback }; return AddCheck(area); } public int AddClickCheckTransform(Transform transform, bool noticeAll, Callback_1<bool> callback) { AreaRect area = new AreaRect(transform) { CheckClick = true, ClickAllNotice = noticeAll, ClickCallback = callback }; return AddCheck(area); } public int AddMoveCheckRect(Rect rect, bool outOnEnd, Callback_1<Vector2> begin, Callback_1<Vector2> move, Callback_1<Vector2> end) { AreaRect area = new AreaRect(rect) { CheckMove = true, EndOnOut = outOnEnd, MoveBeginCallback = begin, MoveCallback = move, MoveEndCallback = end }; return AddCheck(area); } public int AddMoveCheckResizeRect(Rect rect, Vector2 designSize, bool outOnEnd, Callback_1<Vector2> begin, Callback_1<Vector2> move, Callback_1<Vector2> end) { AreaRect area = new AreaRect(rect, designSize) { CheckMove = true, EndOnOut = outOnEnd, MoveBeginCallback = begin, MoveCallback = move, MoveEndCallback = end }; return AddCheck(area); } public int AddMoveCheckTransform(Transform transform, bool outOnEnd, Callback_1<Vector2> begin, Callback_1<Vector2> move, Callback_1<Vector2> end) { AreaRect area = new AreaRect(transform) { CheckMove = true, EndOnOut = outOnEnd, MoveBeginCallback = begin, MoveCallback = move, MoveEndCallback = end }; return AddCheck(area); } /// <summary> /// 添加检测 /// </summary> /// <param name="area"></param> /// <returns></returns> [LuaInterface.NoToLua] public int AddCheck(AreaRect area) { area.id = m_index++; m_rects.Add(area); return area.id; } /// <summary> /// 移除检测 /// </summary> /// <param name="id"></param> public void CancelCheck(int id) { if(!m_deletes.Contains(id)) m_deletes.Add(id); } } public class AreaRect { private Rect m_rect; private bool moving; internal int id; /// <summary> /// 鼠标移动时移除即结束 /// </summary> public bool EndOnOut{ get; set; } /// <summary> /// 通知点中和未点中 /// </summary> public bool ClickAllNotice { get; set; } /// <summary> /// 检测点击 /// </summary> public bool CheckClick { get; set; } /// <summary> /// 检测移动 /// </summary> public bool CheckMove { get; set; } /// <summary> /// 点击回调 /// </summary> public Callback_1<bool> ClickCallback; /// <summary> /// 移动结束回调 /// </summary> public Callback_1<Vector2> MoveBeginCallback; /// <summary> /// 移动回调 /// </summary> public Callback_1<Vector2> MoveCallback; /// <summary> /// 移动结束回调 /// </summary> public Callback_1<Vector2> MoveEndCallback; /// <summary> /// 普通构造函数 /// </summary> /// <param name="rect">在屏幕上的区域</param> public AreaRect(Rect rect) { m_rect = rect; } /// <summary> /// 可缩放区域 /// </summary> /// <param name="rect">设计时所选区域,如UI设计时的rect</param> /// <param name="designSize">UI设计时屏幕分辨率</param> public AreaRect(Rect rect, Vector2 designSize) { float sx = Screen.width/designSize.x; float sy = Screen.height/designSize.y; Rect newRect = new Rect() { x = rect.x*sx, y = rect.y*sy, width = rect.width*sx, height = rect.height*sy }; m_rect = newRect; } /// <summary> /// UI区域 /// </summary> /// <param name="transform">RectTransform</param> public AreaRect(Transform transform) { RectTransform rectTransform = transform as RectTransform; /*m_rect = rectTransform.rect; //没有考虑到缩放问题,当缩放后rect的长宽并未改变 m_rect.center = rectTransform.position;*/ //没有考虑到中心点影响,center并非world position float w = rectTransform.sizeDelta.x * rectTransform.lossyScale.x;//消除缩放影响 float h = rectTransform.sizeDelta.y * rectTransform.localScale.y; float x = rectTransform.position.x - rectTransform.pivot.x * w; //消除中心点并非pivot非(0.5,0.5)影响 float y = rectTransform.position.y - rectTransform.pivot.y * h; m_rect.center = new Vector2(x, y); m_rect.width = w; m_rect.height = h; } /// <summary> /// 是否在区域中 /// </summary> /// <param name="pos"></param> /// <returns></returns> public bool IsContain(Vector3 pos) { return m_rect.Contains(pos); } /// <summary> /// 区域点击检测 /// </summary> /// <param name="pos"></param> public void OnClick(Vector2 pos) { if(!CheckClick) return; if (IsContain(pos) && ClickCallback != null) { ClickCallback(true); } else if (ClickAllNotice && ClickCallback != null) { ClickCallback(false); } } /// <summary> /// 开始移动 /// </summary> /// <param name="pos"></param> public void OnMoveBegin(Vector2 pos) { if (!CheckMove) return; if (IsContain(pos)) { moving = true; if (MoveBeginCallback != null) MoveBeginCallback(pos); } } /// <summary> /// 区域移动检测 /// </summary> /// <param name="pos"></param> public void OnMove(Vector2 pos) { if(!moving || !CheckMove) return; if (IsContain(pos)) { if (MoveCallback != null) MoveCallback(pos); } else { if (EndOnOut) { moving = false; if (MoveEndCallback != null) MoveEndCallback(pos); } else { if (MoveCallback != null) MoveCallback(pos); } } } /// <summary> /// 移动结束 /// </summary> /// <param name="pos"></param> public void OnMoveEnd(Vector2 pos) { if (!moving || !CheckMove) return; if (MoveEndCallback != null) MoveEndCallback(pos); } }}
2 0
- 【UGUI】屏幕区域点击检测
- UGUI实现不规则区域点击响应
- Unity 点击屏幕与UGUI的区分
- 手机触屏检测,检测是否点击在UGUI上
- 点击屏幕任何区域隐藏键盘
- 点击屏幕任意区域软键盘消失
- 关于BoundingBox区域的点击检测问题:
- ugui与ngui如何检测是否点击在UI上
- searchbar在点击屏幕上空白区域后收起键盘
- Android 点击屏幕除TextView区域软键盘自动消失
- ios入门:点击屏幕其他区域,隐藏软键盘
- unity ui button ugui 按钮如何设置点击区域为圆形?【整理转载】
- 关于UGUI的DropDown点击区域外不关闭的问题
- cocos2dx 检测是否点击到了图片的透明区域
- cocos2dx 检测是否点击到了图片的透明区域
- UGUI自适应屏幕
- UGUI屏幕自适应
- UGUI - 判断是否点击在UI 上 Bug,IsPointerOverGameObject()在移动端检测失败
- 数字三角形问题
- linux copy_from/to_user原理
- bzoj 4085: [Sdoi2015]音质检测
- 云计算学习,OpenStack主要逻辑模块Nova的详细功能
- 前端小白训练营DAY3
- 【UGUI】屏幕区域点击检测
- 排序
- SATA盘和SAS盘区别
- 判断链表序列是否对称
- 文章标题
- hdu1074Doing Homework( 状态压缩dp)
- Expected one result (or null) to be returned by selectOne(), but found: 2
- 自适应共振理论人工神经网络
- Linux流量监控工具