当前位置:   article > 正文

Unity 进阶 之 简单模仿鼠标交互(场景:手机屏幕当做触摸板Touch Pad,移动鼠标,鼠标确定等操作)_unity触屏代替鼠标

unity触屏代替鼠标

 Unity 进阶 之 简单模仿鼠标交互(场景:手机屏幕当做触摸板Touch Pad,移动鼠标,鼠标确定等操作)

目录

 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

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace XANUtil {
  5. public class TestMousePointerInteraction : MonoBehaviour,IMouseGesturePointerCallback
  6. {
  7. public RectTransform PointerImageRectTrans;
  8. private MousePointerMoveWrapper mMousePointerMoveWrapper = new MousePointerMoveWrapper();
  9. private ScreenRayRaycasterUIWrapper mScreenRayRaycasterUIWrapper = new ScreenRayRaycasterUIWrapper();
  10. void Start()
  11. {
  12. Init();
  13. }
  14. void Update()
  15. {
  16. if (mMousePointerMoveWrapper != null)
  17. {
  18. mMousePointerMoveWrapper.Update();
  19. }
  20. if (mScreenRayRaycasterUIWrapper != null)
  21. {
  22. mScreenRayRaycasterUIWrapper.Update();
  23. }
  24. }
  25. void Init()
  26. {
  27. if (mMousePointerMoveWrapper != null)
  28. {
  29. // 把鼠标的位置传 Ray 发射位置
  30. mMousePointerMoveWrapper.Init(this);
  31. }
  32. if (mScreenRayRaycasterUIWrapper != null)
  33. {
  34. // 把鼠标的位置传 Ray 发射位置
  35. mScreenRayRaycasterUIWrapper.Init(() => { return PointerImageRectTrans.anchoredPosition; });
  36. }
  37. }
  38. #region PointerImageRectTrans
  39. void SetPointerImageRectTrans(Vector2 deltrPos)
  40. {
  41. if (PointerImageRectTrans != null)
  42. {
  43. Vector2 val = PointerImageRectTrans.anchoredPosition;
  44. val += ModifyPointerPos(deltrPos);
  45. PointerImageRectTrans.anchoredPosition = ClampValue(val);
  46. }
  47. }
  48. /// <summary>
  49. /// 根据需要做指针位置修正处理
  50. /// </summary>
  51. /// <param name="deltrPos"></param>
  52. /// <returns></returns>
  53. Vector2 ModifyPointerPos(Vector2 deltrPos)
  54. {
  55. return deltrPos;
  56. }
  57. /// <summary>
  58. /// 显示指针位置
  59. /// </summary>
  60. /// <param name="val"></param>
  61. /// <returns></returns>
  62. Vector2 ClampValue(Vector2 val)
  63. {
  64. val.x = val.x < 0 ? 0 : val.x;
  65. val.y = val.y < 0 ? 0 : val.y;
  66. val.x = val.x > Screen.width ? Screen.width : val.x;
  67. val.y = val.y > Screen.height ? Screen.height : val.y;
  68. return val;
  69. }
  70. #endregion
  71. #region Interface IMouseGesturePointerCallback
  72. public void MousePointerMoveDeltraPos(Vector2 deltraPos)
  73. {
  74. SetPointerImageRectTrans(deltraPos);
  75. }
  76. #endregion
  77. }
  78. }

2、SimulationPointerButtonItem

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.UI;
  6. namespace XANUtil {
  7. /// <summary>
  8. /// 简单的模拟指针选中的按钮脚本
  9. /// (可以不用这个,也可重写,仅做参考)
  10. /// </summary>
  11. public class SimulationPointerButtonItem : MonoBehaviour
  12. {
  13. private Button mBtn;
  14. private Text mBtnText;
  15. Action mOnClick;
  16. private int mCounter = 0;
  17. private void Awake()
  18. {
  19. Init(null);
  20. }
  21. public void Init(Action onClick)
  22. {
  23. mBtn = this.GetComponent<Button>();
  24. mBtnText = this.GetComponentInChildren<Text>();
  25. mCounter = 0;
  26. mOnClick = onClick;
  27. mBtn.onClick.AddListener(OnClick);
  28. }
  29. public void OnClick()
  30. {
  31. mCounter++;
  32. mBtnText.text = mCounter.ToString();
  33. mOnClick?.Invoke();
  34. }
  35. }
  36. }

