kingBook

导航

Unity Camera

透视相机

Field of View:

//设置FOV Axis=Vertical时,fieldOfView的值为45f。
m_camera.fieldOfView=45f;//m_camera.fieldOfView 永远指的都是竖直方向上展开角度(水平方向的展开角度是根据camera.aspect计算出来的)
//设置FOV Axis=Horizontal时,fieldOfView的值为45f。
m_camera.fieldOfView=2f*Mathf.Atan(Mathf.Tan(45f*Mathf.Deg2Rad*0.5f)/m_camera.aspect)*Mathf.Rad2Deg;

设置相机剪裁面的宽高比:

m_camera.aspect=640f/960f;

设置一个透视相机始终看向目标,且不管相机距离物体多远,物体宽度都能占满屏幕的宽。

float distance=100f;   //相机到物体的距离
float objectWidth=50f; //物体的宽
float slope=(objectWidth*0.5f)/distance;//物体一半宽/距离
m_camera.fieldOfView=2f*Mathf.Atan(slope/m_camera.aspect)*Mathf.Rad2Deg;

计算指定距离相机剪裁面的宽高:

float distance=20f;//剪裁面的距离
float halfFOV=(m_camera.fieldOfView*0.5f)*Mathf.Deg2Rad;
float height=distance*Mathf.Tan(halfFOV);
float width=height*m_camera.aspect;
正交相机

如:相机的大小为800x480,要使相机适应800x480像素的图,则
  Size = 相机高/2/像素单位
     = 480/2/100
     = 2.4
在设计分辨率下有如下公式:
\(屏幕的宽高比Aspect Ratio=\frac{屏幕宽度}{屏幕高度}=\frac{摄像机实际宽度}{摄像机实际高度}=\frac{摄像机实际宽度}{摄像机orthographicSize \times 2}\)

//世界坐标系640*640像素的矩形(640/100/2=3.2,960/100/2=4.8)
Vector2 rectExtents=new Vector2(3.2f,4.8f);

float referenceScaleFactor=rectExtents.x/rectExtents.y;
float scaleFactor=(float)Screen.width/Screen.height;

if(scaleFactor>referenceScaleFactor){
	//设置正交相机适应高度
	m_camera.orthographicSize=rectExtents.y;
}else if(scaleFactor<referenceScaleFactor){
	//设置正交相机适应宽度
	m_camera.orthographicSize=rectExtents.x/scaleFactor;
}
屏幕坐标转世界坐标
Camera cam=Camera.main;
Vector3 screenPoint=Input.mousePosition;
screenPoint.z=10; //z轴表示从相机的位置向前的偏移量(并不是z轴的距离,因为会受到相机旋转的影响)
Vector3 worldPoint=cam.ScreenToWorldPoint(screenPoint);
transform.position=worldPoint;
获取屏幕点的射线与空间平面的交点
Vector3 GetScreenRayCastToPlanePoint(Vector3 screenPoint,Camera camera,Plane plane){
	Vector3 result=Vector3.zero;
	Ray ray=camera.ScreenPointToRay(screenPoint);
	if(plane.Raycast(ray,out float enter)){
		result=ray.GetPoint(enter);
	}else{
		throw new Exception("射线没有穿过平面,即射线与平面平行或射线方向与平面相反。");
	}
	return result;
}
通过移动相机位置使观察对象与鼠标对齐
using UnityEngine;
/// <summary>
/// 通过移动相机位置使观察对象与鼠标对齐
/// </summary>
public class MoveCameraAlignMouse:MonoBehaviour{
	//观察对象的Transform
	public Transform objTransform;
	//主相机
	private Camera cam;
	//观察对象与相机的z轴距离
	private float dz;

	private void Start(){
		cam=Camera.main;
		//计算观察对象与相机的z轴距离
		Vector3 objWorldPos=objTransform.position;
		dz=objWorldPos.z-cam.transform.position.z;
	}

	private void Update(){
		if(Input.GetMouseButton(0)){
			//相机绕观察对象旋转任意角度
			cam.transform.RotateAround(objTransform.position,new Vector3(Random.value,Random.value,Random.value),10);
			//观察对象的位置
			Vector3 objWorldPos=objTransform.position;
			//计算鼠标位置的世界坐标(将通过移动相机位置使观察对象与鼠标对齐)
			Vector3 targetScreenPos=Input.mousePosition;
			targetScreenPos.z=dz;
			Vector3 targetWorldPos=cam.ScreenToWorldPoint(targetScreenPos);
			//相机需要偏移的向量
			Vector3 offsetWorld=objWorldPos-targetWorldPos;
			cam.transform.Translate(offsetWorld,Space.World);
		}
	}

}

posted on 2020-09-12 18:49  kingBook  阅读(477)  评论(0编辑  收藏  举报