vini290
vini290

Reputation: 13

Action for a period of time Unity

i have a problem with my script in unity 3D. I'm trying to make a collectable system that when I collect the item, The game turns itself on slowmotion, but only for 3 seconds then it becomes normal again. I could make it when I collect the first item, but when I collect the second one It doesn't returns to normal speed. After I collect the second item, my Time.fixedTime gets stucked on 4 seconds... It doesn't not update anymore.

using UnityEngine;


public class CollectableDestroy : MonoBehaviour
{
    public GameObject gb;
    public float startTime;
    private float realTime;
    private void FixedUpdate() {
        realTime = Time.fixedTime; // Stores game's time
        if(realTime - startTime >= 3){ // If has passed 3 seconds after hitting the trigger, if returns to normal speed
            PlayerMov.velocityObject = 50f;
        }
        Debug.Log(realTime);
    }
    private void OnTriggerEnter() {
        startTime = Time.fixedTime; // It stores time when player hit trigger
        GameObject.Destroy(gb);
        PlayerMov.velocityObject = 1f; // It turns in slowmotion
    }
}

Upvotes: 0

Views: 1712

Answers (2)

derHugo
derHugo

Reputation: 90629

Don't know if this is the issue but you can simply define OnTriggerEnter as a Coroutine and use WaitForSeconds and WaitForFixedUpdate

bool alreadySlowDone;

private IEnumerator OnTriggerEnter() 
{
    // in case you call this multiple times wait until one routine finished
    // here you can decide what you want to do .. I would block further triggers until bac to normal
    if(alreadySlowDone) yield break;

    alreadySlowDone = true;

    // still questionable why you do this here but maybe at least check it
    if(gb) GameObject.Destroy(gb);
    else Debug.LogError("Why do I try to destroy something here that doesn't exist?", this);

    PlayerMov.velocityObject = 1f; // It turns in slowmotion

    // wait for 3 seconds
    yield return new WaitForSeconds(3f);

    // wait for the next fixed update
    yield return new WaitForFixedUpdate();

    PlayerMov.velocityObject = 50f;

    alreadySlowDone = false;
}

Upvotes: 1

Matt
Matt

Reputation: 98

Time.fixedTime is very weird to work with. Processing power ends up being an issue with how Time is returned. It could desync in a way that gives a different value everytime you Activate that Trigger. Causing your problem.

Why not either use Time.deltaTime (which is more stable) or have leaving the Trigger OnExitTrigger reset the realTime Alternatively in the FixedUpdate() if statement, have a fail safe to reset the realTime just in-case

Upvotes: 0

Related Questions