unity中实现经典的2d横版单向跳跃平台

news/2024/5/18 13:08:07 标签: unity, 游戏引擎, 游戏程序

经常玩2d横版游戏的朋友们相信对这样的效果一定对这种单向跳跃平台很熟悉:我希望我的角色可以通过跳跃跳上平台,然后在平台之上按下键盘的下键后从平台上落下

那么想要实现这样的效果具体要怎么做呢?我们还是先将想要实现的效果进行一个逻辑上的拆分:

(1)单向平台,即平台只检测上方的碰撞而不检测下方;(2)角色在平台之上的情况下通过按下键盘的下键使得角色落下平台。

关于第一点,自己其实当时是苦恼了很久的。因为unity的Collider组件当时的自己只知道作为普通的碰撞器或是触发器来进行使用,一个很粗糙的想法是时刻比较当前平台与玩家的坐标,如果平台坐标在玩家之上就作为触发器,一旦坐标低于平台就要作为碰撞器。但这个想法实际上有很大的缺陷——咱们的平台肯定不止一个,会有很多很多物体,这么多物体实时获取咱们角色的坐标显然是一件重复且开销很大的事情

就算可以用一个管理类专门来获取角色的坐标然后通知给所有的平台以解决前一个问题,角色的轴心与平台的轴心设置仍旧会很麻烦。为了方便与地面的检测我们习惯角色都是以脚底为轴心的,而平台的轴心为了实现我们的效果也最好是用顶部作为轴心,这样只要角色的脚底在平台之上了就能让平台作为碰撞器发挥作用。但实际上这么一比较仍旧会出问题:如果我的角色从平台正下方跳到平台上确实可能做到,那么如果我们的角色是从平台的左右侧试图跳上平台呢?极大可能会出现角色脚底正好挨到平台边缘,而此时平台作为碰撞器会将玩家摊开,然后又因为玩家坐标低了变成触发器。

一开始我也查找了不少博客,从一些大佬们的实现方法中了解到了Collider组件还有一种由效果器触发的方式,而unity提供的组件中恰好就有一个叫Platform Effector 2D的组件,这个组件就是专门用来让碰撞器实现2D平台效果的。

 在这个组件中,我们只需要勾选使用单向,然后将表面弧度设置为90度(一般2D游戏的单向平台都是设置为90度),这样就实现了平台进行单向碰撞检测的效果。

解决了第一个问题,我们再来解决第二个问题:如何让角色处于平台之上后按下键盘的下键让角色落下平台呢?

想要让角色落下平台,无非就是暂时屏蔽角色与平台之间的碰撞,想要实现这一效果的途径理论上来说也有很多种,但自己初次实现这个效果的时候不仅想复杂了而且还并没有达到自己理想的效果。

一开始也是查阅了一些大佬的博客,有一位大佬的方法是通过代码调整上图Plaform Effector 2D中的碰撞器遮罩。碰撞器遮罩中实际上就是我们所有图层,默认为Everything,即检测所有图层的碰撞。

那位大佬的方法是为Platform专门写一个脚本,在脚本中获取到Player的图层序号,保存碰撞器遮罩中检测的所有序号,然后在Update中实时检测一旦按下了键盘的下键,就将碰撞器遮罩的图层中的Player图层暂时剔除掉,用一个计时器来短暂计时,超过这一时间后再将Player图层重新添加回去

自己一开始确实采用的这一方法(毕竟看上去问题其实还是挺大但确实暂时实现了自己想要的效果),但这一方法属于是最笨的方法,效果也并不是那么的好:首先关于计时器,你需要自己调整好一个时间不能太短,否则可能角色还没落下平台结果就恢复了对Player图层的碰撞检测,导致角色刚落下一半就又回到了平台上,而且如果有多种角色每个角色身高胖瘦各不相同,这样的检测显然是不行的;其次,只要检测到下键就会执行一次碰撞器遮罩剔除与恢复,这无疑会浪费性能,可能很多时候我们的角色并没有在平台上,在进行其他各种行动时我们都有可能按下键,这显然会导致很多无用的操作

后来经过一番思索与优化后,我发现了问题所在:我一直在想着怎么在给平台检测玩家单独写的这个脚本之中的代码进行优化检测,那么为什么不可以逆向一下,我在玩家的移动之中来检测平台呢?更何况玩家的移动方式之类的我全都是在玩家的脚本中检测的。

我的角色检测地面的方式是学习的麦扣老师《Robbie》教程中的Raycast射线检测方式(非常感谢麦扣老师持续产出的游戏项目课程,带给了我非常多的帮助!),那么既然都用射线检测地面了,为什么不可以用射线检测平台呢?我们只需要给平台加一个Tag就可以用同款的射线方式检测了。

