Как остановить функцию через 1 секунду Unity 3D? - PullRequest
0 голосов
/ 09 декабря 2018

В моем коде я вызываю функцию Slow Motion, когда игрок входит в Trigger, но я хочу, чтобы эта функция прекратилась через 1 секунду, я попробовал код ниже, но медленное движение не сработало.У вас есть идеи?

Сценарий игрока:

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:

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

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

1 Ответ

0 голосов
/ 10 декабря 2018

Есть несколько проблем с вашим кодом

  1. Вы никогда не устанавливаете SlowOn в true, поэтому ваша строка

    timeManager.DoSlowMotion();
    

    никогда не выполняется.Где-то в вашем коде вы должны позвонить

    SlowOn = true;
    

    Я предполагаю, но кажется, что вы хотели использовать этот bool для предотвращения множественных вызовов timeManager.DoSlowMotion()?В этом случае это должно быть что-то вроде

    if(!SlowOn)
    {
        timeManager.DoSlowMotion();
        SlowOn = true;
    }
    
  2. Почему вы вызываете StartCoroutine(SlowOff()); в вашем Start() методе?

    Я думаю, вам лучше удалитьэту строку и поместите ее после

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

    , чтобы сопрограмма запускалась при каждом запуске SlowMotion.

  3. Недостаточно остановки SlowMotion, чтобы просто установитьSlowOn = false.

    В вашем TimeManager вы должны скорее сохранить исходную шкалу времени и сбросить ее во втором методе:

    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;
    }
    
  4. Полагаю, вы знаете, что измененная шкала времени будет также влиять на

    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;
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...