【Unity】在RawImage上鼠标点在屏幕上发生偏移的问题

问题简述

实现3D人物使用RawImage映射到UI上时,鼠标悬浮在人物的身上时出现UI的效果。
但是发现鼠标点不到正确的人物部位,鼠标在UI上的坐标相比在屏幕上的坐标发生了偏移。

问题解决简述

使用RectTransformUtility.ScreenPointToLocalPointInRectangle()方法将屏幕坐标转换成UGUI的坐标

一般使用Physics.Raycast()时是ray = MainCamera.ScreenPointToRay(Input.mousePosition)

但是3D物体要投射到UI上时,就多了一步,先将Input.mousePosition转UGUI的坐标,再用ScreenPointToRay()

注意:
①RawImage的Width和Height必须和创建的RenderTexture的Size一致。
②如果Canvas的Render Mode是overlay则RectTransformUtility.ScreenPointToLocalPointInRectangle()的关于相机的参数可以写null
③RawImage的Pivot为了方便设置成0。Pivot是控制UI的中心点,设置成0则UI的(0,0)点在UI的左下角,方便计算。

具体实现

1、使用RawImage将3D人物投射到UI上

1、创建一个Canvas,在其下创建一个RawImage,然后在Assets下创建一个Render Texture。使RawImage的Width和Height和创建的RenderTexture的Size一致,将Render Texture赋给RawImage。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
2、创建一个Camera来专门看人物,CullingMask选择创建的Model层,将ModelShow赋给Target Texture。
在这里插入图片描述
3、将人物的Layer也选为Model
在这里插入图片描述

2、使用RectTransformUtility.ScreenPointToLocalPointInRectangle()方法解决鼠标偏移

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class RayCastModel : MonoBehaviour
{
    [SerializeField]
    private bool isStart = false;

    [SerializeField]
    private Vector3 screenPoint;
    
    [SerializeField]
    private Vector2 localPoint;

    public RectTransform rect;

    public List<Transform> PointsList = new List<Transform>();

    public Transform labels;

    public Camera modelCamera;

    Ray ray;
    RaycastHit raycastHit;

    void Start()
    {
        labels = GameObject.Find("UICanvas/Labels").transform;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
            isStart = true;
        }

        if (Input.GetKeyDown(KeyCode.D))
        {
            isStart = false;
        }

        if (isStart == true)
        {
        	//获取屏幕坐标
            screenPoint = Input.mousePosition;
	        //屏幕坐标转UGUI坐标
            if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, screenPoint, null, out localPoint))
            {
                localPoint = new Vector2(localPoint.x, localPoint.y);
 
                ray = modelCamera.ScreenPointToRay(localPoint);

                if (Physics.Raycast(ray, out raycastHit, 1000, 1 << 8))
                {                    
                    Debug.DrawLine(modelCamera.transform.position, raycastHit.collider.transform.position, Color.blue);
                    if (PointsList.Contains(raycastHit.collider.transform))
                    {
                        if (raycastHit.collider.transform.name == "LeftPoint")
                        {
                            labels.GetChild(0).transform.position = screenPoint;
                            labels.GetChild(0).Find("Image/Text").GetComponent<Text>().text = "左手";
                            labels.GetChild(0).gameObject.SetActive(true);
                        }
                        if (raycastHit.collider.transform.name == "RightPoint")
                        {
                            labels.GetChild(0).transform.position = screenPoint;
                            labels.GetChild(0).Find("Image/Text").GetComponent<Text>().text = "右手";
                            labels.GetChild(0).gameObject.SetActive(true);
                        }

                    }
                }
                else
                {
                    for (int i = 0; i < labels.childCount; i++)
                    {
                        labels.GetChild(i).gameObject.SetActive(false);
                    }

                }
            }
        }
    }
}



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值