Camera.ScreenToWorldPoint

本文详细解释了如何使用Camera.ScreenToWorldPoint方法将屏幕坐标转换为世界坐标,并通过实例展示了参数中Z坐标的含义及其作用。

Camera.ScreenToWorldPoint
Vector3 ScreenToWorldPoint(Vector3 position);

将屏幕坐标转换为世界坐标。

如何转换?假如给定一个所谓的屏幕坐标(x,y,z),如何将其转换为世界坐标?

首先,我们要理解摄像机是如何渲染物体的:

摄像机对游戏世界的渲染范围是一个平截头体,渲染边界是一个矩形,用与near clippingplane或者far clippingplane平行的平面截取这个平截头体,可以获得无数个平行的矩形面,也就是我们看到的屏幕矩形。离摄像机越远,矩形越大,离摄像机越近,矩形越小。所以,同样大小的物体,随着离摄像机越来越远,相对于对应屏幕矩形就越来越小,所看起来就越来越小。

在屏幕上,某个像素点相对于屏幕矩形的位置,可以对应于游戏世界中的点相对于某个截面的位置,关键在于这个点在哪个截面上,也就是说,关键在于这个截面离摄像机有多远!

 

在ScreenToWorldPoint这个方法中,参数是一个三维坐标,而实际上,屏幕坐标只能是二维坐标。参数中的z坐标的作用就是:用来表示上述平面离摄像机的距离。

也就是说,给定一个坐标(X,Y,Z),

首先截取一个垂直于摄像机Z轴的,距离为Z的平面P,这样不管X,Y怎么变化,返回的点都只能在这个平面上;

然后,X,Y表示像素坐标,根据(X,Y)相对于屏幕的位置,得到游戏世界中的点相对于截面P的位置,我们也就将屏幕坐标转换为了世界坐标。

 

官网文档中的说法:

Camera.ScreenToWorldPoint
 
 Vector3 ScreenToWorldPoint(Vector3 position);
Description
 Transforms position from screen space into world space.
  
  Screenspace is defined in pixels. The bottom-left of the screen is (0,0); the right-top is (pixelWidth,pixelHeight). The z position is in world units from the camera.

using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour {
    void OnDrawGizmosSelected() {
        Vector3 p = camera.ScreenToWorldPoint(new Vector3(100, 100, camera.nearClipPlane));
        Gizmos.color = Color.yellow;
        Gizmos.DrawSphere(p, 0.1F);
    }
}


 

using UnityEngine; /// <summary> /// 坐标转换工具 /// </summary> public static class CCUtils { /// <summary> /// 世界坐标转屏幕坐标 /// </summary> public static Vector2 World2Screen(Vector3 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 worldPos = v; Vector3 pos = camera.WorldToScreenPoint(worldPos); return pos; } /// <summary> /// 屏幕坐标转世界坐标 /// </summary> public static Vector3 Screen2World(Vector2 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 screenPos = new Vector3(v.x, v.y, -camera.transform.position.z); Vector3 pos = camera.ScreenToWorldPoint(screenPos); return pos; } /// <summary> /// 世界坐标转视口坐标 /// </summary> public static Vector2 World2Viewport(Vector3 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 worldPos = v; Vector3 pos = camera.WorldToViewportPoint(worldPos); return pos; } /// <summary> /// 视口坐标转世界坐标 /// </summary> public static Vector3 Viewport2World(Vector2 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 viewportPos = new Vector3(v.x, v.y, -camera.transform.position.z); Vector3 pos = camera.ViewportToWorldPoint(viewportPos); return pos; } /// <summary> /// 屏幕坐标转视口坐标 /// </summary> public static Vector2 Screen2Viewport(Vector2 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 screenPos = v; Vector3 pos = camera.ScreenToViewportPoint(screenPos); return pos; } /// <summary> /// 视口坐标转屏幕坐标 /// </summary> public static Vector2 Viewport2Screen(Vector2 v, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 viewportPos = v; Vector3 pos = camera.ViewportToScreenPoint(viewportPos); return pos; } /// <summary> /// 屏幕坐标转UI坐标 /// </summary> public static Vector2 Screen2UI(Vector2 v, RectTransform rect, Camera camera = null) { Vector2 pos; RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, v, camera, out pos); return pos; } /// <summary> /// 世界坐标转UI坐标 /// </summary> public static Vector2 World2UI(Vector3 v, RectTransform rect, Camera uiCamera, Camera worldCamera = null) { if (worldCamera == null) { worldCamera = Camera.main; } Vector2 screenPos = World2Screen(v, worldCamera); Vector2 pos = Screen2UI(screenPos, rect, uiCamera); return pos; } }
最新发布
10-30
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值