分享
三行代码  ›  专栏  ›  技术社区  ›  Arnold

UNITY |更新还是调用重复?

  •  0
  • Arnold  · 技术社区  · 5 天前

    我在Unity项目中使用了很多计时器,它们是这样做的:

    void Update()
    {
        timer -= Time.deltaTime;
        if(timer < 0)
        {
            DoSomething();
        }
    }
    

    在谷歌的每个链接上都是这样的。 但今天我发现(我是新手) InvokeRepeating();

    int timer = 60; 
    
    void Start()
    {
        InvokeRepeating("Timer", 1f, 1f);
    }
    
    void Timer()
    {
        timer -= 1;
    }
    

    Update() ?

    哪种方法对性能影响较小?

    1 回复  |  直到 5 天前
        1
  •  2
  •   derHugo    5 天前

    看情况而定!

    在编程中,通常一个问题有多个有效的解决方案。

    在我看来最大的不同是 InvokeRepeating 不活动 游戏对象或 解散 Update 仅在对象处于活动状态且组件已启用时调用。


    void Start()
    {
        timer = 1f;
    }
    
    void Update()
    {
        timer -= Time.deltaTime;
        if(timer < 0)
        {
            timer = 1f;
            DoSomething();
        }
    }
    

    void Start()
    {
        InvokeRepeating(nameof(DoSomething), 1f, 1f);
    }
    

    顺便说一句:第三种基本上等效的解决方案是 Coroutine 更新 MoveNext 调用在 更新

    // Yes, Start can be an IEnumertaor and is in this case internally implicitly started as Coroutine!
    IEnumerator Start() 
    {
        while(true)
        {
            yield return new WaitForSeconds(1f);
    
            DoSeomthing();
        }
    }
    

    正如Kuruchy所提到的:在与 timeScale .

    • 更新 :因为它使用时间。德尔塔时间为了减少计时器,它将受到时间刻度的影响

      为了避免这种情况,您需要使用 Time.unscaledDeltaTime 相反。 如果设置,请保持静止 Time.timeScale = 0; 然后 根本不打电话。

    • 协同程序:类似于更新 WaitForSeconds 也取决于时间尺度。

      为了避免这种情况,您需要使用 WaitForSecondsRealitme 阿法伊克,即使那样 时间刻度=0; 会导致我们的例行程序根本没人打电话。

    • :从文件中我只能看到

      如果将“时间比例”(time scale)设定为0,则此操作不起作用。


    性能方面,你可能根本不必在意!我想这可能是过度优化了。

    不过,我的猜测是 更新 实际上速度稍快,因为在使用时您已经知道方法引用 你把它当作 string 这是另外一个容易出错的问题,这意味着内部统一必须首先找到该方法。

        2
  •  1
  •   Sygan    5 天前

    没有讲太多细节是因为表演。

    相比之下,InvokeRepeating要慢得多。首先要查找的是方法的初始调用和初始调用所需的时间。并且您希望尽可能避免在代码中使用反射。

    这是一篇很好的短文,在这篇文章中,测试是在这两种方法之间进行的- http://www.kittehface.com/2017/09/unity-performance-with-invokerepeating.html