用Unity实现Minecraft中的镜头控制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用Unity实现Minecraft中的镜头控制相关的知识,希望对你有一定的参考价值。
在学习Unity的过程中,最基本而又最重要的一部分就是镜头控制(Camera Control)。
镜头控制就是通过鼠标、键盘等输入设备的操作,来实现在游戏中的导航。在Unity中的本质是通过接收鼠标的移动和键盘的按键,来变换相机对象(Camera)的位置(position)和旋转(rotation),这两个值位于camera的transform组件(conponent)中。
在这里我们通过实现《我的世界》中创造模式的镜头控制方式来学习第一人称的镜头控制。
在我的世界中,镜头的朝向(旋转)是通过鼠标在X和Y方向的平移来控制的,镜头的前后左右移动是通常的WASD键,升起(向上移动)为空格键,降落(向下移动)为Shift键。
下面我先给出完整代码和Demo的建立步骤。运行成功后,我们再进行代码剖析。
建立Demo
1. 新建一个Unity项目。
2. 将下面代码保存为BasicCameraControl.cs,放到Unity项目的Assets文件夹下。
using UnityEngine; using System.Collections; public class BasicCameraControl : MonoBehaviour { float yaw = 0; // 偏航角,绕Y轴旋转的角度 float pitch = 0; // 俯仰角,绕Z轴旋转的角度 const float roll = 0; // 翻滚角,绕X轴旋转的角度 void FixedUpdate () { // Move forward or backward if (Input.GetKey (KeyCode.W)) transform.position += Vector3.ClampMagnitude (transform.forward, 0.1f); else if (Input.GetKey (KeyCode.S)) transform.position -= Vector3.ClampMagnitude (transform.forward, 0.1f); // Move left or right if (Input.GetKey (KeyCode.A)) transform.position -= Vector3.ClampMagnitude (transform.right, 0.1f); else if (Input.GetKey (KeyCode.D)) transform.position += Vector3.ClampMagnitude (transform.right, 0.1f); // Move up or down if (Input.GetKey (KeyCode.Space)) transform.position += new Vector3 (0, 0.1f, 0); else if (Input.GetKey (KeyCode.LeftShift)) transform.position -= new Vector3 (0, 0.1f, 0); // Rotate pitch -= Input.GetAxis ("Mouse Y") * 5; pitch = Mathf.Clamp (pitch, -90, 90); yaw += Input.GetAxis ("Mouse X") * 5; transform.rotation = Quaternion.Euler (pitch, yaw, roll); } }
3. 为场景中的默认相机对象(Main Camera)添加此脚本组件。具体做法为,选择Main Camera,在Inspector中点击底部的Add Component按钮,点击Scripts菜单,点击Basic Camera Control完成。
4. 在场景的中心位置添加一些物体作为移动相机时的参照,比如一个正方体(Cube)。
5. 点击Play按钮,移动鼠标进行转向,按下WASD、空格和Shift进行移动。
建立Demo
1. 镜头平移控制
镜头的平移实际上是在检测到键盘上WASD、空格、Shift的按下后,修改camera.transform.positon的x, y, z分量。
在这里我们需要注意的是,y分量也就是升起和降落,是永远平行于世界坐标系的y轴的,所以直接修改y分量即可:
transform.position -= new Vector3 (0, 0.1f, 0);
但是对于前进后退和左右平移是不一样的,因为我们在这四个方向的移动还和我们面朝的方向有关。所以我们通过tansform.forward和transform.right获取朝向然后与与transform.position进行加减。
使用Vector3.ClampMagnitude()函数是为了减慢移动速度到合适的程度。
2.镜头旋转控制
关于镜头的旋转我们或许可以用下面的一行代码实现:
transform.Rotate (- Input.GetAxis ("Mouse Y") * 5, Input.GetAxis ("Mouse X") * 5, 0);
但是这样无法保证我们的镜头始终与地面保持垂直。通过在屏幕上不断地画圆圈,我们可以实现倒立。我们不是杂技团,所以这肯定不是我们想要的。
为了避免这种情况发生,我们通过先对旋转角的分量进行偏移,然后再用Quaternion.Euler()函数转换为四元数即可。
3.为什么用FixedUpdate()
Update()与FixedUpdate()的区别是Update()是随渲染(Render)过程发生的。而FixedUpdate()是按照固定的周期发生的,也就是说即使由于画面上人物众多,刷新率降低,也能保证函数执行的次数恒定。
了解到这些,我们就可以设想。假如我们在Minecraft中进行一场赛跑,一台高配台式电脑以60FPS运行,而一台笔记本以平均30FPS运行。如果我们用Update()来驱动人物运动的话,那么笔记本上的人物肯定移动没有台式机快。这样肯定不符合公平的原则,所以我们在这里必须使用FixedUpdate()。
【End】
以上是关于用Unity实现Minecraft中的镜头控制的主要内容,如果未能解决你的问题,请参考以下文章
[Unity3D] 多人游戏中镜头固定角度、随角色移动的实现方式
Unity3D镜头抖动怎么做?比如发生爆炸后场景的抖动(用镜头抖动或者画面抖动实现),跪求高手回答!
unity人物第一人称视角制作角色身体遮挡主镜头去掉方法,用VFX自制子弹拖尾效果。