赞
踩
1、需要射线检测的物体先加个collider组件,方便射线检测到
2、第一种方式通过获取点击UI界面的UI坐标A,将A转换为RawImage的相对坐标B,再将B转为映射相机的视口(Viewport)坐标C,然后在映射相机发射射线对穿过的物体进行检测
代码如下:
-
- using UnityEngine;
- using UnityEngine.UI;
-
- public class TestRenderTexture : MonoBehaviour
- {
- // 点击RawImage时,相对RawImage自身的坐标
- private Vector2 ClickPosInRawImg;
- // 画布
- public Canvas Canvas;
- // 预览映射相机
- public Camera PreviewCamera;
- public RawImage PreviewImage;
- public Camera UiCamera;
- private Vector3 MousePos;
-
- void Start(){}
-
- void Update()
- {
- if (Input.GetMouseButtonDown(0))
- {
- MousePos = Input.mousePosition;
- }
- if (MousePos != null)
- {
- CheckDrawRayLine(Canvas, Input.mousePosition, PreviewImage, PreviewCamera);
- }
- }
-
- /// <summary>
- /// 射线投射
- /// </summary>
- /// <param name="canvas">画布</param>
- /// <param name="mousePosition">当前Canvas下点击的鼠标位置</param>
- /// <param name="previewImage">预览图</param>
- /// <param name="previewCamera">预览映射图的摄像机</param>
- void CheckDrawRayLine(Canvas canvas, Vector3 mousePosition, RawImage previewImage, Camera previewCamera)
- {
- // 将UI相机下点击的UI坐标转为相对RawImage的坐标
- if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, mousePosition, UiCamera, out ClickPosInRawImg))
- {
- // Lylibs.MessageUtil.Show("坐标:x=" + ClickPosInRawImg.x + ",y=" + ClickPosInRawImg.y);
-
- //获取预览图的长宽
- float imageWidth = previewImage.rectTransform.rect.width;
- float imageHeight = previewImage.rectTransform.rect.height;
- //获取预览图的坐标,此处RawImage的Pivot需为(0,0),不然自己再换算下
- float localPositionX = previewImage.rectTransform.localPosition.x;
- float localPositionY = previewImage.rectTransform.localPosition.y;
-
- //获取在预览映射相机viewport内的坐标(坐标比例)
- float p_x = (ClickPosInRawImg.x - localPositionX) / imageWidth;
- float p_y = (ClickPosInRawImg.y - localPositionY) / imageHeight;
-
- //从视口坐标发射线
- Ray p_ray = previewCamera.ViewportPointToRay(new Vector2(p_x, p_y));
- RaycastHit p_hitInfo;
- if (Physics.Raycast(p_ray, out p_hitInfo))
- {
- //显示射线,只有在scene视图中才能看到
- Debug.DrawLine(p_ray.origin, p_hitInfo.point);
- // Debug.Log(p_hitInfo.transform.name);
- }
- }
- }
- }
3、第二种方式直接写个继承RawImage的类A,在A里直接通过监听RawImage的点击事件获取相对RawImage的点击坐标B,将A转换为RawImage的相对坐标B,再将B转为映射相机的视口(Viewport)坐标C,然后在映射相机发射射线对穿过的物体进行检测,感觉比第一种方便些
代码如下:
-
- using System;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
-
- namespace Lylibs
- {
- public class LyRawImage : RawImage, IPointerClickHandler
- {
- // 点击RawImage时,相对RawImage自身的坐标
- private Vector2 ClickPosInRawImg;
- // 预览映射相机
- private Camera PreviewCamera;
- private XLua.LuaTable ObjTable;
- private Action<XLua.LuaTable, Vector2, Transform> CallFun = null;
-
- void Start()
- {
- // 初始获取预览映射相机
- if (PreviewCamera == null)
- {
- PreviewCamera = GameObject.Find("[CAMERAs]").transform.Find("[RENDER_TEXTURE_CAMERA]").GetComponent<Camera>();
- }
- }
-
- void Update()
- {
- #if UNITY_EDITOR
- CheckDrawRayLine(false);
- #endif
- }
-
- void IPointerClickHandler.OnPointerClick(PointerEventData eventData)
- {
- // 获取相对RawImage的点击坐标
- if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out ClickPosInRawImg))
- {
- // Lylibs.MessageUtil.Show("坐标:x=" + ClickPosInRawImg.x + ",y=" + ClickPosInRawImg.y);
- CheckDrawRayLine(true);
- }
- }
-
- // 检查是否需要绘制射线
- void CheckDrawRayLine(bool isCallBack)
- {
- if (PreviewCamera != null && ClickPosInRawImg != null)
- {
- //获取预览图的长宽
- float p_imageWidth = rectTransform.rect.width;
- float p_imageHeight = rectTransform.rect.height;
- //获取预览图的坐标
- float p_localPositionX = rectTransform.localPosition.x;
- float p_localPositionY = rectTransform.localPosition.y;
-
- //获取在预览映射相机viewport内的坐标(坐标比例)
- float p_x = ClickPosInRawImg.x / p_imageWidth;
- float p_y = ClickPosInRawImg.y / p_imageHeight;
-
- //从预览映射相机视口坐标发射线
- Ray ray = PreviewCamera.ViewportPointToRay(new Vector2(p_x, p_y));
- RaycastHit hitInfo;
- if (Physics.Raycast(ray, out hitInfo))
- {
- //显示射线,只有在scene视图中才能看到
- Debug.DrawLine(ray.origin, hitInfo.point);
- // Debug.Log(hitInfo.transform.name);
-
- if (isCallBack == true && ObjTable != null && CallFun != null)
- {
- CallFun(ObjTable, ClickPosInRawImg, hitInfo.transform);
- }
- }
- }
- }
-
- public void SetEventCall(XLua.LuaTable table, Action<XLua.LuaTable, Vector2, Transform> call)
- {
- ObjTable = table;
- CallFun = call;
- }
- }
- }
4、此种实现诸如如下的效果方便:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。