当前位置:   article > 正文

[ 游戏开发日记with Unity ] 没病走两步? 让你的Player动起来吧_player游戏对象加力运动实现原理

player游戏对象加力运动实现原理

写在前面

这个系列() 来自一个用Unity开发的2D横版射击游戏的开发过程,用来记录学习进度以及一些学习心得。和大家分享共勉,有错误的话请评论指出,我会积极回复。

=+=+=+=+=+=+=+=+=+=

那么,我们开始吧

=+=+=+=+=+=+=+=+=+=

前情提要

上一次,我们提到了Rigidbody2D以及Collider2D,总而言之,如果你希望你的物体运动、碰撞,那么是Collider2D在负责。而受力是Rigidbody2D的特性。 如果你希望创建一个拥有运动逻辑的活物,比如一个Player,给他一个Rigidbody2D

Question Again

在这里插入图片描述

你好,我是Player,你想让我动起来?凭啥?

确实,我们用什么方法让它动起来呢?你可能会说WASD,或者抄起你的手柄一通猛搓。
但是并没有什么用,因为你还什么都没写呢。
虽然你什么都没写,但是在这个时候其实你的输入已经被Unity读取了,这是通过我们的Input Manager实现的,你可以在Edit -> Project Settings -> Input Manager 里找到它。
在这里插入图片描述Like this ↑
有了这个,我们可以开始着手编写脚本Script了。

关 于 脚 本

脚本是你操纵Unity中的物体的遥控器,就像Minecraft的创造模式的控制台指令一样,你可以通过写下一些简单的代码来实现对组件参数定义操作。 同样地,你所需要的逻辑判断数值系统,也都需要写在脚本里。可以说,脚本就是一个物体的灵魂Soul

首先

确保你的Visual Studio有Unity支持组件,有C#编译环境
并且,确保你的Edit -> Preferences -> External Tools里面的External Script Editor是你正在使用的Visual Studio。
当然了,如果你不需要自动补全,也可以用记事本写代码,Unity无所谓的。

创建一个C# Script

在你这个项目的随便什么地方(我建议创建一个Scripts文件夹)里,右键新建一个C# Script,然后打开它。你可以将它命名为Player或者PlayerController或者aaabc之类的。
在这里插入图片描述你应该会看到这样的景象
在这里插入图片描述上面的using是库函数引用,你现在不用管他们。

  • CSDN是我给这个脚本的命名,你可以从上面的Tab看到。 它是一个public class公共的类,并且:继承了MonoBehaviour
  • MonoBehaviour是个啥? 它是一个继承了Component的脚本基类,所有的Unity脚本都得继承MonoBehaviour。当然, 如果你不需要Unity,自己写脚本,或者你的所有方法里都没有用到Unity提供的组件和函数,那你自然也不必要继承MonoBehaviour
  • 下面的两个方法Start() Update(),是我们获取Component和捕捉信号,判断逻辑的地方。
  • Start() 顾名思义,这个方法在对象被创建时用来初始化我们的脚本,获取一些必要的信息,比如我们需要的Rigidbody2D ,巧妇难为无米之炊,如果没有刚体,我们又怎么能让刚体运动呢?
  • Update() 更新方法,这个方法每一帧都会被执行一次,所以你不能将所有的代码内容放到这个里面,至少我不建议你这么做。我们需要在Update里面来读取一些基本的输入信息,更新/维护我们的人物状态。总而言之,在保证功能能够正常实现的情况下,Update里执行的代码行数越少越好。

现在,将手放到键盘上吧。

我们考虑实现运动所需要的组件是什么,因为我们要在Start()里面去获取它。
答案呼之欲出:Rigidbody2D
但是首先,我们需要在代码中先创建一个空的Rigidbody2D

[SerializeField] Rigidbody2D RB;
  • 1

你也可以不加[SerializeField]
将它改成public,这都是为了让我们能够在Unity里面看见这个属性,没错,这是脚本的一个属性,稍后我们需要将Player的Rigidbody2D组件拖动到Player的Player(Script)的这个位置。
在这里插入图片描述

然后,在你的Start()中写下这样一行:

RB = GetComponent<Rigidbody2D>();
  • 1

这样,我们就从脚本附着的对象上摘取了它的名为Rigidbody2D的Component了,我们就成功了一半了,接下来,你对RB做的所有改变,都能如实地在你的Player身上体现。

现在,输入吧。

Start()写完了,接下来让我们把目光转向Update()
我们该从Unity那里搞点输入数据过来了,没有输入数据的话我怎么给你算这个东西应该怎么运动啊(恼)

很多时候写脚本就像老妈子唠叨一样,跟Unity问这问那,有没有这个啊,整点这个,啊啊那我明白了,应该得是这样的吧,你看看怎么动一下子。

在Unity给我们提供的库里,有这样的一系列方法,他们叫Input,一般来说,你可以从他们的名字来读出他们的用处,前提是你认识那些词汇的话,当然不认识也没关系,可以翻译一下,词汇量非常少。比如我们这里用到的

