Unity学习笔记(一):第三人称镜头和人物移动

博主分享了在Unity中制作第三人称RPG游戏的初步尝试,包括使用Cinemachine的FreeLookCamera实现人物跟随和LookAt功能,以及创建ThirdPersonMovement脚本来处理键盘输入和人物移动。通过学习和实践,博主发现了镜头移动的不顺畅和视角体验的问题,并计划尝试不同的实现方法以优化游戏体验。
摘要由CSDN通过智能技术生成

凭借一腔热情,想着大学做点什么事,就想着做个游戏出来。之前没有接触过unity等各类引擎,学习了一段时间发现有许多地方挺复杂的,开个专栏记录一下学到的东西。

 基本目标是做一个RPG式的游戏,涉及的东西有很多:人物移动和镜头、战斗系统构建、UI构建等,先从基本的开始学起。

 关于第三人称镜头和人物移动,我们的目标是实现一个玩家能够随意移动镜头观察环境,同时人物在静止时不会受到镜头方向影响,而移动时会受到影响的移动系统,就是比较常见的第三人称移动系统。

第一种实现方式,我主要模仿了油管主Brackeys的实现https://www.youtube.com/watch?v=j48LtUkZRjU&list=PLPV2KyIb3jR5QFsefuO2RlAgWEz6EvVi6

套用一个插件cinemachine,使用其中的FreeLook Camera可以比较轻松的去实现人物的跟随和Lookat

 插件自带Folliw和LookAt,将人物拖进去即可

 

 X和Y Axis对应unity的x和y轴,值得注意的是unity的y轴对应的是竖轴。按照我们一般玩家的习惯,Input Axis Name栏的Mouse X和Y就是对应我们鼠标的移动,所以不用去修改。需要强调的是,我们设置镜头后,镜头的旋转是和我们鼠标对应的,也就是说鼠标向上拖拽时是看向下,向左拖拽时是看向右边,因此我在Y Axis 勾选了invert反转,而X Axis取消了invert。

Orbits的TopRig MiddleRig BottomRig对应下图的三个环,代表游戏时拖拽鼠标上中下能够看到的范围

 

 聚焦刚刚设置完的FreeLook Camera可以看到镜头的一个大概观察范围,蓝色十字中心便是镜头的中心(有时候会表示出黄点)。不同人物模型可能出现默认的聚焦中心不一样,如果觉得位置不符合我们的预期,可以在右边inspecter面板调出offset进行调整

 通过以上的设置,我们基本完成了镜头的跟随和聚焦,利用插件实现十分方便。之后重头戏便是人物移动,这一点需要我们去编写脚本了。

创建一个ThirdPersonMovement脚本

利用Input.GetAxisRaw()函数去实现键盘映射(可在设置修改映射默认键位)

   float horizontal = Input.GetAxisRaw("Horizontal");//对应键盘上的左右键,按下左或右时触发
   float vertical = Input.GetAxisRaw("Vertical");//对应键盘上的上下键,按下前或后时触发

建立映射后,将映射的方向保存在一个vector3变量中(normalized属性能够返回值为1的方向),之后引入if判断:如果该变量离原点大于0.01f  即有值映射入了direction,随后便可在if里实现移动

        Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;//建立一个矢量direction,其方向对应键盘输入的,各方向值为1
        if (direction.magnitude >= 0.01f)//magnitude返回矢量坐标到原点距离
        {
           
          
        }

 这一段是具体实现,老实说我自己也不太懂,属于是照葫芦画瓢地写上去了,大致意思是建立targetAngle表示人物需要转动的角度(转到镜头正对的方位),利用Mathf库的SmoothDampAngle函数和quaternion四元数实现较为平滑的转动,最后用CharacterController对象的move方法实现移动,最后在移动时乘上速度和Time.deltaTime去模拟正常行动

(关于unity脚本中最常见的update函数和这里用到的Time.deltaTime可以看这个理解:

(7条消息) Unity增量时间Time.deltaTime详解_ChinarCSDN的博客-CSDN博客

            float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
            float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
            transform.rotation = Quaternion.Euler(0f, angle, 0f);//函数第二个参数为转动的角度,上面一系列有关angle的代码是设置一个较为平滑的转动角度

            Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
            controller.Move(moveDir.normalized * speed * Time.deltaTime);

最后实现的全部代码如下(有关于动画和速度调整的部分)

using UnityEngine;

public class ThirdPlayerMovement : MonoBehaviour
{
    public CharacterController controller;//建立控制器对象
    public Transform cam;//建立摄像机的对象,数据类型是Transform类,对应主摄像机的转动
    public float walkSpeed=6f;//设置一个速度,浮点数类型
    public float runSpeed=10f;
    public float turnSmoothTime = 0.1f;
    public float turnSmoothVelocity;

    public Animator anim;

    private int isMove = Animator.StringToHash("isMove");
    private int isRunning = Animator.StringToHash("isRunning");


    private void Start()
    {
        //anim = this.GetComponent<Animator>();
        anim.SetBool(isMove, false);
        anim.SetBool(isRunning, false);
    }

    // Update is called once per frame
    void Update()
    {
        anim.SetBool(isMove, false);
        anim.SetBool(isRunning, false);
        float speed = walkSpeed;
        float horizontal = Input.GetAxisRaw("Horizontal");//对应键盘上的左右键,按下左或右时触发
        float vertical = Input.GetAxisRaw("Vertical");//对应键盘上的上下键,按下前或后时触发
        Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;//建立一个矢量direction,其方向对应键盘输入的,各方向值为1


        if(Input.GetKey("left shift"))
        {
            anim.SetBool(isRunning, true);
            speed = runSpeed;
        }
        if(Input.GetKey("w")||Input.GetKey("a")|| Input.GetKey("s")|| Input.GetKey("d"))
        {
            anim.SetBool(isMove, true);
        }
        if (direction.magnitude >= 0.01f)//magnitude返回矢量坐标到原点距离
        {
            //anim.SetBool("isMove", true);
            float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
            float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
            transform.rotation = Quaternion.Euler(0f, angle, 0f);//函数第二个参数为转动的角度,上面一系列有关angle的代码是设置一个较为平滑的转动角度

            Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
            controller.Move(moveDir.normalized * speed * Time.deltaTime);
        }
        //anim.SetBool("isMove", false);
        //if(Input.GetKey(KeyCode.))

    }
}

老实说我觉得这段代码在动画和速度控制上有点乱,整体结构也不是特别清晰,关于人物控制脚本的架构这一点我还需要学习一个

这段代码最后实现了一个和我们正常游玩较为相似的移动和镜头,但是我个人感觉依然有些别扭(一来镜头的移动有点不顺滑,二来镜头给我的感觉更像是电影镜头),本着学习的态度,我准备换一种方式去实现人物移动和镜头,到时对比哪个更合适。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值