Tried to make a platform disappear after standing on it for 5 seconds, but when the player landed on the platform unity crashed

I’m trying to make a 2.5D platformer and I wanted a platform that would break a few seconds after the player landed on it, so these are the scripts I wrote:

Code for the platform.

public class brokenPlatform : MonoBehaviour
{

    public float holdTime = 5f;

    public bool stoodOn = false;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(holdTime == 0)
        {
            Destroy(gameObject);
        }

        while(stoodOn == true)
        {
            holdTime -= 1f;
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            stoodOn = true;
        }
    }

    private void OnCollisionExit(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            stoodOn = false;

            holdTime = 5f;
        }
    }
}

Code for the player.

public class playerControl : MonoBehaviour
{
    public float speed = 6f;

    public float jumpForce = 5;

    public bool grounded = true;

    private float horbutt;

    private Rigidbody playerRB;

    // Start is called before the first frame update
    void Start()
    {
        playerRB = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        horbutt = Input.GetAxis("Horizontal");

        transform.Translate(Vector3.right * Time.deltaTime * speed * horbutt);

        if (Input.GetKeyDown(KeyCode.W) && grounded)
        {
            playerRB.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);

            grounded = false;
        }
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("ground") || collision.gameObject.CompareTag("brokenPlat"))
        {
            grounded = true;

            speed = 6f;
        }

        if (collision.gameObject.CompareTag("goo"))
        {
            grounded = false;

            speed = 2f;
        }
    }
}

But when I tested it, unity crashed as soon as the player landed on it.

What do I do?

Thanks for posting the source code. It helps!

Two things. The problem in your code is that you have a while loop which you never escape from. Unity is not crashing but it’s going into an infinite spin. If you replace the while loop with:

    if (stoodOn)
    {
        holdTime -= 1f;
    }

Then it works fine. Just bear in mind that it may be bad practice to destroy a game object which has a currently running script.

On to the second point. You are are running a countdown inside the Update but decreasing the counter every frame. However, given that the Update loop will run very quickly, you won’t see any delay at all - just 5 frames which might be a tenth of a second or less. One technique is to decrement the hold time by Time.DeltaTime, which is the amount of time since the last frame. So you would code:

if (stoodOn)
{
    holdTime -= Time.DeltaTime;
}

However, the resulting time would never be exactly zero so change your test to:

if(holdTime <0) and you’ll be fine. Other techniques include Invoke and Coroutines which can return after a certain period of time but the Time.DeltaTime method means minimum change to your code.

The technique most commonly used in these circumstances is Destroy(gameObject, t), where t is a float in seconds. You wouldn’t need a timer at all and would certainly be the easiest in this case. It’s the solution I’d recommend.

@sinnerbie Yeah, the way I normally do it is this:

public int timer = 0;

private void Update() {
    timer += 1;

    if (timer >= 10)
    {
        print("Timer done!");
        timer = 0;
    }
}

But that repeats the timer. If you want the timer to only go once, use this:

public bool timerDone = false;//Is the timer done?
public int timer = 0;//Timer

private void Update() {
    if (!timerDone)//If the timer hasn't reached 10, do the timer stuff
    {
        timer += 1;//Add one to the timer each game tick

        if (timer >= 10)//Check if the timer has counted to 10
        {
            print("Timer done!");//Do what you want to do when the timer is done
            timer = 0;//Reset the timer
            timerDone = true;//Make sure the timer doesn't repeat
        }
    }
}

This probably wasn’t what you were looking for but hey, it’s a handy piece of code when you need a timer.