在哪里附加碰撞检测脚本?

时间:2018-06-29 09:28:53

标签: c# performance unity3d

我观看了Basic Platformer Game的Unity教程,演示者创建了他附加到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 变得可取时,GameObjects的大致数量是多少?

还是使用方法B 总是更好,因为它看起来更干净(当我们有许多不同的可拾取对象时)?

4 个答案:

答案 0 :(得分:5)

在您的示例中,“方法a”比其他方法更有效,因为OnTriggerEnter2D被调用一次。使用“方法b”,在两个不同的脚本上两次调用OnTriggerEnter2Dslower是Unity在两个不同的脚本+播放器上进行回调调用所必需的。同样,OnTriggerEnter2D被发送到禁用的MonoBehaviours,这使“处理方法”更为有效。 缓慢的事件调用的主要原因是因为该调用是从代码的本机C ++端到Unity的C#API端进行的,这是costly

请注意,这没什么大不了。这只是试图回答您的问题,哪个效率更高,但您正在执行的是微优化。


在此决定中起重要作用的是触发后硬币的行为。

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

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

答案 1 :(得分:1)

考虑到您可以为每个代币和每个超高速启动创建一个预制件,并已附加第二种方法脚本,并考虑可以非常轻松地生成它们在代码中的任何地方,我都会真正坚持第二种方法,使每个人都更明智,更清洁并且更容易理解。

我不喜欢(而且我绝对不会使用)此特定目的的第一种方法,主要是因为自从将OnTriggerEnter2D放到播放器上以来,它很可能被开除很多次玩家正在四处碰碰东西。

答案 2 :(得分:1)

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

但是方法A不会拆分交互,因此假设您可以与2个不同的可拾取对象碰撞,并且同时与bouth碰撞。如果使用方法A,它将始终使用相同的碰撞顺序,这可能是您所希望的!

但是很显然,使用方法B时,您实际上并不知道首先选择哪个对象(在这种情况下!)

答案 3 :(得分:1)

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