Unity——角色行走#01

在Unity中实现角色行走时会遇到林林总总的问题,这里就记录一下我遇到的问题并提供解决方法。

由于本人是零基础自学,可能会出现一些很基本的问题,记录成长为主。

1.玩家键盘的输入转为移动信号

    玩家的输入一般由两种形式,一是键盘输入,二是手柄输入,这里暂且只考虑键盘输入。一般移动的输入键是wasd亦或是↑↓←→。而移动信号的表现形式为一个二维坐标轴:

    我们要做的就是当玩家键入W时,记录坐标轴的xy变量分别为(1,0);另外还要考虑冲突问题,当玩家同时键入AD时xy变量应为(0,0),角色应静止不动。

    由此我们可以写下如下代码:

    显然targetUp为x坐标,targetRight为y坐标。剩下要做的就是添加blend tree和动画,把blend tree(Blend Type为1D)的参数与信号联系起来,这是后话了。

2.平滑移动的问题

    按上述实现的代码的话,不难发现:当玩家键入W,角色会从静止立刻到播放行走的动画,即0直接变为1,这就很突兀,动画播放上会不连贯。解决这个问题的根本就是0应该匀速增长到1或是1匀速减少到0。恰好Mathf类提供了这么一个方法:


SmoothDamp

    这个函数能实现从一个三维坐标向一个理想值地逐渐转变。由图知此函数需要一个当前的坐标值、一个目标坐标值、一个当前速度的三维坐标引用,一个平滑时间的浮点值。其中的3个不难理解,平滑时间就是规定完成这个过程的时间,但这个currentVelocity需要解释一下,按照官网的描述,当你每一次调用这个函数时,这个值都会被修改,那么其实就提供一个不用初始化的Vector3变量就好,其余的SmoothDamp会自己搞定。


SmoothDamp

    targetUp呢就是刚才得到的硬邦邦的不是0就是1的值,显然这个就是目标值,需要匀速增长或减少到这个值;Dup呢就是初始值,是增长或减少前的值。当Dup为0时,targetUp为1时,就从0增到1;当targetUp变回0时,此时Dup是1,就从1减到0。

    这个处理其实与Blend Tree里的参数是很符合的。

3.转向问题

    转向问题其实就是改变角色当前向前的方向的问题(forward)。一开始用的是坐标轴的坐标做信号,现在可以换个方式,用距坐标轴原点的距离做移动的信号,配合上单位向量,就能解决转向和斜向走的问题。

    设置一变量记录距原点的距离:勾股定理,不难理解。

      当然Dmag只是一个标量,不具备方向,但可以与Blend Tree的参数产生联系了,forward为在Blend Tree里的参数,anim为一Animator类型,接收其Animator组件,不再赘述。

命名为ground的Blend Tree

    我们还需要一个Vector3变量来记录其方向和坐标值:


标量与单位向量相乘是矢量

    以此改变模型的向前向量:


    此时角色就能随意转向了,但仍有一点瑕疵:

        1.当Dup、Dright归0时,Dvec会得到一个(0,0,0)的矢量,从而导致模型的向前向量也变为(0,0,0),会出现无论我怎么转方向,过一会就会回到模型z轴的正方向。

        2.转向也缺少平滑处理。

        3.Dmag会出现1.414的情况,原因是当斜向走时由于勾股定理得到的是一个根号2,这会造成当你角色真正走起来时斜向走的速度会比正向走快40%。

    关于第一个问题,只要在改变转向之前给Dmag设个最低阈值,这就能防止把(0,0,0)给到向前向量。

    其他问题将会在后续解决。

4.真正走起来

    在给模型添加了刚体(Rigidbody)组件后,有两种方式可以令角色真正走起来,一是改变刚体的位置position,二是改变刚体的速度velocity。改变位置很简单,速度乘以时间就好:

movingVec是一个Vector3变量
rigid为Rigidbody类型

    但这一过程要在FixedUpdate()里实现,而不是Update(),因为这两个函数每一帧的时间不一致,Update()每一帧的时间不固定,即第一帧与第二帧的时间t1和第三帧与第四帧的时间t2不一定相同。FixedUpdate()每帧与每帧之间相差的时间是固定的。所以一些物理属性的更新操作应该放在FxiedUpdate中操作,因为这样GameObject的物理表现的更平滑,更接近现实。而Time.fixedDeltaTime与Time.DeltaTime也有所区别,前者是固定时间,为0.02s(可修改);后者是前一帧到后一帧所用的时间,因为Update()中的帧率会变化,所以Time.DeltaTime也会变化。

    如果改变的是刚体的速度,要有一点需要注意,如果单纯是这样:

    这在地面上时没什么问题,可以正常行走,但当你走上斜波再走下来,你会发现你悬空然后慢慢下降:

悬空

    因为上述代码把它速度中的y分量置0了,movingVec中只有x(Dright)和z(Dup)分量有值,y分量为0,这就导致了它一下坡就悬空了。代码应该改为

保留velocity中的y分量

    这就可以了。现在角色走起来没什么大碍了。

以后多点GIF来展示效果好一点。

角色行走

2019年7月1日 17:07:20

5.平滑转向

    现在物体前进的方向是受Dvec控制的,而Dvec只是单纯的坐标轴坐标与单位向量相乘而得,就是说D就是左,A就是右,从左转到右不具备转身的过渡态,是立刻完成。上图或许更直观:


突兀的转向

    这里需要一个函数来解决这个平滑转向的问题,那就是Vector3.Slerp,先看看这个函数在官网上的描述:


Vector3.Slerp

    能在两坐标之间进行球面插值,何为插值?就是在离散数据之间补插一条连续函数,使得这些离散数据可以在这条函数中估算得到。例如两个不相关的点,在其间补插了一条连续函数之后,能用这条函数从一个点递增或递减到另外一个点,不过这是线性插值,线性插值有经过零点的可能,相关函数是Mathf.Lerp。球面插值与线性插值不同,它加入了向量当做方向,这使得它可以不经过零点。这个特性很好的解决了转向的问题。

    接下来看看它要怎么调用:


Vector.Slerp

    它吃3个参数,一个是当前值,一个目标值,一个是进行插值过程的速度。好来试试看:


Vector.Slerp调用

    为了让效果明显一点,我把速度设为了0.1f,这个转向速度就很慢了:

    我们可以看到,现在已经有一个转身的效果了,但是速度设置太慢会有一个副作用,就是会产生一段与转身反向垂直方向的位移,这不能说不好,看是否需要吧,要是不需要就把速度提高点,提高到0.5试试看:

    现在呢位移就几乎没有了(实际上还是有的),转向也很流畅、自然。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容