赞
踩
目录
Unity 进阶 之 简单模仿鼠标交互(场景:手机屏幕当做触摸板Touch Pad,移动鼠标,鼠标确定等操作)
Unity中的一些知识点整理。
本节简单介绍在Unity开发中的,因为项目的开发需要,需要把手机屏幕当做触控板,模拟鼠标移动和点击交互等,所以这里简单的整理一些,或许场景不同,你可能需要进行屏幕适配,这里仅供参考学习使用,如果你有新的方式也可以留言,多谢。
1、这里使用 Input.GetMouseButtonDown(0) 、Input.GetMouseButton(0) 、Input.GetMouseButtonUp(0) 相关事件来获取位置相关信息进行处理,用来当做UI射线交互的位置
2、获取当前的 UI 的 EventSystem,然后进行对应改写,关键代码如下
m_eventSystem = EventSystem.current; // 获取当前的 EventSystem
m_pointerEvent = new PointerEventData(m_eventSystem);
m_pointerEvent.button = PointerEventData.InputButton.Left;
m_pointerEvent.position = mFunPointerPos != null ? mFunPointerPos.Invoke() : new Vector2(Screen.width * 1 / 2, Screen.height / 2); // 这里就是模拟鼠标位置
List<RaycastResult> raycastResults = new List<RaycastResult>();
m_eventSystem.RaycastAll(m_pointerEvent, raycastResults);
1、使用场景不同,可能需要做适当的屏幕适配
2、因为使用模拟鼠标交互,EventSystem 上默认的 Standalone Input Module 最好移除或者禁用,不然可能影响模拟的鼠标交互操作
3、可能有些情况模拟的鼠标会被遮住,你可以进行对应处理,可以调整UI层级,可以换种方式显示模拟鼠标,可以添加材质调整渲染队列,等
1、打开 Unity ,新建空工程
2、布置场景,一个是模拟的鼠标点,一些事交互控件
3、创建脚本,编写对应的逻辑代码,实现对应功能,IMouseGesturePointerCallback 回调接口,MousePointerMoveWrapper 鼠标位置,ScreenRayRaycasterUIWrapper 获取改写EventSystem当前的UI交互等等
4、 把脚本挂载到场景中,并对应把模拟的鼠标赋值,如图
5、这里Button 设置如下,并挂载一个脚本,用来点击交互,计数使用,方便效果演示
6、EventSystem 上默认的 Standalone Input Module 最好移除或者禁用,不然可能影响模拟的鼠标交互操作
7、运行场景,点击屏幕,移动,就可看到对应鼠标移动,并能简单交互 ,效果如上
1、TestMousePointerInteraction
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- namespace XANUtil {
-
- public class TestMousePointerInteraction : MonoBehaviour,IMouseGesturePointerCallback
- {
- public RectTransform PointerImageRectTrans;
-
- private MousePointerMoveWrapper mMousePointerMoveWrapper = new MousePointerMoveWrapper();
- private ScreenRayRaycasterUIWrapper mScreenRayRaycasterUIWrapper = new ScreenRayRaycasterUIWrapper();
-
- void Start()
- {
- Init();
- }
-
- void Update()
- {
- if (mMousePointerMoveWrapper != null)
- {
- mMousePointerMoveWrapper.Update();
-
- }
-
- if (mScreenRayRaycasterUIWrapper != null)
- {
- mScreenRayRaycasterUIWrapper.Update();
- }
- }
-
- void Init()
- {
-
- if (mMousePointerMoveWrapper != null)
- {
- // 把鼠标的位置传 Ray 发射位置
- mMousePointerMoveWrapper.Init(this);
- }
-
-
- if (mScreenRayRaycasterUIWrapper != null)
- {
- // 把鼠标的位置传 Ray 发射位置
- mScreenRayRaycasterUIWrapper.Init(() => { return PointerImageRectTrans.anchoredPosition; });
- }
- }
-
- #region PointerImageRectTrans
-
- void SetPointerImageRectTrans(Vector2 deltrPos)
- {
- if (PointerImageRectTrans != null)
- {
- Vector2 val = PointerImageRectTrans.anchoredPosition;
- val += ModifyPointerPos(deltrPos);
-
- PointerImageRectTrans.anchoredPosition = ClampValue(val);
- }
-
- }
-
- /// <summary>
- /// 根据需要做指针位置修正处理
- /// </summary>
- /// <param name="deltrPos"></param>
- /// <returns></returns>
- Vector2 ModifyPointerPos(Vector2 deltrPos)
- {
-
- return deltrPos;
- }
-
- /// <summary>
- /// 显示指针位置
- /// </summary>
- /// <param name="val"></param>
- /// <returns></returns>
- Vector2 ClampValue(Vector2 val)
- {
- val.x = val.x < 0 ? 0 : val.x;
- val.y = val.y < 0 ? 0 : val.y;
-
- val.x = val.x > Screen.width ? Screen.width : val.x;
- val.y = val.y > Screen.height ? Screen.height : val.y;
-
- return val;
- }
-
- #endregion
-
- #region Interface IMouseGesturePointerCallback
- public void MousePointerMoveDeltraPos(Vector2 deltraPos)
- {
- SetPointerImageRectTrans(deltraPos);
-
- }
- #endregion
-
- }
- }