if (Input.GetKeyDown(KeyCode.DownArrow))
            {
                RaycastHit2D leftCheck = Raycast(new Vector2(-footOffset, 0), Vector2.down, groundDistance, groundLayer);
                RaycastHit2D rightCheck = Raycast(new Vector2(footOffset, 0), Vector2.down, groundDistance, groundLayer);

                if (leftCheck.collider.CompareTag("Platform") || rightCheck.collider.CompareTag("Platform"))
                {
                    coll.enabled = false;
                }
            }

protected void PhysicsCheck()
    {
        RaycastHit2D leftCheck = Raycast(new Vector2(-footOffset,0), Vector2.down, groundDistance, groundLayer);
        RaycastHit2D rightCheck = Raycast(new Vector2(footOffset, 0), Vector2.down, groundDistance, groundLayer);
        if(leftCheck || rightCheck)
        {
            if(coll.enabled == false && (leftCheck.collider.CompareTag("Ground") || rightCheck.collider.CompareTag("Ground")))
            {
                coll.enabled = true;
            }
        }
    }

于是在玩家移动的代码中我额外加了上图部分,只要按下下键我就从左脚与右脚发出向下的射线进行检测,如果检测到了平台那么我就暂时关闭玩家的碰撞器,随后在玩家检测地面碰撞的时候如果检测到左脚或右脚接触地面,并且此时的碰撞器是关闭的,我们就将碰撞器重新开启即可。

至此,已经基本实现了我们想要的单向平台,并且玩家按下键盘下键后角色可以从平台上落下的效果。不过我的这种实现方式仍有待完善,目前已知的问题是偶尔不知道为什么会在按下下键的碰撞检测时报错(但实际上效果并未受到影响);然后目前必须得在玩家落下平台接触到地面后才会恢复碰撞体,如果存在一段连续向下且只有平台的关卡,那么这种方式就需要更改了,可能得结合一下前面的计时器思路手动加一个玩家碰撞体恢复的计时器。或者还可以在PhysicsCheck中关于恢复碰撞体的条件判断那里做一点文章,不过暂时也没想出来具体怎么更改。如果大佬们有更好的想法欢迎在评论区中进行讨论!


http://www.niftyadmin.cn/n/286335.html

相关文章

PM864AK01-eA一极用于直流电压电平,地面是用于海底/地下电缆的永久返回路径

​ PM864AK01-eA一极用于直流电压电平,地面是用于海底/地下电缆的永久返回路径 高压直流输电 电力以交流电的形式产生和传输,但对于长距离传输,会产生很大的损耗,或者在两个交流系统无法同步的情况下。所以我们可以用直流输电的方…

SwiftUI 如何动态条件显示和隐藏 Toolbar 按钮且不做无谓刷新

功能需求 在 SwiftUI 中我们可以非常容易的定制导航栏 Toolbar 中按钮的显示,包括折叠、分组和按条件动态显示和隐藏等。 如上图所示,我们仅用寥寥几行代码就实现了 SwiftUI 导航栏 Toolbar 按钮的折叠、分组和按条件动态显示隐藏等功能。 在本篇博文中,您将学到以下内容:…

怎么找回微信删除的聊天记录

生活离不开手机,聊天离不开微信,现在很多人与朋友同事之间的聊天都是使用微信,而使用过微信就会产生聊天记录,这些会一直保存着。但在现实中,可能会因为各种原因,导致微信聊天记录的丢失,在这些…

【2106. 摘水果】

来源:力扣(LeetCode) 描述: 在一个无限的 x 坐标轴上,有许多水果分布在其中某些位置。给你一个二维整数数组 fruits ,其中 fruits[i] [positioni, amounti] 表示共有 amounti 个水果放置在 positioni 上…

C++ STL快速入门

先要说明一下这个STL内容都是概述性的,不是详细的内容,简单来说就是一些大概的框架性的,可以应付一些面试情况。但是要深入学习的话,必须要找更加详细的资料。 不罗嗦,进入正题。 STL是C中的标准模板库,本…

WordPress移除搜索结果页面noindex nofollow教程

WordPress 其实在网站页面规范上做到了非常好的白帽 SEO,不仅有 canonical 规范,还有针对 404 页面,搜索页面的 meta 标签 robots 属性的设置,而页面中一旦被设置为 noindex 或 nofollow,那么也就意味着页面无法被搜索…

警惕免杀版Gh0st木马!

https://github.com/SecurityNo1/Gh0st2023 经过调查发现,这款开源的高度免杀版Gh0st木马目前正在大范围传播,据称可免杀多种主流杀软:开发者不仅制作了新颖的下载页面,还设法增加了搜索引擎的收录权重,吸引了许多免…

辅助驾驶功能开发-功能规范篇(16)-2-领航辅助系统NAP-巡航跟车基础功能

接上篇博文 2.3.2.巡航跟车基础功能 巡航跟车基础功能介绍辅助驾驶系统的车速设定,车间时距设定,纵向定速巡航、跟车加减速、起停,横向居中控制,弯道控制等逻辑。 前置条件: (1)NOA功能激活; 2.3.2.1.车速调节 1)激活时初始显示 中控屏设置界面有“融合限速设置”的开…