首页 文章

如何在1秒Unity 3D后停止功能?

提问于
浏览
0

在我的代码中,当玩家进入触发器时我正在调用慢动作功能,但我希望此功能在1秒后停止,我尝试了下面的代码,但慢动作不起作用 . 你有什么主意吗?

Player Script:

public Rigidbody Ball;
public float Speed = 50f;
public TimeManager timeManager;
bool SlowOn;
bool ClickDone = false;



// Use this for initialization
void Start () {
    StartCoroutine(SlowOff());
}

// Update is called once per frame
void FixedUpdate () {
    if (!ClickDone){
        if (Input.GetMouseButton (0)) {
            ClickDone = true;
            Ball.velocity = transform.forward * Speed;
        }
    }
}

private void OnTriggerEnter (Collider other) {
    if(other.gameObject.CompareTag ("SlowMotionArea")) {
        if (SlowOn) {
            timeManager.DoSlowMotion();
        }
    }
}

IEnumerator SlowOff () {
    yield return new WaitForSeconds(2.0f);
    SlowOn = false;
}

TimeManager Script:

public float SlowDownFactor = 0.05f;
    public float SlowdownLength = 2f;

    public void DoSlowMotion () {    
        Time.timeScale = SlowDownFactor;
        Time.fixedDeltaTime = 0.02f * Time.timeScale ;
    }

1 回答

  • 0

    您的代码存在一些问题

    • 你永远不会将 SlowOn 设置为 true 所以你的行
    timeManager.DoSlowMotion();
    

    从未被执行过 . 您应该在代码中的某处调用

    SlowOn = true;
    

    我猜,但似乎你想使用那个bool来防止多次调用 timeManager.DoSlowMotion() ?在这种情况下,它应该是类似的东西

    if(!SlowOn)
    {
        timeManager.DoSlowMotion();
        SlowOn = true;
    }
    
    • 为什么在 Start() 方法中调用 StartCoroutine(SlowOff());

    我想你应该删除该行并将其放置

    timeManager.DoSlowMotion();
    StartCoroutine(SlowOff());
    

    所以每当SlowMotion开始时,Coroutine就会启动 .

    • 慢动作仅停止设置 SlowOn = false 是不够的 .

    TimeManager 中,您应该存储原始TimeScale并在第二种方法中重置它们:

    public float SlowDownFactor = 0.05f;
    public float SlowdownLength = 2f;
    
    private float originalTimeScale;
    private float originalFixedDeltaTime;
    
    public void DoSlowMotion () {   
    
        // before changing store current values
        originalTimeScale = Time.timeScale;
        originalFixedDeltaTime = Time.fixedDeltaTime;
    
        Time.timeScale = SlowDownFactor;
        Time.fixedDeltaTime = 0.02f * Time.timeScale ;
    }
    
    public void ResetTimeScales()
    {
        Time.timeScale = originalTimeScale;
        Time.fixedDeltaTime = originalFixedDeltaTime;
    }
    

    而且你还必须从玩家那里调用 ResetTimeScales 方法

    IEnumerator SlowOff () {
        yield return new WaitForSeconds(2.0f);
        timeManager.ResetTimeScales();
        SlowOn = false;
    }
    
    • 我想你知道的
    yield return new WaitForSeconds(2.0f);
    

    也将受到更改的时间刻度的影响,因此您的SlowMotion当前将比预期的 2 秒更长,即 2 / SlowDownFactor = 40

    您可以通过使用 Time.unscaledDeltaTime 作为倒计时来避免这种情况

    private IEnumerator SlowOff()
    {
        // since your title actually claims you want to reset after 1 second
        float timer = 1;
    
        while (timer > 0)
        {
            timer -= Time.unscaledDeltaTime;
            yield return null;
        }
    
        timeManager.ResetTimeScales();
        SlowDown = false;
    }
    

相关问题