阅读(4835)
赞(0)
Unity 3D 实践案例三
2020-07-11 12:01:16 更新
Unity 3D 中提供了第一人称和第三人称虚拟漫游组件,虚拟漫游可以提升游戏玩家对游戏产生的沉浸感。
本案例通过脚本实现第一人称虚拟漫游功能的实践操作,熟悉并掌握编写 Unity 3D 脚本实现游戏功能的方法。
案例设计
本案例采用 C# 脚本开发第一人称虚拟漫游功能。
构建简单的 3D 场景,使用 W
、S
、A
、D
键即可在场景内自由行走,还可以通过鼠标实现观察者视角的旋转功能。
案例实施
- 执行
GameObject
→3D Object
→Plane
命令创建一个平面。
- 执行
GameObject
→Create Empty
命令创建空物体,并将标签设为Player
。
一个标签是用来索引一个或一组游戏对象的词。标签是为了编程的目的而对游戏对象的标注,游戏开发人员可以使用标签来书写脚本代码,通过搜索找到包含想要的标签的对象。
添加标签方法很简单,选中 Inspector 面板右上方的 Tag
,点击 Add Tag
将在检视面板打开标签管理器,然后在里面输入 Player
。
然后再次选择空物体,在 Tag
的下拉列表中找到 Player
标签,完成添加标签。
- 为主角添加角色控制器组件。执行
Component
→Physics
→Character Controller
命令,如下图所示。
角色控制器主要用于第三人称或第一人称游戏主角控制,并不使用刚体物理效果,具体参数如下表所示。
参数 | 描述 | 功能 |
---|---|---|
Slope Limit |
坡度限制 | 限制碰撞器只能爬小于等于该值的斜坡 |
Step Offset |
台阶高度 | 角色可以迈上的最高台阶高度 |
Skin Width |
皮肤厚度 | 皮肤厚度决定了两个碰撞器可以互相渗透的深度 |
Min Move Distance |
最小移动距离 | 如果角色移动的距离小于该值,角色就不会移动 |
Center |
中心 | 该值决定胶囊碰撞器在世界空间中的位置 |
Radius |
半径 | 胶囊碰撞器的横截面半径 |
Height |
高度 | 胶囊碰撞器的高度 |
- 添加
Rigidbody
组件,取消选中Use Gravity
复选框,选中Is Kinematic
复选框使其不受物理影响,而是受脚本控制。
- 调整
Character Controller
的位置和大小,使其置于平面之上。
- 创建 C# 脚本,将其命名为
Player
。
- 输入如下代码:
using UnityEngine;
using System.Collections;
public class Player:MonoBehaviour{
public Transform m_transform;
//角色控制器组件
CharacterController m_ch;
//角色移动速度
float m_movSpeed=3.0f;
//重力
float m_gravity=2.0f;
void Start(){
m_transform=this.transform;
//获取角色控制器组件
m_ch=this.GetComponent<CharacterController>();
}
void Update(){
Control();
}
void Control(){
//定义3个值控制移动
float xm=0, ym=0, zm=0;
//重力运动
ym-=m_gravity*Time.deltaTime;
//前后左右移动
if(Input.GetKey(KeyCode.W)){
zm+=m_movSpeed*Time.deltaTime;
}else if(Input.GetKey(KeyCode.S)){
zm-=m_movSpeed*Time.deltaTime;
}
if(Input.GetKey(KeyCode.A)){
xm-=m_movSpeed*Time.deltaTime;
}else if(Input.GetKey(KeyCode.D)){
xm+=m_movSpeed*Time.deltaTime;
}
//使用角色控制器提供的Move函数进行移动
m_ch.Move(m_transform.TransformDirection(new Vector3(xm, ym, zm)));
}
}
上述代码主要是控制角色前后左右移动。
在 Start 函数
中,首先获取 CharacterController
组件,然后在 Control 函数
中通过键盘操作获得 X 和 Y 方向上的移动距离,最后使用 CharacterController
组件提供的 Move 函数
移动角色。
使用 CharacterController
提供的功能进行移动时,会自动计算移动体与场景之间的碰撞。
- 在 Hierarchy 视图中选中
Player
游戏对象,在其Inspector
属性面板中选择Component→Script
,选择Player
脚本将其链接到Player
游戏对象上。
- 此时运行测试,按 W、S、A、D 键可以控制主角前后左右移动,但是在 Game 视图中却观察不到主角在场景中移动的效果,这是因为摄像机还没有与主角的游戏对象关联起来,需要添加摄像机代码。打开 "Player.cs",添加如下代码:
//摄像机Transform
Transform m_camTransform;
//摄像机旋转角度
Vector3 m_camRot;
//摄像机高度
float m_camHeight=1.4f;
//修改Start函数, 初始化摄像机的位置和旋转角度
void Start(){
m_transform=this.transform;
//获取角色控制器组件
m_ch=this.GetComponent<CharacterController>();
//获取摄像机
m_camTransform=Camera.main.transform;
Vector3 pos=m_transform.position;
pos.y+=m_camHeight;
m_camTransform.position=pos;
//设置摄像机的旋转方向与主角一致
m_camTransform.rotation=m_transform.rotation;
m_camRot=m_camTransform.eulerAngles;
//锁定鼠标
Screen.lockCursor=true;
}
void Update(){
Control();
}
void Control(){
//获取鼠标移动距离
float rh=Input.GetAxis("Mouse X");
float rv=Input.GetAxis("Mouse Y");
//旋转摄像机
m_camRot.x-=rv;
m_camRot.y+=rh;
m_camTransform.eulerAngles=m_camRot;
//使角色的面向方向与摄像机一致
Vector3 camrot=m_camTransform.eulerAngles;
camrot.x=0;camrot.z=0;
m_transform.eulerAngles=camrot;
//操作角色移动代码
//使摄像机位置与角色一致
Vector3 pos=m_transform.position;
pos.y+=m_camHeight;
m_camTransform.position=pos;
}
上述代码通过控制鼠标旋转摄像机方向,使角色跟随摄像机的 Y 轴旋转方向,在移动角色时,使摄像机跟随角色运动。
- 单击
Play
按钮进行测试,效果如下图所示,通过鼠标操作可以在场景中旋转视角,通过 W、S、A、D 键可以在场景中向前、向后、向左、向右移动。