爱收集资源网

碰撞代码解密:角色控制器与游戏世界的奇妙交错

网络整理 2023-09-30 02:00

#0:8:0:4:1:c:d:2:1:2:e:2:1:b:a:a:2:0:2:7:1:7:4:5:9:1:a:6:1:f:8:7#

我实在很喜欢用Unity。它在处理好多底层问题的同时有给了开发者好多自由。而且它还有着十分活跃的社区,起到了很大的帮助。

不幸的是,之前也说了,Unity也带着世界上最糟糕的角色控制器。在与Unity对比之前,这里我阐述一下广义上的角色控制器是哪些。其实角色控制器无非就是处理角色与游戏世界碰撞的一堆代码。它不像袋子、栅栏之类的可以有化学引擎统一处理,角色行为上的特殊性须要代码特殊处理。由于我们须要做碰撞测量,我们还是须要选择一个几何形体去表示我们的角色。大多数3D游戏还会选择胶囊体。

#3:9:e:4:5:9:b:5:2:5:4:3:6:6:a:d:f:a:b:7:e:a:0:3:9:1:7:e:3:3:e:9#

胶囊体的广泛使用有着好多缘由,具体缘由我们有机会再讨论。现在,为了让问题简单,我们先瞧瞧二维情况下的角色控制器。

#3:f:a:4:b:b:b:8:3:2:b:1:b:c:8:f:9:5:b:2:8:1:7:0:a:f:8:2:3:b:3:2#

你会看见我早已把座标标记为z轴和y轴,而不是x轴和y轴。这是因为我将会从顶视图来观察这个三维世界。由于顶视图的缘故,那个白色方形是胶囊体。绿色圆形是一堵墙。理想的状况是,角色难以穿过墙面。因此当角色与外墙交叉时,我希望才能测量出碰撞的发生,然后正确地进行处理。之所以我们自己处理碰撞检查,也就是瞧瞧方形是否与圆形发生了交叉,有两个缘由。一个是Unity有相当多的资源(我们前面会讲)来处理这个问题,第二个就是这是一个讲解碰撞测量的好反例。我们将会让碰撞体估算出正确的位置因而得到合理的行为。

#e:9:5:9:1:3:b:5:4:5:c:4:e:f:0:c:a:e:5:0:7:d:4:a:0:4:f:1:9:2:7:b#

上面展示了我们的角色尝试去朝着墙壁运动。为了处理这个问题,我们从角色位移的起点与位移的终点之间进行一次扫略体测试。这次测试的结果是有一面墙在我们的前方,并且返回到墙壁的距离。那么我们就可以直接领到这个距离,将角色根据方向联通所得碰撞距离,从而联通到墙面之前。(PS:Unity有着好多内建的功能可以做到这点,包括Rigidbody.SweepTest,Physics.SphereCast,Physics.CapsuleCast)。

但是,这并不完全是我们想要的疗效。如果我们用了这些技巧,角色在与物体稍微碰撞以后,就再也没有进行任何联通了。问题在于它缺乏了现实中的回调与侧滑。

#8:a:c:c:4:7:b:9:c:b:7:8:3:b:2:b:6:0:e:0:c:b:5:9:d:0:d:1:1:a:a:9#

这个疗效就愈加合理一些。最初的扫略测试是在联通方向上进行的。当扫略测试接触到外墙以后,角色就直接联通过去,就像刚刚那样。但是此次我们更进一步,让角色向下滑动来补齐遗失的联通,这样促使可以顺着表面滑动。这是一个理想中的角色控制器该有的行为,但这不是实现它的最佳方式。首先,这么做效率不是很高:手机靓号拍卖每次你想联通角色,你就须要执行这个函数。如果每帧只执行一次还好,但是如果由于个别缘由这个函数要执行多次,那就消耗很大。其次,碰撞处理是依赖于角色联通的方向和距离。如果角色由于某种神奇的缘由步入了外墙内部,角色是不会被推出的。实际上,我发觉这个问题很让人头痛。

#f:d:6:d:8:4:6:0:c:4:c:5:3:3:0:5:6:3:9:3:5:0:8:2:0:a:2:3:1:7:0:7#

这是一个糟糕的情况。我们可以看见我们的英雄如今早已在外墙内部了。这种情况下,我们不应当再考虑如何像之前一样处理碰撞,而是当作一种独立的情况来处理。我们不再关心玩家朝那个方向联通或则联通了多远。而是我们应当考虑的是,这一刻他应当在那个位置,这个位置是否存在问题。在上图中,我们可以见到玩家正在与外墙交叉(在外墙内部了),因此他当前位置存在问题,并且须要修正。自从我们不再将处理碰撞检查作为运动的反馈,我们是不知道之前的位置在哪或则联通了多远。而我们所晓得的是,他目前卡在墙内,而我们须要将他从外墙内挪下来。但是应当放在那里呢?就像之前的事例一样,我们应当在刚接触墙壁的时侯就将其推出。这里我们有不少候选位置。

#f:a:2:3:6:f:c:9:4:b:d:9:8:4:e:6:e:6:3:d:4:7:f:7:9:c:8:0:2:a:9:7#

每个半透明蓝色圆圈都指示了一个潜在的满足推出的位置。但是我们应当选择那个呢?很简单,只要选择距离角色近来的墙壁的近来点即可。

#4:6:9:4:3:1:b:2:1:0:1:6:6:1:4:5:c:7:0:9:1:f:b:2:4:a:9:2:a:5:d:f#

这里我们估算得出距离角色近来点坐落一侧。接着我们就可以将角色联通到该点,加上角色的直径(红色部份)。

到这儿就结束了我们深入神秘的角色控制器的第一部份。下次,我将会开始聊聊怎样在Unity中实现,以及一些角色控制器会用到的愈加复杂的函数。

致谢与引用:

这里的大多数知识都来源于两个信息源:Unity峰会上的用户techmage以及逆向剖析Unity角色控制器包的用户fholm。两个名子都不知道如何发音。不管怎样,在RPGController目录下。这是一个很不错的项目,代码写得挺好。很显然,他时做Unity顾问的,如果有谁须要这个服务的话。最后,如果谁有关于这个话题的挺好的资源,不妨与我分享一下。

unity中角色控制器碰
上一篇:测量MySQL查询响应时间 下一篇:没有了