Unity中的坐标系转化

https://li-kang.gitbooks.io/unity-concise-course/content/Summary/coordinate.html


坐标系

在3D数学坐标系中,提到了以下3种坐标系。

  • 世界坐标系:以大家公认的原点和轴向建立的坐标系。
  • 物体坐标系:以物体位置和自身轴向建立的坐标系。
  • 惯性坐标系:以物体位置和世界坐标系轴向建立的坐标系。

世界坐标系

  • Unity的Scene面板中(0,0,0)的位置就是世界坐标系的原点。
  • 右上角示意图指明了世界坐标系的轴向。
transform.position; // 世界坐标系中物体的位置
transform.forward;  // 世界坐标系中物体的前方

物体坐标系

  • 选择一个物体时,检视面板Transform下的Position、Rotation、Scale指的是它在父物体坐标系中的位置、旋转、缩放。
  • 当一个物体没有指定父物体时,它的父物体就是世界。也就是说这时检视面板Transform下的Position正好是它在世界坐标系中的位置。
  • Unity引擎中物体保存的都是相对于父物体坐标系中的数据,所以当父物体变化(移动、旋转、缩放)时,子物体会同步变化。

[截图Transfrom面板]

transform.localPosition; // 在父物体坐标系中的位置
transform.localRotation; // 在父物体坐标系中的旋转
transform.localScale;    // 在父物体坐标系中的缩放

屏幕坐标系

  • 屏幕坐标系是2维的。
  • 屏幕坐标系是以屏幕左下角为(0,0), 右上角 (camera.pixelWidth, camera.pixelHeight)建立的坐标系。
Input.mousePosition; // 获取鼠标在屏幕坐标系中的位置

视口坐标系

  • 视口坐标系也是用来反应屏幕中位置的。
  • 视口坐标系使用的是屏幕宽度和高度的百分比,其左下角(0,0),右上角 (1,1)。
  • 视口坐标系适合用来在不同大小的屏幕间做适配。

GUI坐标系

  • 专门用与GUI的坐标系。
  • 与屏幕坐标是上下颠倒的。
  • 其左上角(0,0), 右下角 (Screen.width, Screen.hight)

坐标系的转换

  • GUI\屏幕间的转化
// 屏幕坐标与GUI坐标间的转化方面是一样的
Vector2 TransformScreenAndGui(Vector2 point) {
  Vector2 result;

  // x轴不变
  result.x = point.x;
  // y轴为屏幕高度减去原y坐标
  result.y = Screen.hight - point.y;

  return result;
}
  • 屏幕\视口\世界间的转化
// 屏幕转视口
Camera.main.ScreenToViewportPoint(Input.mousePosition); 

// 视口转屏幕
Camera.main.ViewportToScreenPoint(new Vector3(0.25F, 0.1F, 0));

// 屏幕转世界
// 转化后z轴不变
// 如果输入的是Vector2,转化后z轴大小为camera的z轴值
camera.ScreenToWorldPoint(Input.mousePosition);

// 世界转屏幕
camera.WorldToScreenPoint(target.transform.position);

// 视口转世界
camera.ViewportToWorldPoint(new Vector3(1, 1, camera.nearClipPlane));

// 世界转视口
camera.WorldToViewportPoint(target.transform.position);
  • 物体\世界间的转化
// 物体转世界坐标
transform.TransformPoint(3, 4, 5); 

// 世界转物体坐标
transform.InverseTransformPoint(3, 4, 5);

// 物体坐标系中的方向转到世界坐标方向
transform.TransformDirection(Vector3.forward);

// 世界坐标系中的方向转到物体坐标方向
transform.InverseTransformDirection(Vector3.forward);

运用举例

// 确定目标在屏幕的左边还是右边
using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public Transform target;
    Camera camera;

    void Start() {
        camera = GetComponent<Camera>();
    }

    void Update() {
        Vector3 viewPos = camera.WorldToViewportPoint(target.position);
        if (viewPos.x > 0.5F)
            print("target is on the right side!");
        else
            print("target is on the left side!");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值