unity中实现经典的2d横版单向跳跃平台_unity2d 平台跳跃游戏-程序员宅基地

技术标签: 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中关于恢复碰撞体的条件判断那里做一点文章,不过暂时也没想出来具体怎么更改。如果大佬们有更好的想法欢迎在评论区中进行讨论!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_57596472/article/details/130480653

智能推荐

没有U盘Win10电脑下如何使用本地硬盘安装Ubuntu20.04(单双硬盘都行)_没有u盘怎么装ubuntu-程序员宅基地

文章浏览阅读3.6k次,点赞2次,收藏2次。DELL7080台式机两块硬盘。_没有u盘怎么装ubuntu

【POJ 3401】Asteroids-程序员宅基地

文章浏览阅读32次。题面Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <= 500). The grid contains K asteroids (1 <= K <= 10,000), which are conv...

工业机器视觉系统的构成与开发过程(理论篇—1)_工业机器视觉系统的构成与开发过程(理论篇—1-程序员宅基地

文章浏览阅读2.6w次,点赞21次,收藏112次。机器视觉则主要是指工业领域视觉的应用研究,例如自主机器人的视觉,用于检测和测量的视觉系统等。它通过在工业领域将图像感知、图像处理、控制理论与软件、硬件紧密结合,并研究解决图像处理和计算机视觉理论在实际应用过程中的问题,以实现高效的运动控制或各种实时操作。_工业机器视觉系统的构成与开发过程(理论篇—1

plt.legend的用法-程序员宅基地

文章浏览阅读5.9w次,点赞32次,收藏58次。legend 传奇、图例。plt.legend()的作用:在plt.plot() 定义后plt.legend() 会显示该 label 的内容,否则会报error: No handles with labels found to put in legend.plt.plot(result_price, color = 'red', label = 'Training Loss') legend作用位置:下图红圈处。..._plt.legend

深入理解 C# .NET Core 中 async await 异步编程思想_netcore async await-程序员宅基地

文章浏览阅读2.2k次,点赞3次,收藏11次。深入理解 C# .NET Core 中 async await 异步编程思想引言一、什么是异步?1.1 简单实例(WatchTV并行CookCoffee)二、深入理解(异步)2.1 当我需要异步返回值时,怎么处理?2.2 充分利用异步并行的高效性async await的秘密引言很久没来CSDN了,快小半年了一直在闲置,也写不出一些带有思想和深度的文章;之前就写过一篇关于async await 的异步理解 ,现在回顾,真的不要太浅和太陋,让人不忍直视!好了,废话不再啰嗦,直入主题:一、什么是异步?_netcore async await

IntelliJ IDEA设置类注释和方法注释带作者和日期_idea作者和日期等注释-程序员宅基地

文章浏览阅读6.5w次,点赞166次,收藏309次。当我看到别人的类上面的多行注释是是这样的:这样的:这样的:好装X啊!我也想要!怎么办呢?往下瞅:跟着我左手右手一个慢动作~~~File--->Settings---->Editor---->File and Code Templates --->Includes--->File Header:之后点applay--..._idea作者和日期等注释

随便推点

发行版Linux和麒麟操作系统下netperf 网络性能测试-程序员宅基地

文章浏览阅读175次。Netperf是一种网络性能的测量工具,主要针对基于TCP或UDP的传输。Netperf根据应用的不同,可以进行不同模式的网络性能测试,即批量数据传输(bulk data transfer)模式和请求/应答(request/reponse)模式。工作原理Netperf工具以client/server方式工作。server端是netserver,用来侦听来自client端的连接,c..._netperf 麒麟

万字长文详解 Go 程序是怎样跑起来的?| CSDN 博文精选-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏3次。作者| qcrao责编 | 屠敏出品 | 程序员宅基地刚开始写这篇文章的时候,目标非常大,想要探索 Go 程序的一生:编码、编译、汇编、链接、运行、退出。它的每一步具体如何进行,力图弄清 Go 程序的这一生。在这个过程中,我又复习了一遍《程序员的自我修养》。这是一本讲编译、链接的书,非常详细,值得一看!数年前,我第一次看到这本书的书名,就非常喜欢。因为它模仿了周星驰喜剧..._go run 每次都要编译吗

C++之istringstream、ostringstream、stringstream 类详解_c++ istringstream a >> string-程序员宅基地

文章浏览阅读1.4k次,点赞4次,收藏2次。0、C++的输入输出分为三种:(1)基于控制台的I/O (2)基于文件的I/O (3)基于字符串的I/O 1、头文件[cpp] view plaincopyprint?#include 2、作用istringstream类用于执行C++风格的字符串流的输入操作。 ostringstream类用_c++ istringstream a >> string

MySQL 的 binglog、redolog、undolog-程序员宅基地

文章浏览阅读2k次,点赞3次,收藏14次。我们在每个修改的地方都记录一条对应的 redo 日志显然是不现实的,因此实现方式是用时间换空间,我们在数据库崩了之后用日志还原数据时,在执行这条日志之前,数据库应该是一个一致性状态,我们用对应的参数,执行固定的步骤,修改对应的数据。1,MySQL 就是通过 undolog 回滚日志来保证事务原子性的,在异常发生时,对已经执行的操作进行回滚,回滚日志会先于数据持久化到磁盘上(因为它记录的数据比较少,所以持久化的速度快),当用户再次启动数据库的时候,数据库能够通过查询回滚日志来回滚将之前未完成的事务。_binglog

我的第一个Chrome小插件-基于vue开发的flexbox布局CSS拷贝工具_chrome css布局插件-程序员宅基地

文章浏览阅读3k次。概述之前介绍过 移动Web开发基础-flex弹性布局(兼容写法) 里面有提到过想做一个Chrome插件,来生成flexbox布局的css代码直接拷贝出来用。最近把这个想法实现了,给大家分享下。play-flexbox插件介绍play-flexbox一秒搞定flexbox布局,可直接预览效果,拷贝CSS代码快速用于页面重构。 你也可以通过点击以下链接(codepen示例)查_chrome css布局插件

win10下安装TensorFlow-gpu的流程(包括cuda、cuDnn下载以及安装问题)-程序员宅基地

文章浏览阅读308次。我自己的配置是GeForce GTX 1660 +CUDA10.0+CUDNN7.6.0 + TensorFlow-GPU 1.14.0Win10系统安装tensorflow-gpu(按照步骤一次成功)https://blog.csdn.net/zqxdsy/article/details/103152190环境配置——win10下TensorFlow-GPU安装(GTX1660 SUPER+CUDA10+CUDNN7.4)https://blog.csdn.net/jiDxiaohuo/arti