Problem delaying script changes.

Hi, I’m making an RPG for a uni project and it’s been decided that we want a Final Fantasy style scene switch. If you don’t know what that is then when the player collides with an enemy a new screen/scene appears as a battle arena. I have this implemented already, it switches from my “Main Level” scene to my “BattleArena”. Unlike Final Fantasy though my game will not be turn-based.

My code works so that when the enemy is destroyed (in this case a dragon) the scene will switch back to the main level but as you may or may not know this makes the switch rather fast. I would like for the main level scene to load 2 seconds after the enemy is dead.

At the moment I have 2 scripts, one for the dragon and one for the scene switch (so I can use it for other enemies).

This is my switch scene code -

function OnTriggerEnter (other : Collider) 
{
	Application.LoadLevel("Main Level");
}

I have tried yield WaitForSeconds but it does nothing for me and I can’t seem to find another function to do what I want.

Any help would be appreciated.

Thanks,

Cas:face_with_spiral_eyes:

Edit - Scene changes, not script.

A cut and paste of my answer to another thread:

Obviously you need to adapt this a bit, but the basic InvokeRepeating() idea applies. :slight_smile:

Thanks for the reply but i’m a little confused. I tried implementing that code but i couldn’t get it to work.
For the moment I NEED it to run when the trigger is, well, triggered. I don’t know how (or even if you can) to use OnTriggerEnter without the function part of the code or is there another way of doing this?

Within OnTriggerEnter() you’re currently calling Application.LoadLevel(), right?

To add my delay idea to your code, within OnTriggerEnter() you’re going to call InvokeRepeating() instead. Either way, OnTriggerEnter() will have a body, so you don’t have to worry about missing function parts. :slight_smile:

InvokeRepeating CancelInvoke are also discussed in the Unity docs:

Not sure why you would repeat cancel anything here…
Just use Invoke with a delay no?

function OnTriggerEnter (other : Collider) 
  {
   Invoke("LoadMainScene",3); // load main after 3 sec delay.
  }
 
function LoadMainScene()
  {
   Application.LoadLevel("Main Level");
  }

Even better. :slight_smile:

Thanks for the replies. I must be doing something wrong somewhere because I cannot get it to work. My dragon dies but the scene doesn’t switch or the dragon dies and it does switch but there’s no delay.

Do I need to put this code into my dragonControl script or can it work on it’s own? I realise that the code I have asked about won’t work if the enemy has to take multiple hits so I need to add that when the enemy is deleted(dies) the scene changes.

Cheers,

Cas

This because you are calling the load level in the wrong place. The Invoke should be called in the dragons death method (or any sequence that ends fighting the dragon). As it stands every hit is calling Invoke within that 3 second delay…

Have a little more patience you will soon see the solution. If not PM me.

I have been trying to get this code working again and I am still stuck. You’re most likely just as frustrated with me asking about it as I am trying and failing. I’ve been trying various things to see if I can get it to work but I can figure it out.

var LookAtTarget:Transform;
var damp = 5.0;
var bulletPrefab:Transform;
var savedTime=0;
private var dead = false;

function Update () 
{
	if (LookAtTarget)
	{
		var rotate = Quaternion.LookRotation(LookAtTarget.position - transform.position);
		
		transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * damp);
		
		var seconds : int = Time.time;
		var oddeven = (seconds % 2);
		
		if(oddeven)
		{
			Shoot(seconds);
		}
	}
}

function Shoot(seconds)
{

	if(seconds!=savedTime)
	{
	var bullet = Instantiate(bulletPrefab, transform.Find("spawnPoint").transform.position, Quaternion.identity);
	
	bullet.gameObject.tag = "enemyProjectile";
	bullet.rigidbody.AddForce(transform.forward * 500);
	
	savedTime=seconds;
	}
}

function OnTriggerEnter (hit : Collider )
{	
	if(hit.gameObject.tag == "playerProjectile")
	{
		Destroy(hit.gameObject.Find ("dragon"));
		Invoke("LoadMainScene",3);
	}
}

function LoadMainScene()
{
	if(dead)
	{
		Application.LoadLevel("MainLevel");
	}
}

Thanks,

Cas

I don’t know if abruptly destroying your dragon gameobject is a good idea. I thought you had created a dragon death method? Like in your OnTriggerEnter you check the total number of hits the dragon can take. You increment the hit counter on every “playerProjectile” detected. On the max number you call your dragon dies / exits scene method…

It may also be a good idea to disable any further collisons between your playerProjectile and dragon after the final hit point count is reached assuming this script is being dropped on your dragon gameobject?
e.g.

[SIZE=2][SIZE=2][COLOR=black]var hitpoint = 5;[/COLOR][/SIZE][/SIZE]
[SIZE=2][SIZE=2][COLOR=black]function OnTriggerEnter (hit : Collider )[/COLOR][/SIZE]
[SIZE=2][COLOR=black]{ [/COLOR][/SIZE]
[SIZE=2][COLOR=black]if(hit.gameObject.tag == "playerProjectile")[/COLOR][/SIZE]
[SIZE=2][COLOR=black]{[/COLOR][/SIZE]
[SIZE=2][COLOR=black]--hitpoint;[/COLOR][/SIZE]
[SIZE=2][COLOR=black]if (hitpoint == 0  ! dead ) {[/COLOR][/SIZE]
[SIZE=2][COLOR=black]  Physics.IgnoreCollision(gameObject.collider,hit,true);[/COLOR][/SIZE]
[COLOR=#2b91af][SIZE=2][COLOR=black]  dead=true;   [/COLOR][/SIZE]
[SIZE=2][COLOR=black]//Destroy(hit.gameObject.Find ("dragon"));[/COLOR][/SIZE]
 
[SIZE=2][COLOR=black]// find "OtherAttachedDragonScriptName" and run it's custom dragon death method aka "runMyKillDragonFunction"..[/COLOR][/SIZE]
[SIZE=2][COLOR=black] hit.gameObject.Find ("dragon").GetComponent("OtherAttachedDragonScriptName").runMyKillDragonFunction();[/COLOR][/SIZE]
[SIZE=2][COLOR=black] Invoke("LoadMainScene",3);[/COLOR][/SIZE]
[SIZE=2][COLOR=black]} [/COLOR][/SIZE]
[SIZE=2][COLOR=black]}[/COLOR][/SIZE]
[SIZE=2][COLOR=black]}[/COLOR][/SIZE]
[/COLOR][/SIZE]

I don’t know how you are attaching what to what dragon wise…