阅读(4835) (0)

Unity 3D 实践案例三

2020-07-11 12:01:16 更新

Unity 3D 中提供了第一人称和第三人称虚拟漫游组件,虚拟漫游可以提升游戏玩家对游戏产生的沉浸感。

本案例通过脚本实现第一人称虚拟漫游功能的实践操作,熟悉并掌握编写 Unity 3D 脚本实现游戏功能的方法。

案例设计

本案例采用 C# 脚本开发第一人称虚拟漫游功能。

构建简单的 3D 场景,使用 WSAD键即可在场景内自由行走,还可以通过鼠标实现观察者视角的旋转功能。

案例实施

  1. 执行 GameObject3D ObjectPlane 命令创建一个平面。

  1. 执行 GameObjectCreate Empty 命令创建空物体,并将标签设为 Player

一个标签是用来索引一个或一组游戏对象的词。标签是为了编程的目的而对游戏对象的标注,游戏开发人员可以使用标签来书写脚本代码,通过搜索找到包含想要的标签的对象。

添加标签方法很简单,选中 Inspector 面板右上方的 Tag,点击 Add Tag 将在检视面板打开标签管理器,然后在里面输入 Player

然后再次选择空物体,在 Tag 的下拉列表中找到 Player 标签,完成添加标签。

  1. 为主角添加角色控制器组件。执行 ComponentPhysicsCharacter Controller 命令,如下图所示。

角色控制器主要用于第三人称或第一人称游戏主角控制,并不使用刚体物理效果,具体参数如下表所示。

参数 描述 功能
Slope Limit 坡度限制 限制碰撞器只能爬小于等于该值的斜坡
Step Offset 台阶高度 角色可以迈上的最高台阶高度
Skin Width 皮肤厚度 皮肤厚度决定了两个碰撞器可以互相渗透的深度
Min Move Distance 最小移动距离 如果角色移动的距离小于该值,角色就不会移动
Center 中心 该值决定胶囊碰撞器在世界空间中的位置
Radius 半径 胶囊碰撞器的横截面半径
Height 高度 胶囊碰撞器的高度

  1. 添加 Rigidbody 组件,取消选中 Use Gravity 复选框,选中 Is Kinematic 复选框使其不受物理影响,而是受脚本控制。

  1. 调整 Character Controller 的位置和大小,使其置于平面之上。

  1. 创建 C# 脚本,将其命名为 Player

  1. 输入如下代码:

    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 提供的功能进行移动时,会自动计算移动体与场景之间的碰撞。

  1. 在 Hierarchy 视图中选中 Player 游戏对象,在其 Inspector 属性面板中选择 Component→Script,选择 Player 脚本将其链接到 Player 游戏对象上。

  1. 此时运行测试,按 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 轴旋转方向,在移动角色时,使摄像机跟随角色运动。

  1. 单击 Play 按钮进行测试,效果如下图所示,通过鼠标操作可以在场景中旋转视角,通过 W、S、A、D 键可以在场景中向前、向后、向左、向右移动。