超大网站制作素材,wordpress 嵌入 php代码,蛋花儿wordpress主题,wordpress同步twitter在UI Canvas的Render Mode模式是Screen Space-Camera模式极其容易3D坐标值转UI坐标出错。 **具体原因是#xff1a;**Canvas的Rect Transform锁定#xff0c;其Scale的倍数值不是1#xff0c;所以导致从3D的坐标数值转换成UI坐标时就会出现问题。 正确做法#xff1a; 1、 …在UI Canvas的Render Mode模式是Screen Space-Camera模式极其容易3D坐标值转UI坐标出错。 **具体原因是**Canvas的Rect Transform锁定其Scale的倍数值不是1所以导致从3D的坐标数值转换成UI坐标时就会出现问题。 正确做法 1、 声明变量 3D物体、 UI的RectTransform、 Canvas的RectTransform、 Canvas所使用的Camera2、将物体的世界坐标转换为Canvas内的局部坐标3、设置UI元素的位置为Canvas内的局部坐标代码
public class TitileMove : MonoBehaviour
{// 3D物体public Transform object3D;// UI Image的RectTransformpublic RectTransform uiImageRectTransform;// Canvas的RectTransformpublic RectTransform canvasRectTransform;// Canvas所使用的Camerapublic Camera canvasCamera;public GameObject lastSelectedObject;private bool isDragging false;private bool isRotating false;private Vector3 lastMousePosition;private void OnBecameInvisible(){// 当物体不可见时隐藏UI元素uiImageRectTransform.gameObject.SetActive(false);}void Update(){// 如果鼠标左键按下if (Input.GetMouseButtonDown(0)){Ray ray Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hit;// 射线检测是否点击到物体if (Physics.Raycast(ray, out hit)){GameObject selectedObject hit.collider.gameObject;// 判断是否点击到了我们想要拖拽的物体if (selectedObject.transform.name 3){uiImageRectTransform.gameObject.SetActive(true);// 开始拖拽// 将物体的世界坐标转换为Canvas内的局部坐标Vector2 localPos;RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTransform, Camera.main.WorldToScreenPoint(selectedObject.transform.position), canvasCamera, out localPos);// 设置UI元素的位置为Canvas内的局部坐标localPos new Vector2(localPos.x - 249, localPos.y 70);uiImageRectTransform.localPosition localPos;lastSelectedObject selectedObject;Vector3 objectPosition selectedObject.transform.position;lastMousePosition Input.mousePosition;}else{// 隐藏UI元素uiImageRectTransform.gameObject.SetActive(false);}}isRotating true;// 检测物体是否不可见并隐藏UI元素if (lastSelectedObject ! null IsObjectInvisible(lastSelectedObject)){uiImageRectTransform.gameObject.SetActive(false);}}if (isRotating object3D ! null){// 获取当前鼠标位置和上一帧鼠标位置之间的差值Vector3 deltaMouse Input.mousePosition - lastMousePosition;// 根据差值来计算旋转角度float rotationSpeed 0.25f; // 调整旋转速度float rotationY deltaMouse.x * rotationSpeed;// 应用旋转object3D.transform.Rotate(Vector3.up, -rotationY, Space.World);// 更新上一帧鼠标位置lastMousePosition Input.mousePosition;if (uiImageRectTransform ! null){// uiImageRectTransform.GetComponentRectTransform().anchoredPosition new Vector2(uiImageRectTransform.GetComponentRectTransform().anchoredPosition.x deltaMouse.x, uiImageRectTransform.GetComponentRectTransform().anchoredPosition.y);// 将物体的世界坐标转换为屏幕坐标Vector2 screenPos RectTransformUtility.WorldToScreenPoint(null, uiImageRectTransform.position);// 将屏幕坐标转换为Canvas内的局部坐标RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTransform, screenPos, null, out Vector2 localPos);localPos new Vector2(localPos.x deltaMouse.x, localPos.y);// 设置物体的局部坐标uiImageRectTransform.anchoredPosition localPos;}}// 如果鼠标左键释放if (Input.GetMouseButtonUp(0)){isRotating false;}}// 检测物体是否不可见private bool IsObjectInvisible(GameObject obj){// 获取物体的包围盒Bounds bounds obj.GetComponentRenderer().bounds;// 获取摄像机的视锥体平面Plane[] frustumPlanes GeometryUtility.CalculateFrustumPlanes(Camera.main);// 检查包围盒是否与视锥体相交return !GeometryUtility.TestPlanesAABB(frustumPlanes, bounds);}// 检测物体是否被遮挡private bool IsObjectOccluded(GameObject obj){// 获取摄像机到物体的方向Vector3 directionToTarget obj.transform.position - Camera.main.transform.position;// 发射射线Ray ray new Ray(Camera.main.transform.position, directionToTarget);RaycastHit hit;// 射线检测是否有其他碰撞器位于射线路径上if (Physics.Raycast(ray, out hit, directionToTarget.magnitude)){// 如果射线击中的物体不是目标物体则表示目标物体被遮挡if (hit.collider.gameObject ! obj){return true;}}return false;}
}重点
// 将物体的世界坐标转换为Canvas内的局部坐标Vector2 localPos;RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTransform, Camera.main.WorldToScreenPoint(selectedObject.transform.position), canvasCamera, out localPos);// 设置UI元素的位置为Canvas内的局部坐标localPos new Vector2(localPos.x - 249, localPos.y 70);uiImageRectTransform.localPosition localPos;