3、ScreenRayRaycasterUIWrapper

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.EventSystems;
  6. using UnityEngine.UI;
  7. namespace XANUtil {
  8. public class ScreenRayRaycasterUIWrapper
  9. {
  10. // Prevents loop over the same selectable
  11. Selectable m_excluded;
  12. Selectable m_currentSelectable = null;
  13. RaycastResult m_currentRaycastResult;
  14. IPointerClickHandler m_clickHandler;
  15. IDragHandler m_dragHandler;
  16. EventSystem m_eventSystem;
  17. PointerEventData m_pointerEvent;
  18. Func<Vector2> mFunPointerPos;
  19. private bool mIsClick = false;
  20. private bool mIsSwipe = false;
  21. private bool mIsDrag = false;
  22. private Vector2 oldPos;
  23. private Vector2 lastPos;
  24. private const float MOVE_LENGTH_LIMIT = 10;
  25. public void Init(Func<Vector2> funPointerPos)
  26. {
  27. m_eventSystem = EventSystem.current;
  28. m_pointerEvent = new PointerEventData(m_eventSystem);
  29. m_pointerEvent.button = PointerEventData.InputButton.Left;
  30. mFunPointerPos = funPointerPos;
  31. }
  32. public void Update()
  33. {
  34. // 没有数据屏幕中心(即为 width * 3/4,height * 1/2)
  35. // Set pointer position
  36. m_pointerEvent.position = mFunPointerPos != null ? mFunPointerPos.Invoke() : new Vector2(Screen.width * 1 / 2, Screen.height / 2);
  37. List<RaycastResult> raycastResults = new List<RaycastResult>();
  38. m_eventSystem.RaycastAll(m_pointerEvent, raycastResults);
  39. // Detect selectable
  40. if (raycastResults.Count > 0)
  41. {
  42. foreach (var result in raycastResults)
  43. {
  44. var newSelectable = result.gameObject.GetComponentInParent<Selectable>();
  45. if (newSelectable)
  46. {
  47. if (newSelectable != m_excluded && newSelectable != m_currentSelectable)
  48. {
  49. Select(newSelectable);
  50. m_currentRaycastResult = result;
  51. }
  52. break;
  53. }
  54. }
  55. }
  56. else
  57. {
  58. if (m_currentSelectable || m_excluded)
  59. {
  60. Select(null, null);
  61. }
  62. }
  63. // Target is being activating
  64. if (m_currentSelectable)
  65. {
  66. if (m_clickHandler != null && Input.GetMouseButtonUp(0) && mIsSwipe == false)
  67. {
  68. m_clickHandler.OnPointerClick(m_pointerEvent);
  69. Select(null, null);
  70. }
  71. else if (m_dragHandler != null && mIsClick /*&& mIsSwipe == false*/)
  72. {
  73. mIsDrag = true;
  74. m_pointerEvent.pointerPressRaycast = m_currentRaycastResult;
  75. m_dragHandler.OnDrag(m_pointerEvent);
  76. }
  77. if (m_dragHandler == null)
  78. {
  79. mIsClick = false;
  80. mIsSwipe = false;
  81. }
  82. if (m_clickHandler != null || m_dragHandler != null)
  83. {
  84. if (Input.GetMouseButtonDown(0))
  85. {
  86. oldPos = Input.mousePosition;
  87. mIsClick = true;
  88. }
  89. else if (Input.GetMouseButtonUp(0))
  90. {
  91. mIsSwipe = false;
  92. mIsClick = false;
  93. mIsDrag = false;
  94. Select(null, null);
  95. }
  96. else
  97. {
  98. lastPos = Input.mousePosition;
  99. mIsSwipe = JudgeISSwipe(oldPos, lastPos);
  100. }
  101. }
  102. }
  103. else
  104. {
  105. mIsClick = false;
  106. mIsSwipe = false;
  107. Select(null, null);
  108. }
  109. if (Input.GetMouseButtonUp(0))
  110. {
  111. mIsSwipe = false;
  112. mIsClick = false;
  113. mIsDrag = false;
  114. Select(null, null);
  115. }
  116. }
  117. /// <summary>
  118. /// 判断是否是缓动
  119. /// </summary>
  120. /// <param name="oldPos"></param>
  121. /// <param name="lastPos"></param>
  122. /// <returns></returns>
  123. private bool JudgeISSwipe(Vector2 oldPos, Vector2 lastPos)
  124. {
  125. return Vector3.Distance(oldPos, lastPos) > MOVE_LENGTH_LIMIT;
  126. }
  127. /// <summary>
  128. /// 选择操作
  129. /// </summary>
  130. /// <param name="s"></param>
  131. /// <param name="exclude"></param>
  132. void Select(Selectable s, Selectable exclude = null)
  133. {
  134. if (mIsDrag == true)
  135. {
  136. return;
  137. }
  138. m_excluded = exclude;
  139. if (m_currentSelectable)
  140. m_currentSelectable.OnPointerExit(m_pointerEvent);
  141. m_currentSelectable = s;
  142. if (m_currentSelectable)
  143. {
  144. m_currentSelectable.OnPointerEnter(m_pointerEvent);
  145. m_clickHandler = m_currentSelectable.GetComponent<IPointerClickHandler>();
  146. m_dragHandler = m_currentSelectable.GetComponent<IDragHandler>();
  147. }
  148. else
  149. {
  150. m_clickHandler = null;
  151. m_dragHandler = null;
  152. }
  153. }
  154. }
  155. }

4、MousePointerMoveWrapper

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace XANUtil {
  5. public class MousePointerMoveWrapper
  6. {
  7. private Vector2 mOldPos;
  8. private Vector2 mLastPos;
  9. private IMouseGesturePointerCallback mIMouseGesturePointerCallback;
  10. public void Init(IMouseGesturePointerCallback callback) {
  11. mIMouseGesturePointerCallback = callback;
  12. }
  13. public void Update()
  14. {
  15. if (Input.GetMouseButtonDown(0))
  16. {
  17. mOldPos = Input.mousePosition;
  18. }
  19. else if (Input.GetMouseButton(0))
  20. {
  21. mLastPos = Input.mousePosition;
  22. Vector2 deltaPosition = (mLastPos - mOldPos);
  23. mIMouseGesturePointerCallback?.MousePointerMoveDeltraPos(deltaPosition);
  24. mOldPos = mLastPos;
  25. }
  26. }
  27. }
  28. }

5、IMouseGesturePointerCallback

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace XANUtil
  5. {
  6. public interface IMouseGesturePointerCallback
  7. {
  8. void MousePointerMoveDeltraPos(Vector2 deltraPos);
  9. }
  10. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/496323
推荐阅读
相关标签
  

闽ICP备14008679号