2、SimulationPointerButtonItem
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
-
- namespace XANUtil {
-
- /// <summary>
- /// 简单的模拟指针选中的按钮脚本
- /// (可以不用这个,也可重写,仅做参考)
- /// </summary>
- public class SimulationPointerButtonItem : MonoBehaviour
- {
- private Button mBtn;
- private Text mBtnText;
-
-
- Action mOnClick;
- private int mCounter = 0;
-
- private void Awake()
- {
- Init(null);
- }
-
- public void Init(Action onClick)
- {
- mBtn = this.GetComponent<Button>();
- mBtnText = this.GetComponentInChildren<Text>();
- mCounter = 0;
- mOnClick = onClick;
- mBtn.onClick.AddListener(OnClick);
- }
-
- public void OnClick()
- {
- mCounter++;
- mBtnText.text = mCounter.ToString();
-
- mOnClick?.Invoke();
-
- }
- }
- }

3、ScreenRayRaycasterUIWrapper
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
-
- namespace XANUtil {
-
- public class ScreenRayRaycasterUIWrapper
- {
- // Prevents loop over the same selectable
- Selectable m_excluded;
- Selectable m_currentSelectable = null;
- RaycastResult m_currentRaycastResult;
-
- IPointerClickHandler m_clickHandler;
- IDragHandler m_dragHandler;
-
- EventSystem m_eventSystem;
- PointerEventData m_pointerEvent;
-
- Func<Vector2> mFunPointerPos;
- private bool mIsClick = false;
- private bool mIsSwipe = false;
- private bool mIsDrag = false;
-
- private Vector2 oldPos;
- private Vector2 lastPos;
- private const float MOVE_LENGTH_LIMIT = 10;
- public void Init(Func<Vector2> funPointerPos)
- {
- m_eventSystem = EventSystem.current;
- m_pointerEvent = new PointerEventData(m_eventSystem);
- m_pointerEvent.button = PointerEventData.InputButton.Left;
-
- mFunPointerPos = funPointerPos;
-
- }
-
- public void Update()
- {
- // 没有数据屏幕中心(即为 width * 3/4,height * 1/2)
- // Set pointer position
- m_pointerEvent.position = mFunPointerPos != null ? mFunPointerPos.Invoke() : new Vector2(Screen.width * 1 / 2, Screen.height / 2);
-
- List<RaycastResult> raycastResults = new List<RaycastResult>();
- m_eventSystem.RaycastAll(m_pointerEvent, raycastResults);
-
- // Detect selectable
- if (raycastResults.Count > 0)
- {
- foreach (var result in raycastResults)
- {
- var newSelectable = result.gameObject.GetComponentInParent<Selectable>();
-
- if (newSelectable)
- {
- if (newSelectable != m_excluded && newSelectable != m_currentSelectable)
- {
- Select(newSelectable);
- m_currentRaycastResult = result;
- }
- break;
- }
- }
- }
- else
- {
- if (m_currentSelectable || m_excluded)
- {
- Select(null, null);
- }
- }
-
- // Target is being activating
- if (m_currentSelectable)
- {
-
- if (m_clickHandler != null && Input.GetMouseButtonUp(0) && mIsSwipe == false)
- {
- m_clickHandler.OnPointerClick(m_pointerEvent);
- Select(null, null);
- }
-
- else if (m_dragHandler != null && mIsClick /*&& mIsSwipe == false*/)
- {
- mIsDrag = true;
- m_pointerEvent.pointerPressRaycast = m_currentRaycastResult;
- m_dragHandler.OnDrag(m_pointerEvent);
- }
- if (m_dragHandler == null)
- {
- mIsClick = false;
- mIsSwipe = false;
- }
-
- if (m_clickHandler != null || m_dragHandler != null)
- {
- if (Input.GetMouseButtonDown(0))
- {
-
- oldPos = Input.mousePosition;
- mIsClick = true;
- }
- else if (Input.GetMouseButtonUp(0))
- {
- mIsSwipe = false;
- mIsClick = false;
- mIsDrag = false;
- Select(null, null);
- }
- else
- {
- lastPos = Input.mousePosition;
- mIsSwipe = JudgeISSwipe(oldPos, lastPos);
- }
-
- }
-
- }
- else
- {
- mIsClick = false;
- mIsSwipe = false;
- Select(null, null);
- }
-
-
- if (Input.GetMouseButtonUp(0))
- {
- mIsSwipe = false;
- mIsClick = false;
- mIsDrag = false;
- Select(null, null);
- }
-
- }
-
- /// <summary>
- /// 判断是否是缓动
- /// </summary>
- /// <param name="oldPos"></param>
- /// <param name="lastPos"></param>
- /// <returns></returns>
- private bool JudgeISSwipe(Vector2 oldPos, Vector2 lastPos)
- {
- return Vector3.Distance(oldPos, lastPos) > MOVE_LENGTH_LIMIT;
- }
-
- /// <summary>
- /// 选择操作
- /// </summary>
- /// <param name="s"></param>
- /// <param name="exclude"></param>
- void Select(Selectable s, Selectable exclude = null)
- {
- if (mIsDrag == true)
- {
- return;
- }
-
- m_excluded = exclude;
-
- if (m_currentSelectable)
- m_currentSelectable.OnPointerExit(m_pointerEvent);
-
- m_currentSelectable = s;
-
- if (m_currentSelectable)
- {
- m_currentSelectable.OnPointerEnter(m_pointerEvent);
- m_clickHandler = m_currentSelectable.GetComponent<IPointerClickHandler>();
- m_dragHandler = m_currentSelectable.GetComponent<IDragHandler>();
- }
- else
- {
- m_clickHandler = null;
- m_dragHandler = null;
- }
-
- }
- }
- }

4、MousePointerMoveWrapper
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- namespace XANUtil {
-
- public class MousePointerMoveWrapper
- {
- private Vector2 mOldPos;
- private Vector2 mLastPos;
-
- private IMouseGesturePointerCallback mIMouseGesturePointerCallback;
-
- public void Init(IMouseGesturePointerCallback callback) {
- mIMouseGesturePointerCallback = callback;
- }
-
- public void Update()
- {
- if (Input.GetMouseButtonDown(0))
- {
- mOldPos = Input.mousePosition;
- }
- else if (Input.GetMouseButton(0))
- {
-
- mLastPos = Input.mousePosition;
- Vector2 deltaPosition = (mLastPos - mOldPos);
-
- mIMouseGesturePointerCallback?.MousePointerMoveDeltraPos(deltaPosition);
-
- mOldPos = mLastPos;
- }
- }
- }
- }

5、IMouseGesturePointerCallback
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- namespace XANUtil
- {
-
- public interface IMouseGesturePointerCallback
- {
- void MousePointerMoveDeltraPos(Vector2 deltraPos);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。