实际上我在知乎也问过好多这类问题……但在学习和制作途中,还是遇到了太多问题。我想也许从一开始我的整体思路就不太对。
我自学了Unity3D,然后用其2D模式进行格斗游戏的开发和学习。
我很自然地、创建了角色(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来检测角色某一方向的碰撞,但也仅仅是想到这就卡住了,仍然不知道该如何解决。
除开以上问题,我自己也解决了一系列功能:
·角色的诸多判定框问题,我是这样解决的:
我在角色下面创建了诸多子物体,并给这些物体添加Trigger作为角色的各种判定框。然后在动画中调节每一帧的判定框位置并利用帧事件来控制判定框的开启与否。
·角色目前的状态:
我写了一个enum结构体用来记录角色当前的状态,并在大多情况下利用动画帧事件来切换状态。比如在“垂直跳跃”动画的第一帧调用AnimEventJump函数事件。并且不同状态下能做什么事,在Update中利用switch来实现。
·目前写了一个实现“打击感”中顿帧的方法:
当Attack标签(tag)的判定框碰到2PHurt标签的判定框时,首先关闭该Attack判定框,然后将角色的动画播放速度设置为0。并控制HitStop秒后恢复播放速度为1(HitStop位float值,用来控制顿帧时间),这样就实现了顿帧效果。目前测试还算可行,但不知道这样的思路是否正确。
我想知道,传统的2D格斗游戏的设计思路究竟是怎样的。以及怎样用Unity来实现这种思路。
有个东西叫指定碰撞忽略:Physics2D.IgnoreCollision() 做格斗游戏的敬你是条汉子!