关于制作 Unity 2D 格斗游戏的思路讨论

作者:Determine
2017-11-12
19 23 12

前言

本文是一篇有关使用 Unity 引擎制作 2D 格斗游戏的方法讨论。本文作者试图使用 Unity 2D 进行格斗游戏制作,并且得到了一些基础的解决方案,但在思路上遇到了一些问题。由于目前关于格斗游戏的制作讨论并不很多,而格斗游戏的制作也有着涉及到物理判定的许多困难,因此尽管讨论非常基础,仍刊登本文试图引发讨论。

目前已经解决的问题

角色的多重判定框问题

我在角色下面创建了多个子物体,并给这些物体添加 Trigger 作为角色的各种判定框,然后在动画中调节每一帧的判定框位置并利用帧事件来控制判定框的开启与否。

角色目前的状态

我写了一个 enum 结构体用来记录角色当前的状态,并在大多情况下利用动画帧事件来切换状态。比如在“垂直跳跃”动画的第一帧调用 AnimEventJump 函数事件。并且不同状态下能做什么事,在 Update 中利用 switch 来实现。

目前写了一个实现“打击感”中顿帧的方法

当 Attack 标签(tag)的判定框碰到2PHurt 标签的判定框时,首先关闭该 Attack 判定框,然后将角色的动画播放速度设置为0。并控制 HitStop 秒后恢复播放速度为1(HitStop 位 float 值,用来控制顿帧时间),这样就实现了顿帧效果。目前测试还算可行,但不知道这样的思路是否正确。

思路探讨

即使有了以上的解决方案,我仍然面临了诸多问题,对于整体思路进行反思,不知其是否正确,因此拿出与大家进行讨论。

学习 Unity 并且打算使用其进行格斗游戏制作之后,我很自然地、创建了角色(sprite)和其动画。然后为角色添加了 RigidBody2D 刚体组件和碰撞框 BoxCollider2D。

角色有重量,有 Collider,自然会落到下面那个有 Collider 的 Ground(作为地面的物体)上。所以,目前角色的站立完全是靠 Unity 自带的 Collider 和 RigidBody 属性来实现的。

为了实现角色的移动,试过用 AddForce 和控制速度(velocity)来实现,但最后觉得最适合格斗游戏的移动方式还是直接控制角色坐标(transform.position +=)。

我利用动画帧事件实现了跳跃,在“垂直跳跃”的第二帧添加事件“AddForce(Vector2.up*JumpPower)”来实现起跳。而“垂直跳跃”的第一帧仍是站立图片,为了实现“向前跳跃”和“向后跳跃”而留出这一帧的时间让玩家同时按下“上(8)”和“前/后(6/4)”再判断执行“向前跳跃”,“向后跳跃”,“垂直跳跃”中的哪一个。

现在遇到的最主要的问题是:角色不仅能站在地面上,还能站在另一个角色头上。

因为我完全是依赖 Coliider 和 RigidBody 而实现的站立,所以当角色跳到另一个拥有 BoxCollider 的角色头上时,自然也会站在上面。

我尝试用 OnCollisionEnter 来解决这个问题,当角色有所接触时,如果是站在了另一个角色头上,就让另一个角色移开一段距离或自己移开。但不知为何效果没有实现。我也并没有从代码中找出问题所在。

后来我去学习了 GameMaker 这个引擎,一是想从这个引擎中找到思路。二是看到过很多用 Undertale,Rival of Aether 等用 GameMaker 做出来的游戏质量都很不错,早就感兴趣。而在学习中,发现 GameMaker 通常采用 Place_meeting 来实现物体碰撞,比如当物体的正下方接触到名为 Ground 的物体时,物体 y 轴坐标不会改变。

于是我想到在 Unity 中用射线 Physic.Raycast 来检测角色某一方向的碰撞,但也仅仅是想到这就卡住了,仍然不知道该如何解决。

希望与诸位探讨,传统的2D 格斗游戏的设计思路究竟是怎样的。以及怎样用 Unity 来实现这种思路。

近期点赞的会员

 分享这篇文章

Determine 

我们可是热血沸腾的思春期少年!根本把持不住自己哦! 

您可能还会对这些文章感兴趣

参与此文章的讨论

  1. 亚恒 2017-11-12

    兄弟你把牛关的问题来这边再问一次我能理解...
    @indienova 站长把这篇文推首页我就有点不能理解了...
    这可是一篇求助文耶(。-`ω-)

    • indienova 2017-11-17

      @亚恒:抱歉回复晚啦……其实这面文章里有作者自己解决一些的问题的思路,所以我们决定发出来。不过你说的也有道理,所以我们把文章结构调整了一下。感谢反馈~

  2. jiangzhen3s 2017-11-12

    现在遇到的最主要的问题是:角色不仅能站在地面上,还能站在另一个角色头上。

    Collider 勾上 IsTrigger 这样会允许重叠
    然后可以在人物上弄两个Collider2D 设置不同的 Layer
    一个Layer与地面Layer 碰撞(可以站立), 另一个Collider2D弄成Trigger (人物打斗触发)

    good luck

    最近由 jiangzhen3s 修改于:2017-11-12 13:19:40
    • whitecrow 2019-09-25

      @indienova: @jiangzhen3s: 还以为遇到高手了 看了文章彻底失望 太入门了, 如果不自己写物理引擎 这里的实现是这样的 碰撞体是要的 以为人物不允许前进直接穿过去,需要在头的部位 拢一个触发器 这个触发器的作用是强行位移 ,或者更好的方法是用胶囊碰撞体 在头部位置能自然下坠 方法太多 细节太多

  3. rein1 2017-11-12

    跟我的实现思路差不多~

  4. Anchor 2017-11-16

    可以看下我之前做格斗游戏时的思路。
    Unity2D格斗游戏开发问题? - AnchorWang的回答 - 知乎
    https://www.zhihu.com/question/40969731/answer/89658017

  5. auducie 2017-11-17

    弄成球形Collider 试试,球形的会自己慢慢滑下来,或者吧Collider改成上下尖头的,然后再写个判断正好人物在头顶的尖上就随机移动一点

  6. JasonTodd 2017-12-04

    最近在做一个2D横版动作游戏,攻击判定我也是这样做的,但是关于移动、跳跃和重量这个,我试过用Unity自带的Collider 和 RigidBody来实现,说实话真的挺坑的,问题不在于Unity实现不得不好,而是在于Unity的2D碰撞是基于Box2D、模拟真实物理效果实现的,这样角色就会出现很多看起来像BUG的诡异行为,后来在看到推荐说用射线的方法来实现,最后实现出来的效果还算满意。

  7. fjzjk 2018-01-19

    用射线 Physic.Raycast 来检测某一方向的碰撞的话,会先射到自己

  8. Chestnut 2018-08-26

    你好,最近我也在试着做一个2d的格斗游戏,但是在判定这方面遇到些问题。我在动画中某一帧激活用来判定攻击范围的物体A后,挂载在A上的脚本OnTriggerEnter2D和OnTriggerStay2D函数均不能检测到范围内有游戏物体,请问这个博主是怎么解决的呢?

  9. xiaoyaoziluo 2019-03-15

    能不能使用碰撞点的法线来判断碰撞到的地方呢?

  10. WonkmyGame 2021-10-27

    我倒是觉得首先要解决的问题是美术,格斗游戏人物的动作是非常多的

您需要登录或者注册后才能发表评论

登录/注册