【在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);
}
}
}
}
}
}