Unity3D 关于相机 Camera 的使用
文章目录
一、Unity3D 中的 Camera 介绍
- 正如电影中使用摄像机向观众展现故事一样,Unity 中的摄像机用于向玩家展示游戏世界。在场景中至少要有一个摄像机,但也可以有多个摄像机。多个摄像机可以提供双人分屏或营造高级自定义效果。
- Unity 场景是通过在三维空间中放置并移动对象来创建的。由于观察者的屏幕是二维屏幕,因此需要通过一种方法来捕捉视图并将其“平面化”以进行显示。该过程通过摄像机完成。
1. 相机的机位
- 透视与正交
- 现实世界中的摄像机在观察外界事物时,物体距离视点越远,看起来越小。这就是“透视效果”。Unity 中也支持透视摄像机,而显示的对象不随距离变远而缩小的摄像机称为正交摄像机
- 如下图,在相机的属性设置里可以选择用透视还是正交
① 透视摄像机
-
用透视的方式渲染游戏对象
-
效果:远小近大,有距离之分,如有一个模型放在相机距离较近,那么就会显示的特别大,相反距离越远就越小。如下图所示,靠近摄像机的人物模型比远处的看起来大
② 正交摄像机
- 用无透视的方式来渲染游戏对象
- 效果:没有远小近大,没有距离之分。如两个一样大的物体放在相机有不同的位置,看不出来谁前谁后
- size 用于控制正交模式摄像机的视口大小。
2. 摄像机视图的背景
- 摄像机可以用一些对象填充空白空间。比如使用摄像机的 Background属性来设置背景颜色,在检视面板或脚本中进行操作。
- 或者使用天空盒 (Skybox)。摄像机被有效地放置在此盒体的中央,并可从各个方向观察天空。天空盒是在场景中所有对象的后面渲染,因此表现了一个无限远的视图。
- 添加完天空盒后的相机拍到的场景
二、Camera 的属性
1. 属性的具体功能如下
属性 | 功能 |
---|---|
Clear Flags | 确定将清除屏幕的哪些部分 |
Background | 在绘制视图中的所有元素之后但没有天空盒的情况下,应用于剩余屏幕部分的颜色 |
Culling Mask | 包含或忽略要由摄像机渲染的对象层。 |
Clipping Planes | 开始和停止渲染位置到摄像机的距离 |
Viewport Rect | 通过四个值指示将在屏幕上绘制此摄像机视图的位置。在视口坐标中测量 |
Depth | 摄像机在绘制顺序中的位置。具有更大值的摄像机将绘制在具有更小值的摄像机之上 |
Rendering Path | 定义摄像机将使用的渲染方法的选项 |
Target Texture | 引用将包含摄像机视图输出的渲染纹理。设置此引用将禁用此摄像机的渲染到屏幕功能 |
Occlusion Culling | 为此摄像机启用遮挡剔除 |
HDR | 为此摄像机启用高动态范围渲染 |
MSAA | 为此摄像机启用多重采样抗锯齿 |
Allow Dynamic Resolution | 为此摄像机启用动态分辨率渲染 |
Target Display | 定义要渲染到的外部设备 |
2. 具体介绍某些常用属性
① ClearFlags
ClearFlags | 把空白的地方显示 |
---|---|
Skybox | 天空盒子 |
Solider Color | 纯色显示 |
Depth | 显示物体只看深度高低 |
Don’t Clear | 只显示物体,其他都不显示 |
② Culing Mask 层次显示
- 设置相机取消 UI 这个勾,发现游戏视图看不到血条模型了
③ Viewport Rect 视口显示器
- 可以设置多机位
- 设置偏移量: x y 范围是 0 ~1;设置长度:w h 范围是 0 ~ 1;
三、如何提升使用 Camera 的体验
1. 让摄像机始终跟随某个物体移动
- 挂载如下脚本到摄像机上,设置相机一直跟随玩家移动,实现第三人称游戏视角
public GameObject follow; // 跟随的玩家
public float speed = 5.0f; // 相机跟随的速度
Vector3 offset; // 相机与玩家相对偏移位置
void Start()
{
offset = transform.position - follow.transform.position;
}
void FixedUpdate()
{
// 摄像机自身位置到目标位置平滑过渡
Vector3 target = follow.transform.position + offset;
transform.position = Vector3.Lerp(transform.position, target, speed * Time.deltaTime);
}
- 效果如下
2. 使某一游戏对象一直面向摄像机
- 添加以下脚本 LookAtCamera.cs
public class LookAtCamera : MonoBehaviour
{
void Update()
{
this.transform.LookAt(Camera.main.transform.position);
}
}
- 效果如下
3. 用键盘控制相机的移动
- 添加以下脚本,按下 wasd 键相机镜头会向着前后左右移动
//巡游模式摄像机控制
public class CameraMove : MonoBehaviour
{
public static CameraMove Instance = null;
private Vector3 dirVector3;
private Vector3 rotaVector3;
private float paramater = 0.1f;
//旋转参数
private float xspeed = -0.05f;
private float yspeed = 0.1f;
void Awake()
{
Instance = this;
}
private void Start()
{
rotaVector3 = transform.localEulerAngles;
}
// Update is called once per frame
void FixedUpdate()
{
//旋转
if (Input.GetMouseButton(1))
{
rotaVector3.y += Input.GetAxis("Horizontal") * yspeed;
rotaVector3.x += Input.GetAxis("Vertical") * xspeed;
transform.rotation = Quaternion.Euler(rotaVector3);
}
//移动
dirVector3 = Vector3.zero;
if (Input.GetKey(KeyCode.W))
{
if (Input.GetKey(KeyCode.LeftShift))
dirVector3.z = 3;
else
dirVector3.z = 1;
}
if (Input.GetKey(KeyCode.S))
{
if (Input.GetKey(KeyCode.LeftShift))
dirVector3.z = -3;
else
dirVector3.z = -1;
}
if (Input.GetKey(KeyCode.A))
{
if (Input.GetKey(KeyCode.LeftShift))
dirVector3.x = -3;
else
dirVector3.x = -1;
}
if (Input.GetKey(KeyCode.D))
{
if (Input.GetKey(KeyCode.LeftShift))
dirVector3.x = 3;
else
dirVector3.x = 1;
}
if (Input.GetKey(KeyCode.Q))
{
if (Input.GetKey(KeyCode.LeftShift))
dirVector3.y = -3;
else
dirVector3.y = -1;
}
if (Input.GetKey(KeyCode.E))
{
if (Input.GetKey(KeyCode.LeftShift))
dirVector3.y = 3;
else
dirVector3.y = 1;
}
transform.Translate(dirVector3 * paramater, Space.Self);
}
}
- 效果如下