• 用Unity实现Minecraft中的镜头控制


    在学习Unity的过程中,最基本而又最重要的一部分就是镜头控制(Camera Control)

    镜头控制就是通过鼠标、键盘等输入设备的操作,来实现在游戏中的导航。在Unity中的本质是通过接收鼠标的移动和键盘的按键,来变换相机对象(Camera)的位置(position)和旋转(rotation),这两个值位于cameratransform组件(conponent)中。

    在这里我们通过实现《我的世界》中创造模式的镜头控制方式来学习第一人称的镜头控制。

    在我的世界中,镜头的朝向(旋转)是通过鼠标在XY方向的平移来控制的,镜头的前后左右移动是通常的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进行移动。

    细节解析

    1. 镜头平移控制

    镜头的平移实际上是在检测到键盘上WASD、空格、Shift的按下后,修改camera.transform.positonx, y, z分量。

    在这里我们需要注意的是,y分量也就是升起和降落,是永远平行于世界坐标系的y轴的,所以直接修改y分量即可:

    transform.position -= new Vector3 (0, 0.1f, 0);

    但是对于前进后退和左右平移是不一样的,因为我们在这四个方向的移动还和我们面朝的方向有关。所以我们通过tansform.forwardtransform.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

  • 相关阅读:
    技术问答集录(二)(RPC和MVC框架&syn,lock区别)
    Zookeeper同一台机器集群部署
    Linux——JDK安装
    VirtualBox CentOs7 设置ssh连接

    ThreadLocal
    关于Centos 7上面的防火墙配置
    windows下使用命令行关闭进程
    强类型 弱类型语言 静态 动态语言
    无法启动此程序 ,因为计算机中丢失MSVCP120.dll
  • 原文地址:https://www.cnblogs.com/jarvisniu/p/5506524.html
Copyright © 2020-2023  润新知