当前位置:   article > 正文

Unity点击RawImage获取RenderTexture的映射物体_raw image触发映射区点击事件

raw image触发映射区点击事件

1、需要射线检测的物体先加个collider组件,方便射线检测到

2、第一种方式通过获取点击UI界面的UI坐标A,将A转换为RawImage的相对坐标B,再将B转为映射相机的视口(Viewport)坐标C,然后在映射相机发射射线对穿过的物体进行检测

    代码如下:

  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. public class TestRenderTexture : MonoBehaviour
  4. {
  5. // 点击RawImage时,相对RawImage自身的坐标
  6. private Vector2 ClickPosInRawImg;
  7. // 画布
  8. public Canvas Canvas;
  9. // 预览映射相机
  10. public Camera PreviewCamera;
  11. public RawImage PreviewImage;
  12. public Camera UiCamera;
  13. private Vector3 MousePos;
  14. void Start(){}
  15. void Update()
  16. {
  17. if (Input.GetMouseButtonDown(0))
  18. {
  19. MousePos = Input.mousePosition;
  20. }
  21. if (MousePos != null)
  22. {
  23. CheckDrawRayLine(Canvas, Input.mousePosition, PreviewImage, PreviewCamera);
  24. }
  25. }
  26. /// <summary>
  27. /// 射线投射
  28. /// </summary>
  29. /// <param name="canvas">画布</param>
  30. /// <param name="mousePosition">当前Canvas下点击的鼠标位置</param>
  31. /// <param name="previewImage">预览图</param>
  32. /// <param name="previewCamera">预览映射图的摄像机</param>
  33. void CheckDrawRayLine(Canvas canvas, Vector3 mousePosition, RawImage previewImage, Camera previewCamera)
  34. {
  35. // 将UI相机下点击的UI坐标转为相对RawImage的坐标
  36. if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, mousePosition, UiCamera, out ClickPosInRawImg))
  37. {
  38. // Lylibs.MessageUtil.Show("坐标:x=" + ClickPosInRawImg.x + ",y=" + ClickPosInRawImg.y);
  39. //获取预览图的长宽
  40. float imageWidth = previewImage.rectTransform.rect.width;
  41. float imageHeight = previewImage.rectTransform.rect.height;
  42. //获取预览图的坐标,此处RawImage的Pivot需为(0,0),不然自己再换算下
  43. float localPositionX = previewImage.rectTransform.localPosition.x;
  44. float localPositionY = previewImage.rectTransform.localPosition.y;
  45. //获取在预览映射相机viewport内的坐标(坐标比例)
  46. float p_x = (ClickPosInRawImg.x - localPositionX) / imageWidth;
  47. float p_y = (ClickPosInRawImg.y - localPositionY) / imageHeight;
  48. //从视口坐标发射线
  49. Ray p_ray = previewCamera.ViewportPointToRay(new Vector2(p_x, p_y));
  50. RaycastHit p_hitInfo;
  51. if (Physics.Raycast(p_ray, out p_hitInfo))
  52. {
  53. //显示射线,只有在scene视图中才能看到
  54. Debug.DrawLine(p_ray.origin, p_hitInfo.point);
  55. // Debug.Log(p_hitInfo.transform.name);
  56. }
  57. }
  58. }
  59. }

3、第二种方式直接写个继承RawImage的类A,在A里直接通过监听RawImage的点击事件获取相对RawImage的点击坐标B,将A转换为RawImage的相对坐标B,再将B转为映射相机的视口(Viewport)坐标C,然后在映射相机发射射线对穿过的物体进行检测,感觉比第一种方便些

代码如下:

  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.EventSystems;
  4. using UnityEngine.UI;
  5. namespace Lylibs
  6. {
  7. public class LyRawImage : RawImage, IPointerClickHandler
  8. {
  9. // 点击RawImage时,相对RawImage自身的坐标
  10. private Vector2 ClickPosInRawImg;
  11. // 预览映射相机
  12. private Camera PreviewCamera;
  13. private XLua.LuaTable ObjTable;
  14. private Action<XLua.LuaTable, Vector2, Transform> CallFun = null;
  15. void Start()
  16. {
  17. // 初始获取预览映射相机
  18. if (PreviewCamera == null)
  19. {
  20. PreviewCamera = GameObject.Find("[CAMERAs]").transform.Find("[RENDER_TEXTURE_CAMERA]").GetComponent<Camera>();
  21. }
  22. }
  23. void Update()
  24. {
  25. #if UNITY_EDITOR
  26. CheckDrawRayLine(false);
  27. #endif
  28. }
  29. void IPointerClickHandler.OnPointerClick(PointerEventData eventData)
  30. {
  31. // 获取相对RawImage的点击坐标
  32. if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out ClickPosInRawImg))
  33. {
  34. // Lylibs.MessageUtil.Show("坐标:x=" + ClickPosInRawImg.x + ",y=" + ClickPosInRawImg.y);
  35. CheckDrawRayLine(true);
  36. }
  37. }
  38. // 检查是否需要绘制射线
  39. void CheckDrawRayLine(bool isCallBack)
  40. {
  41. if (PreviewCamera != null && ClickPosInRawImg != null)
  42. {
  43. //获取预览图的长宽
  44. float p_imageWidth = rectTransform.rect.width;
  45. float p_imageHeight = rectTransform.rect.height;
  46. //获取预览图的坐标
  47. float p_localPositionX = rectTransform.localPosition.x;
  48. float p_localPositionY = rectTransform.localPosition.y;
  49. //获取在预览映射相机viewport内的坐标(坐标比例)
  50. float p_x = ClickPosInRawImg.x / p_imageWidth;
  51. float p_y = ClickPosInRawImg.y / p_imageHeight;
  52. //从预览映射相机视口坐标发射线
  53. Ray ray = PreviewCamera.ViewportPointToRay(new Vector2(p_x, p_y));
  54. RaycastHit hitInfo;
  55. if (Physics.Raycast(ray, out hitInfo))
  56. {
  57. //显示射线,只有在scene视图中才能看到
  58. Debug.DrawLine(ray.origin, hitInfo.point);
  59. // Debug.Log(hitInfo.transform.name);
  60. if (isCallBack == true && ObjTable != null && CallFun != null)
  61. {
  62. CallFun(ObjTable, ClickPosInRawImg, hitInfo.transform);
  63. }
  64. }
  65. }
  66. }
  67. public void SetEventCall(XLua.LuaTable table, Action<XLua.LuaTable, Vector2, Transform> call)
  68. {
  69. ObjTable = table;
  70. CallFun = call;
  71. }
  72. }
  73. }

4、此种实现诸如如下的效果方便:

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

闽ICP备14008679号