当前位置:   article > 正文

Unity功能测试3D物体和UI的点击事件_unity辅助功能测试

unity辅助功能测试

我们在功能开发中 当UI和3D物体在一起的时候点击事件通常会有这么几种情况

1、UI和3D物体同时响应事件

这种情况很常见,如果是故意有次功能需求那将不需要改动.实现代码

3D物体上挂载

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PointObjClick : MonoBehaviour
  5. {
  6. // Start is called before the first frame update
  7. void Start()
  8. {
  9. }
  10. private void OnMouseDown()
  11. {
  12. Click();
  13. }
  14. private void Click()
  15. {
  16. transform.GetComponent<MeshRenderer>().material.color = Random.ColorHSV();
  17. }
  18. }

UI上挂载

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using UnityEngine.EventSystems;
  6. public class PointUIClick : MonoBehaviour, IPointerClickHandler
  7. {
  8. public void OnPointerClick(PointerEventData eventData)
  9. {
  10. Click();
  11. //实现穿透的事件效果
  12. // ExecuteAll(eventData);
  13. }
  14. private void Click()
  15. {
  16. transform.GetComponent<Image>().color = Random.ColorHSV();
  17. }
  18. private void ExecuteAll(PointerEventData eventData)
  19. {
  20. //UGUI 底层会对射线射到的所有物体进行排序 只触发最前面的物体
  21. List<RaycastResult> results = new List<RaycastResult>();
  22. //拿到射线下所有的物体 放到集合里
  23. EventSystem.current.RaycastAll(eventData, results);
  24. foreach (var item in results)
  25. {
  26. if (item.gameObject != gameObject)
  27. {
  28. //触发 1、触发对象 2、触发事件 3、触发方式
  29. ExecuteEvents.Execute(item.gameObject, eventData, ExecuteEvents.pointerClickHandler);
  30. }
  31. }
  32. }
  33. }

这里面ExecuteAll这个方法也可以处理同理响应事件的问题(已注释)

2、UI和3D物体分别响应事件

这种情况应该是我们理想中的效果,看代码是如何实现的

首先在主相机上添加Physics RayCaster组件

1. 什么是PhysicsRaycaster组件?

PhysicsRaycaster是Unity UGUI中的一个组件,用于在UI元素上进行物理射线检测。它可以检测鼠标或触摸事件是否发生在UI元素上,并将事件传递给相应的UI元素。

2. PhysicsRaycaster的工作原理

PhysicsRaycaster通过发射一条射线来检测UI元素。当射线与UI元素相交时,PhysicsRaycaster会将事件传递给相应的UI元素。

利用Physics Raycaster这个特性 我们可以把UI和3D的点击事件分开

3D物体挂载

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.EventSystems;
  5. public class PointCubeClick : MonoBehaviour, IPointerClickHandler
  6. {
  7. public void OnPointerClick(PointerEventData eventData)
  8. {
  9. Click();
  10. }
  11. private void Click()
  12. {
  13. transform.GetComponent<MeshRenderer>().material.color = Random.ColorHSV();
  14. }
  15. }

UI上挂载

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using UnityEngine.EventSystems;
  6. public class PointUIClick : MonoBehaviour, IPointerClickHandler
  7. {
  8. public void OnPointerClick(PointerEventData eventData)
  9. {
  10. Click();
  11. //实现穿透的事件效果
  12. // ExecuteAll(eventData);
  13. }
  14. private void Click()
  15. {
  16. transform.GetComponent<Image>().color = Random.ColorHSV();
  17. }
  18. private void ExecuteAll(PointerEventData eventData)
  19. {
  20. //UGUI 底层会对射线射到的所有物体进行排序 只触发最前面的物体
  21. List<RaycastResult> results = new List<RaycastResult>();
  22. //拿到射线下所有的物体 放到集合里
  23. EventSystem.current.RaycastAll(eventData, results);
  24. foreach (var item in results)
  25. {
  26. if (item.gameObject != gameObject)
  27. {
  28. //触发 1、触发对象 2、触发事件 3、触发方式
  29. ExecuteEvents.Execute(item.gameObject, eventData, ExecuteEvents.pointerClickHandler);
  30. }
  31. }
  32. }
  33. }

3、检测点击的游戏对象是UII还是3D物体

来看代码实现

UI上挂载

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.EventSystems;
  5. using UnityEngine.UI;
  6. public class PointIsUI : MonoBehaviour
  7. {
  8. //GraphicRaycaster是专门用于Canvas下UI的射线检测的
  9. private GraphicRaycaster _raycaster;
  10. // Start is called before the first frame update
  11. void Start()
  12. {
  13. _raycaster = FindObjectOfType<GraphicRaycaster>();
  14. }
  15. // Update is called once per frame
  16. void Update()
  17. {
  18. if (Input.GetMouseButtonDown(0))
  19. {
  20. if (IsUI())
  21. {
  22. Debug.LogError("是UI");
  23. }
  24. else
  25. {
  26. Debug.LogError("不是UI");
  27. }
  28. }
  29. }
  30. private bool IsUI()
  31. {
  32. //New一个点击事件 传入当前事件
  33. PointerEventData eventData = new PointerEventData(EventSystem.current);
  34. eventData.pressPosition = Input.mousePosition;
  35. //PointerEventData.pressPosition
  36. //按下的时候的指针位置,同样的一次点击事件只有一个
  37. eventData.position = Input.mousePosition;
  38. //PointerEventData .position当前指针的位置,
  39. //返回一个vector2向量,这个值是一个屏幕坐标,
  40. //左下角为原点(0, 0),右上角为(屏幕宽, 屏幕高),
  41. //这个屏幕是根据当前分辨率来的
  42. List<RaycastResult> results = new List<RaycastResult>(); //拿到射线点击的物体
  43. _raycaster.Raycast(eventData, results); //射线赋值 到集合里
  44. return results.Count > 0; //true是UI false不是UI
  45. }
  46. }

谢谢观看!

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

闽ICP备14008679号