【问题标题】:Coroutine WaitForSeconds affected by timeScale受 timeScale 影响的协程 WaitForSeconds
【发布时间】:2016-07-06 17:54:53
【问题描述】:

我正在为我的 UI 元素制作一个简单的动画。

我有一个动画组件,它有 2 个不同的动画 - ZoomIn 和 ZoomOut。

只要需要在屏幕上显示 UI 元素(例如按钮),就会显示这些动画。

我通常更喜欢在不显示时停用游戏对象。

我为动画编写了以下方法:

私有 IEnumerator ToggleObjectWithAnimation (GameObject gameObj) {
        动画师 gameObjectAnimator = gameObj.GetComponent(); // Animator 设置为未缩放时间
        如果(gameObj.activeSelf == false){
            gameObj.transform.localScale = new Vector3 (0, 0, 1.0f);
            gameObj.SetActive (true);
            gameObjectAnimator.SetTrigger ("ZoomIn");
            yield return new WaitForSeconds (0.5f);
        } 否则如果(gameObj.activeSelf == true){
            gameObjectAnimator.SetTrigger ("ZoomOut");
            yield return new WaitForSeconds (0.5f);
            gameObj.SetActive (false); // 当 timescale = 0 时代码不执行
        }
        收益返回空;
}

代码在大多数屏幕上都能正常工作,但当我使用 timescale = 0 暂停游戏时出现问题。

timescale为0时,行gameObj.SetActive(false)不起作用。

【问题讨论】:

  • 你把Debug.Log("test");在 gameObj.SetActive (false) 之前;看看日志是否出现。
  • 这是一个很好的例子,说明为什么你从不改变 Unity 中的 timeScale。暂停游戏非常困难,并且涉及大量代码。您必须为游戏中的每个元素编写暂​​停例程。几年前,网上有人提到你可以“更改 timeScale”来暂停 Unity 中的游戏,这很荒谬。该评论已在整个互联网上重复出现,现在初学者和爱好者都在浪费时间。
  • 我已经尝试添加 Debug.Logs。
  • 代码在行后的 else 块中中断 - yield return new WaitForSeconds (0.5f);虽然没有显示 yield 语句后的日志,但我确信 yield 块已执行,因为我能够看到动画。但是这一行 - gameObj.SetActive (false) 永远不会被执行。
  • @Joe Blow - 感谢您的建议。我不知道更改时间表是一种不好的做法。虽然我尝试过在不使用时间刻度的情况下暂停我的游戏,但我在这样做时遇到了重大挑战。当我的角色撞到意外物体时,我的游戏暂停。现在,当我的角色与另一个对象发生碰撞时,它可以正在执行某个动画。所以在暂停我的游戏时,我希望我的角色处于动画的过渡状态,而不是完成它。使用 timescale = 0 很容易实现。

标签: c# unity3d coroutine


【解决方案1】:

我知道可能有点晚了,但是:

问题不在于SetActive,而是WaitForSeconds si 受Time.timeScale 影响!

实际暂停时间等于给定时间乘以Time.timeScale。如果您希望使用 unscaled 时间等待,请参阅 WaitForSecondsRealtime

所以如果你有Time.timescale=0WaitForSeconds 永远不会完成!


你应该使用WaitForSecondsRealtime

private IEnumerator ToggleObjectWithAnimation (GameObject gameObj) 
{
    Animator gameObjectAnimator = gameObj.GetComponent ();   // Animator is set to unscaled time

    if (gameObj.activeSelf == false) 
    {
        gameObj.transform.localScale = new Vector3 (0, 0, 1.0f);
        gameObj.SetActive (true);
        gameObjectAnimator.SetTrigger ("ZoomIn");
        yield return new WaitForSecondsRealtime(0.5f);
    } 
    else if(gameObj.activeSelf == true) 
    {
        gameObjectAnimator.SetTrigger ("ZoomOut");
        yield return new WaitForSecondsRealtime(0.5f);
        gameObj.SetActive (false);   // code not execute when timescale = 0
    }
    yieldr eturn null;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 2015-07-01
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 2017-09-22
    • 2016-06-15
    • 1970-01-01
    相关资源
    最近更新 更多