U3D:如何使用collision pipeline提升游戏开发优势
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了U3D:如何使用collision pipeline提升游戏开发优势相关的知识,希望对你有一定的参考价值。
如何将事件的执行顺序应用于您的优势
当我在移动设备上工作的时候,我遇到了一个二维的基于网格的动作难题,我遇到了一个复杂的问题,但是使用Unity3D的collision pipeline,我可以用一种可靠的方式来解决它。
好的,想象一下你有一个2D的基于网格的游戏,玩家可以在直线上运行,然后撞到墙上,你需要让玩家在游戏中运行一些基于这样原理的关卡。
我们使用一个带有一个BoxCollider2D的精灵来制作一个“块”,并附加一个“块”脚本,当玩家碰到它时,它会将这个玩家反射到相反的方向上。
1 public class Block : MonoBehaviour 2 { 3 void OnCollisionEnter2D(Collision2D coll) 4 { 5 if (coll.gameObject.tag == "Player") 6 { 7 Player player = coll.gameObject.GetComponent <PLayer> (); 8 9 if (player) player.direction = Opposite(direction); 10 } 11 } 12 }
现在你可以在场景周围放置几个这样的“方块”,效果很好。
但这还不够,你想要加快速度,所以你要在你的项目中包含一个2D地图AR编辑工具。这个工具使你可以在你的场景中直接绘制出与网格直接对齐的瓷砖,你甚至可以一次在多个图层上工作。太棒了!现在,让这个层次成为一种轻而易举的事情,你可以把设计层次的任务委托给关卡设计师,
最终,关卡设计师说:“嘿!我们需要一个能在玩家撞到他的时候杀死玩家的蜘蛛,这样我就能创造出更有趣的关卡。”这对你来说不是问题,所以你要敲出一个小的“SpikeyBlock”脚本,当玩家撞到它时,它就会杀死玩家。有了“SpikeyBlock”脚本,不久你就会有“粘块”、“buttonblock”等等
一切都很顺利,直到不可思议的事情发生。关卡设计人员需要一个块,在一边是spikey,在另一边是sticky。换句话说,块现在应该有边了!边! !而级别设计人员希望能够以不同的方式添加大量的边。那么你会怎么做呢?
一开始,您考虑向块类添加额外的变量和冲突逻辑,但是很快意识到这种方法将使块类变得复杂且难以扩展。这也会使那些现在不得不在检查器窗口中设置值的关卡设计人员变得更加困难。这不仅是一个缓慢的过程,而且还会让可爱的小地图编辑工具毫无意义。
然后,您提出了另一个想法,来创建一个“Edge”类,它封装了不同的行为,并可以添加到一个块中。更好。这解决了保持代码整洁的问题,但是对于仍然需要在检查器窗口中添加边缘组件的关卡设计人员来说,这并不能使事情变得更容易。
解决方案
这让我们了解了本文的关键,即利用Unity3D pipeline的解决方案。
首先,你将一个边缘的概念分解成一个单独的对象,这个对象可以使用不同的timap层来放置在tilemap的任何地方。通过小心的预制结构,边缘可以放置在一块砖的旁边,看起来就像它的一部分一样。这解决了级别设计人员的工作流程问题。
其次,我们用一种稍微不同的方式构造边界,把它们的碰撞器标记为检查器的触发器区域。这让我们有机会在与区块碰撞前处理与边的碰撞,因为,等待它,在管道中发生固体碰撞之前,触发大碰撞,如果你不相信的话,请检查Unity的“事件页面的执行顺序”。我们只是将OnCollision函数的代码移到OnTrigger函数中。
但是,等一下,如果玩家正在擦过其中的一个边,并触碰到一个触发区域,会怎么样呢?我们只想处理碰撞,如果玩家撞到边缘,而不是越过它。如果玩家在一个有两种不同边的角上呢?我们应该打哪边?现在我们要做一系列的计算来检验我们是否真的击中了边缘。这是不对的,Unity是一个游戏引擎!我们不需要做这些检查,我们只是想知道什么时候发生了碰撞,然后做一些很酷的事情。我们仍然可以进一步利用pipeline。
假设玩家有一个Edges数组,当玩家进入一个边缘的触发区域时,它会被添加到数组中,当玩家离开该区域时,它会被移除。就是这样,这就是我们所做的,我们不需要做任何检查就能知道我们什么时候到达了Block的边缘。相反,我们让Unity告诉我们,当我们撞到这个街区的时候,因为我们会收到一个碰撞事件,因为它的固体碰撞器。然后我们要做的就是让玩家检查数组中的任何边(最大的3条边),如果任何边都朝向相反的方向(我使用了一个enum),玩家就会与这条边发生碰撞,否则我们就会与这个方块发生碰撞。请记住, OnTrigger是在OnCollision之前处理的,因此我们确信,当玩家到达块时,他们的数组中已经有了边缘。
玩家的碰撞检查很简单:
// in the Player script OnHitBlock(Block block) { // check the edges foreach (Edge edge in edges) { if (edge.direction == Opposite(player.direction)) { Hit(edge); // handle edge collision return; } } Hit(block); // otherwise handle the block collision }
结论
好了,这可能需要一段时间才能达到这个目的,但我最终到达了这里,希望你们已经看到了如何使用流水线上的执行顺序来帮助解决复杂的问题。
无论如何,我试图保持这篇文章的光芒(尽管主题是一些技术性的),并希望它能在某种程度上有所帮助。欢迎发表任何问题或评论,我将尽我所能做出回应。
以上是关于U3D:如何使用collision pipeline提升游戏开发优势的主要内容,如果未能解决你的问题,请参考以下文章