撰写了文章 发布于 2018-09-19 15:32:17
【代码日志】unity中不同坐标系的坐标转换(常用于跨摄像机跟随)
unity中有多种坐标系,经常用到的是世界坐标系、屏幕坐标系和视窗(camera)坐标系三种。
其中世界坐标系和屏幕坐标系的相互转换常用于鼠标点击定位,拖拽等操作,也用于射线Ray的使用,常用的方法是:
pos = Camera.main.ScreenPointToRay(position); //屏幕转射线 pos = Camera.main.ScreenToWorldPoint(position);//屏幕转世界坐标 pos = Camera.main.WorldToScreenPoint(position);//世界转屏幕坐标
然后接下来说到游戏中常用的不同摄像机之间的视窗坐标的相互转化(例如UI摄像机和世界3D摄像机),多用于血条、按钮、弹窗等进行跟随和定位出现位置的功能。
下面是一个示例(UI跟随世界坐标系物体进行移动,这里的UI使用的是NGUI):
using UnityEngine;
using System.Collections;
public class UIFollow : MonoBehaviour {
public GameObject target; public Camera worldCamera; public Camera guiCamera;
void Awake() { }
public void LateUpdate() { worldCamera = NGUITools.FindCameraForLayer(target.layer); guiCamera = NGUITools.FindCameraForLayer(gameObject.layer);
Vector3 pos = worldCamera.WorldToViewportPoint(target.transform.position); if (pos.z >= 0) { pos = guiCamera.ViewportToWorldPoint(pos); pos.z = 0; transform.position = pos; } else { pos = guiCamera.ViewportToWorldPoint(pos); pos.z = guiCamera.farClipPlane + 10f; transform.position = pos; } }
}
简单注释一下:
首先取得被跟随的目标物体所在layer的相机,再取得跟随物体(这里是UI)的layer的相机。
然后获得目标物体的相机坐标,再使用ViewportToWorldPoint获得最终的UI的UI相机坐标。
此时如果在LateUpdate()进行赋值,表示一直跟随,如果是在start()或者方法中进行赋值,则表示单次确定位置。
最后说一下使用方法:
只需要把这个脚本扔到要跟随的UI上,再把被跟随的世界坐标的目标赋给target变量(使用控件拖动或者代码查询都可以)即可。
林荫 1年前
发布