说明
如图,红色球表示世界坐标中某个点A的位置,绿色方块表示UI坐标中某个点B的位置。
当前需要在屏幕中,基于点A算得其对应的点B(二者在屏幕中显示在同一位置)。
世界坐标到UI坐标 可使用GifCam来录制Gif.gif
该示意图中,绿色方块会从红色球位置移动至目标位置(图中Button的中心)。
用途:要在UI元素之前显示3D物体。如制作这样一个效果:在场景中击杀某个敌人后,从敌人身上飞出金币,飞向UI中显示金币数量的地方,以便能形象地表示获得金币。
关键代码
// _worldPosTrans:3D世界中的某物件,将其位置作为起点
Vector2 screenPos = Camera.main.WorldToScreenPoint(_worldPosTrans.position);
// 第一个参数是一个RectTransform,可以将UI中要挡在UI前的3D元素的父节点的RectTransform传入
// 相机参数要传入UI相机。
RectTransformUtility.ScreenPointToWorldPointInRectangle(_uiPosTrans.parent.GetComponent<RectTransform>(), screenPos, _uiCam, out Vector3 beginPos);
// 终点的z应小于实际的终点物件位置的Z坐标,以便能挡在终点物件之前。
var endPos = _uiElementTrans.position;
endPos.z--;
beginPos.z = endPos.z;
上述示意图用到的代码
Fan_WorldPosToUIPos.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fan_WorldPosToUIPos : MonoBehaviour
{
[SerializeField, Header("3D世界中的物体作为起点")]
private Transform _worldPosTrans;
[SerializeField, Header("UI下的3D物体")]
private Transform _uiPosTrans;
[SerializeField, Header("UI相机")]
private Camera _uiCam;
[SerializeField, Header("UI下的UI元素作为终点")]
private Transform _uiElementTrans;
private IEnumerator _testCoroutine;
private void Start()
{
Init();
}
private void Update()
{
MyUpdate();
}
private void OnDestroy()
{
MyDestroy();
}
private void Init()
{
}
private void MyUpdate()
{
if (Input.GetKeyDown(KeyCode.Space))
{
if (_testCoroutine != null)
{
StopCoroutine(_testCoroutine);
_testCoroutine = null;
}
_testCoroutine = TestCoroutine();
StartCoroutine(_testCoroutine);
}
}
private IEnumerator TestCoroutine()
{
Vector2 screenPos = Camera.main.WorldToScreenPoint(_worldPosTrans.position);
RectTransformUtility.ScreenPointToWorldPointInRectangle(_uiPosTrans.parent.GetComponent<RectTransform>(), screenPos, _uiCam, out Vector3 beginPos);
var endPos = _uiElementTrans.position;
endPos.z--;
beginPos.z = endPos.z;
_uiPosTrans.position = beginPos;
float duration = 1f;
float timer = 0f;
while (timer < duration)
{
_uiPosTrans.position = Vector3.Lerp(beginPos, endPos, timer / duration);
timer += Time.deltaTime;
yield return null;
}
_uiPosTrans.position = endPos;
}
private void MyDestroy()
{
}
}
网友评论