direction = Input.GetAxis("Horizontal");
  • 1

在C#中,.是一种声明父子关系的符号,所以Input.GetAxis("Horizontal")就是Input类里面的一个用来获取某一条轴上的输入的方法。它返回一个-1~1的浮点数"Horizontal"是它的参数,你也可以改成"Vertical"或者其它的什么轴,总之,现在我们的direction就是你的输入数值。(噢,别忘了声明direction作为一个float变量,然后设置合适的权限,比如private,这个我就不多赘述了)

  • 手柄上,这个数值和你推摇杆的轻重正相关
  • 然而键盘的话这个数字会以极快的速度变化到极大或极小值。
    因为这个原因,我们在做键盘输入的时候,也可以不使用GetAxis方法,而一转使用GetAxisRawGetAxisRaw只会返回-1,0,1之中的一个数。
    当然了,你也可以使用GetButtonDown或者GetKeyDown,不知道怎么用的话,将鼠标悬停在他们的名字上,你可以看到这个方法的使用手册。
    在这里插入图片描述在这里插入图片描述
    接下来,我们希望在我们输入之后,物体朝着我们想要的方向运动。

Pull Your Mind Out Now

在现实中,我们希望一个物体运动,有什么办法呢?
给一个力推它,给它一个速度(当然现实中你无法给瞬时速度),或者使用传送魔法
好消息是,这些方法在Unity中都能实现,你猜猜哪种最好用?

Come Back To Script

这一部分代码你可以写在Update()中或者是FixedUpdate()中,因为你需要时刻检测物体是否运动。

  • Update() 检测周期 T = 1/fps(s) fps是你的电脑帧率
  • FixedUpdate() 检测周期 T = 1/50(s)
    首先我们忽略传送术,就算是Dash,我们也不是将人物直接传送到目标位置。直接修改坐标的方法我们留到有用的时候再说。
    那么现在还剩两种方法:调用刚体的AddForce方法和直接修改刚体的velocity属性
AddForce

它提供了一个加速度,这意味着你的物体在你的按键下会做一个匀加速直线运动,不可或缺地,这样方式操作的运动会有一个很平滑的速度曲线,像Mario里面的黄油手感一样。AddForce方法有两种施力模式,默认下是Force,也就是原力 ,你还可以通过在第一个参数后再加一个参数声明ForceMode2D.Impulse,如此一来,就算你按住,这个力也只会被施加一次给这个刚体,你可以看成提供了一个碰撞冲量。

  • 写法是这样的
RB.AddForce(Vector2D.right * force);
  • 1

整个参数是一个二维向量force是我们自己定义的一个推力大小,建议设置成float类型。而Vector2D.right其实就是new Vector2D(1,0)的简便写法。

如此一来,我们就添加了一个二维的恒力。它会提供一个恒定的 (大概) 加速度。 现在回到Unity里,开始你的Game,人物应该能左右平移了。

velocity

相似地,我们也可以通过直接设置刚体的速度velocity来实现移动的效果,事实上,我正在使用的以及比较推荐初学者使用的就是这种。
像下面这样使用:

RB.velocity = new Vector2(direction * speed, RB.velocity.y);
  • 1

我们新建一个二维向量,x是我们的输入乘以速度系数speed,同样是一个需要定义的float变量。而y是刚体目前的纵向速度。我们在左右移动时不希望垂直速度被改变,所以这样引用。你会发现,形如RB.velocity.y这样的引用,你可以把.翻译成
所以这一条的意思就是RB速度velocityy轴投影大小

Tip here

这样写完之后,你的人物理论上就可以以一个匀速在大部分时间内运动了,当然,速度不会突变,就像现实中那样。起步由于前面提到键盘输入的累加性,必然是一个加速的过程,然后匀速。
如此你会发现,在你松开方向键时,你其实是希望他马上停下来的,然而他会因为输入延迟等因素向前滑行一小段。有可能使血压升高
所以我推荐这样的写法:

if (Mathf.Abs(direction) > 0.2f)//0.2f的意思是一个大小为0.2的浮点数
        {
            RB.velocity = new Vector2(direction * speed, RB.velocity.y);

        }
        else
        {
            RB.velocity = new Vector2(0, RB.velocity.y);
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

也就是在输入绝对值小于0.2时,我们认为用户根本没在输入了,因为这个值足够小,以致于推手柄都不太好达到这个值以下。于是我们将水平速度设置为0

大功告成!

现在,你的人物可以左右移动了,今天我们写了第一个C#脚本,这是珍贵的一步,代表着你正式开始使用Unity了!

试着自己写写跳跃的代码

虽然,现在离你心目中的运动还有很大区别,首先,人物不会掉头,而且,他也没有跑步的动作。有关于贴图Sprite动画机Animator状态控制我们将在下一期进行讲解

To be Continued…

See U!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/89680
推荐阅读
相关标签
  

闽ICP备14008679号