哪里附上碰撞检测脚本?

我观看了Unity的Basic Platformer Game教程,其中主持人创建了他附加到Coin预制件的硬币拾取脚本。 我想知道是否应该将拾取脚本附加到Player或Coin GameObject。

假设我们有一个可以拾取物体的游戏。 他们只做增加分数(或以另一种方式影响玩家)并在碰撞中摧毁自己。

我想知道这个问题的首选方法是什么。

我想出了两种方法:


方法A.

玩家游戏对象上有一个ObjectPickup脚本。 该脚本将根据碰撞对象的类型执行任何操作。

private void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.CompareTag("Coin")) { IncrementScore(); Destroy(other.gameObject); } else if (other.gameObject.CompareTag("SuperSpeed")) { IncreasePlayerSpeed(); Destroy(other.gameObject); } } 

方法B.

每个硬币都有CoinPickup脚本, 每个超高速通电都有 SuperSpeedPickup脚本。

 private void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.CompareTag("Player")) { other.gameObject.IncrementScore(); Destroy(gameObject); } } 

和其他脚本:

 private void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.CompareTag("Player")) { other.gameObject.IncreasePlayerSpeed(); Destroy(gameObject); } } 

方法A方法B更有效吗? 如果是这样,当方法A变得更可取时,游戏对象的粗略数量是多少?

或者使用方法B总是更好,因为它似乎更清洁(当我们有许多不同的可拾取物体时)?

在您的示例中,“接近a”将比另一个更有效,因为OnTriggerEnter2D被调用一次。 使用“方法b”,在两个不同的脚本上调用OnTriggerEnter2D两次。 Unity在两个不同的脚本+播放器上进行回调调用的速度较慢 。 此外, OnTriggerEnter2D被发送到禁用的MonoBehaviours ,这使得“接近”更有效的选择。 缓慢事件调用的主要原因是因为调用是从代码的本机C ++端调用到Unity的C#API端,这是昂贵的 。

请注意,这并不重要 。 这只是一个尝试回答你的问题,哪一个更有效,但你正在做的是微优化。


应该在这个决定中扮演重要角色的东西是触发后硬币的行为。

如果硬币表现相同,则使用“接近a”并在玩家一侧进行检测。

如果硬币具有不同的行为,例如具有不同分数值的硬币,颜色和动作(动画),则在收集时,然后在硬币侧进行检测并处理每个硬币。 这就是脚本首先附加到GameObjects的原因。 每个不同的硬币不需要不同的标签。 使用enum来区分OnTriggerEnter2D函数中的操作。 在这种情况下使用“接近a”来处理这个问题会很糟糕。

考虑到你可以为每个硬币和每个超级速度创建一个预制件,并且已经附加了第二个方法脚本并且考虑到你可以从代码中的任何地方轻松地产生它们,我真的坚持第二种方法 ,制作它每个人都更明智,更干净,更清楚易懂。

我不喜欢(并且我绝对不会使用)这个特定purpouse的第一种方法,主要是因为OnTriggerEnter2D非常可能被OnTriggerEnter2D很多次,因为它被放在播放器上而玩家正在四处移动到处都是东西。

我应该使用B,因为它更像是对象编程的工作原理(至少在我的头上!),即使它更昂贵。

但是方法A不会分裂交互,所以想象一下你可以与2个不同的可拾取对象发生碰撞,并且同时与bouth发生碰撞。 如果您使用方法A,它将始终使用相同的碰撞顺序,这可能是您想要的或不是!

但是很明显,对于方法B,你并不真正知道首先会选择哪个对象(在这个具体案例中!)

方法A听起来更高效,也适用于多人游戏。 如果您有本地或在线的n个玩家,则需要检查硬币上的玩家ID。 否则你需要很多标签。 如果玩家自己检测到物品碰撞,则无需这样做。