Invoke Application.LoadLevel?? How does it work?

Hello. I don´t know how to load scene1, 2 seconds after player touches a collider.

There is my script but i don´t know why it doesn´t work :frowning:

using UnityEngine;
using System.Collections;

public class TNT : MonoBehaviour {
    public GameObject obj;
    public AudioClip[] audioclip;

    void loadlevel()
    {
                Application.LoadLevel (1);
        }
   
    void OnTriggerEnter2D(Collider2D other)
    {
        if(other.tag == "Player")
        {
            Destroy (this.gameObject);
            Instantiate(obj,transform.position,transform.rotation);
            AudioSource.PlayClipAtPoint(audioclip[0], transform.position);
            Invoke("loadlevel", 2f);
           
        }
    }
}

Thank you :slight_smile:

If none of your code works it is possible that the tag of your collider is not “Player”. Make sure you have the right value.

If your collision if fine, it is possible that a level with the index 1 does not exist but you should have seen that error in the console.

Last possibility I can think of is that you forgot to add a collider to your gameobject and because of that your OnTriggerEnter2D method does not trigger.

tag is fine, level 1 exists, it triggers fine. All lines works :

 Destroy (this.gameObject);
            Instantiate(obj,transform.position,transform.rotation);
            AudioSource.PlayClipAtPoint(audioclip[0], transform.position);

But this doesn´t

Invoke("loadlevel", 2f);

If i do this:

using UnityEngine;
using System.Collections;
public class TNT : MonoBehaviour {
    public GameObject obj;
    public AudioClip[] audioclip;
 
    void OnTriggerEnter2D(Collider2D other)
    {
        if(other.tag == "Player")
        {
            Destroy (this.gameObject);
            Instantiate(obj,transform.position,transform.rotation);
            AudioSource.PlayClipAtPoint(audioclip[0], transform.position);
            Application.LoadLevel (1);
         
        }
    }
}

It works fine. But if i do it using Invoke, it doesn´t work. I want the Application.LoadLevel (1); to be delayed. That´s why I would like to use Invoke

Look at where you’re destroying your gameObject.

This doesn´t work either.

using UnityEngine;
using System.Collections;
public class TNT : MonoBehaviour {
    public GameObject obj;
    public AudioClip[] audioclip;
    void loadlevel()
    {
                Application.LoadLevel (1);
        }
  
    void OnTriggerEnter2D(Collider2D other)
    {
        if(other.tag == "Player")
        {
            Instantiate(obj,transform.position,transform.rotation);
            AudioSource.PlayClipAtPoint(audioclip[0], transform.position);
            Invoke("loadlevel", 2f);
       Destroy (this.gameObject);
          
        }
    }
}

I don’t know what the problem is but you can always try a different approach to add delay. For example you can try something like this

using UnityEngine;
using System.Collections;
public class TNT : MonoBehaviour {
                public GameObject obj;
                public AudioClip[] audioclip;
                IEnumerator loadlevel()
                {
                        yield return new WaitForSeconds (2f);
                        Application.LoadLevel (1);
                }

                void OnTriggerEnter2D(Collider2D other)
                {
                        if(other.tag == "Player")
                        {
                                Instantiate(obj,transform.position,transform.rotation);
                                AudioSource.PlayClipAtPoint(audioclip[0], transform.position);
                                StartCoroutine ("loadlevel");
                                Destroy (this.gameObject);

                        }
                }
        }

Look at where you’re destroying your gameObject :slight_smile:

You’re invoking a method to execute in 2 seconds time and then destroying the object on which the method is invoked.

Try:

Destroy(this.gameObject, 3.0f);

or rethink the way in which you’re doing this in the first place.

This code doesn´t work. If I delete the Destroy line, it works.
But it´s a TNT that explodes so i want it to be destroyed right when it explodes(OnTriggerEnter2D) with no delay. And when it explodes i want to switch to the Gameover scene (1) with 2 second delay.

I can´t find a solution :frowning: :frowning:

Turn off the renderer now, then destory later
Or put the loadLevel function on a different object that doesnt need to be destoryed (eg level manager object)

That´s what i wanted to do.
But it´s a prefab, there is no renderer. There is just Transform and Box Collider.

2nd way you suggest i also tried. It works. But only when putting TNT in the scene by myself and attaching the gameobject to it. But those TNT are spawned(instantiated), so it doesn´t know which object has the script where the loadLevel function is.

scrtipt attached on the TNT prefab:

using UnityEngine;
using System.Collections;
public class TNT : MonoBehaviour {
    public GameObject obj;
    public AudioClip[] audioclip;
    public GameOver gameover;
  
    void OnTriggerEnter2D(Collider2D other)
    {
        if(other.tag == "Player")
        {
            Instantiate(obj,transform.position,transform.rotation);
            AudioSource.PlayClipAtPoint(audioclip[0], transform.position);
            gameover.tntexploded = 1;
            Destroy(this.gameObject);
          
        }
    }
}

script attached on a gameobject that runs the function without destroying itself:

using UnityEngine;
using System.Collections;

public class GameOver : MonoBehaviour {
    public int tntexploded;

    void loadscene1()
    {
        Application.LoadLevel(1);
    }

    void Update()
    {
        if (tntexploded == 1)
        {
            Invoke ("loadscene1",2);
        }
    }
}

Is there any way to tell the script which game object has the script?

Give the tnt script a Start or Awake function, with a findWithTag, and tag the GameOver object with ‘gameover’ or something

or disable the collider, so it cant be triggered again during the scene load pause

What about this:

using UnityEngine;
using System.Collections;
public class TNT : MonoBehaviour {
    public GameObject obj;
    public AudioClip[] audioclip;
    void loadlevel()
    {
        Application.LoadLevel (1);
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if(other.tag == "Player")
        {
            Instantiate(obj,transform.position,transform.rotation);
            AudioSource.PlayClipAtPoint(audioclip[0], transform.position);
            Invoke("loadlevel", 2f);
            gameObject.SetActive(false);
        }
    }
}

I’m pretty sure that Invoke will continue to run while the object is inactive, it only gets cut off if the object is destroyed.