GetComponent<>()是否会影响性能

时间:2018-05-06 23:52:49

标签: c# performance unity3d

正如标题所说,GetComponent()确实对性能产生了很大的影响。

我问这个是因为我不喜欢这样做:

public class Player : MonoBehaviour
{
    PlayerStats playerStats = this.GetComponent<PlayerStats>();

    void Update()
    {
        var something = playerStats.Asd;
    }
}

而不是我喜欢这样使用它:

public class Player : MonoBehaviour
{
    void Update()
    {
        var something = this.GetComponent<PlayerStats>().Asd;
    }
}

原因是因为我喜欢破坏许多脚本中的代码(如果需要的话我以后更容易改变一些东西,并且对多个对象使用一个脚本),所以如果我有很多脚本我需要看到如果我已经定义了PlayerStats playerStats....但不仅仅是这个,而是定义了很多。

那么使用第二种方法会减慢我的游戏速度吗?

3 个答案:

答案 0 :(得分:5)

值得注意的是,您的第一个脚本无效且无法编译。正确的方法是使其成为全局变量,但在StartAwake函数中缓存或初始化脚本。这些函数运行一次,用于初始化。

这样的事情:

PlayerStats playerStats;

void Start()
{
    playerStats  = this.GetComponent<PlayerStats>();
}

为了回答您的问题,影响性能的GetComponent功能被夸大了。你在互联网上到处读到这个,但这取决于它的使用频率。如果它偶尔使用一次或只用几个脚本,那么它完全没问题。

如果您在GetComponent函数中使用Update有数百个脚本实例,那么当您GetComponent正在调用时,您将开始注意到一点性能损失到原住民方面。 因此,它取决于它的调用频率以及每个帧调用多少个脚本实例。

答案 1 :(得分:3)

使用第一种方法的主要吸引力在于您可以将这些变量设置为公共,然后直接从Unity编辑器访问它们,允许您按照自己的意愿拖放组件。

GetComponent函数调用的第二个实例意味着您没有缓存变量,可能会通过可能不必要的检查来减慢代码速度。所以我的建议是坚持你的变量在内存中定义然后改变的第一个实例,而不是每次都分配内存然后改变。

并附注意。如果脚本附加到对象,则无需调用this.GetComponent,因为脚本派生自MonoBehaviour;你可以打电话给GetComponent<type>(),开始你的快乐时光。 :)

答案 2 :(得分:3)

我认为这不重要。我只是做了一个检查,并使用循环1,000,000次的for循环,并发现两帧之间完全相同的0.02时间延迟。

话虽如此,它会使您的代码更清晰,因为Player.Stats.AsdPlayer.GetComponent<PlayerStats>().Asd更清晰。它使意图变得更加明显。我确定它仍然是一个微优化,可以将它存储为带有public PlayerStats Stats { get; set; }的变量,但是如果你一直在使用它,那就是真的。

你不应该为它拥有的每个Component使用一个变量,因为如果你为每个脚本都这样做,那么正在使用的内存将开始累加。

另请注意,我称之为Stats而不是PlayerStats,因为Player.PlayerStats不必要地多余。它的实际类型应该被称为PlayerStats是,不要将它与EnemyStats混淆,但当你同时使用它们时,Player.Stats并且Enemy.Stats更清洁。