- Home /
Script to set character to active after 3 seconds not working
Hello,
When my character controller walks into the collider around an npc: the npc is set to inactive, and a new npc is set to active in the same position. After 3 seconds I want the second npc to be set to inactive and the first npc to be set to active again in the new position. (So in the game looking like a character walking past and for three seconds appearing as a different person)
The script works in that on collision, the first npc is set to inactive and the second npc set to active in the right position.
The problem is that after 3 seconds - he doesn't switch back to the first character, and I can't work out why.
This is the script (Javascript):
var player : GameObject;
var dan : GameObject;
var exoGrey : GameObject;
var characterPosition : Vector3;
function Start () {
exoGrey.SetActive (false);
dan.SetActive (true);
}
function OnTriggerEnter () {
characterPosition = dan.transform.position;
dan.SetActive (false);
exoGrey.SetActive (true);
exoGrey.transform.position = characterPosition;
yield WaitForSeconds (3);
characterPosition = exoGrey.transform.position;
exoGrey.SetActive (false);
dan.SetActive (true);
dan.transform.position = characterPosition;
}
Does anyone have any idea why? (I'm not getting any errors in the console)
Thanks, Laurien
Here are a few questions i have:
Is the exoGrey variable properly assigned?
To what gameobject is the script attached?
I've attached the script to the collider, and the exoGrey variable has been properly assigned - for the first part of the script does work (in setting him to active).
I've tried a lot of things out - and it seems that when I use yield WaitForSeconds
in a function OnTriggerEnter
it doesn't work.
For example:
var carl : GameObject;
function OnTriggerEnter(other: Collider){
if (other.gameObject.tag == "Player")
yield WaitForSeconds (4);
Destroy (carl);
}
destroys carl immediately - rather than after 4 seconds.
Why is this?
Answer by Lockstep · Jun 11, 2013 at 11:30 PM
Big edit:
I was wrong about the return type of OnTriggerEnter. It can indeed be of type IEnumerator. I still wouldn't recommend it though. I tried the following script:
function OnTriggerEnter () {
Debug.Log("foo " + Time.time);
yield WaitForSeconds(3.4);
Debug.Log("bar " + Time.time);
}
And got: foo 0.48 bar 3.897639 Which means the yield gets executed correctly. The reason your short example did not yield, is that you didn't use curly brackets and thus the if statement only was relevant for the single line directly under it.
Back to your original problem. Make sure, that the script is not on a gameObject, which gets disabled. Since it works otherwise, this is pretty much the only thing that could go wrong.
Oh the scripting reference confused me - because it says OnTriggerEnter can be a co-routine, simply use the yield statement in the function.
I tried the new code, but it still destroys the character immediately. Do you know what I'm doing wrong?
var carl : GameObject;
function OnTriggerEnter(other: Collider){
StartCoroutine (CharacterSwap());
}
function CharacterSwap () {
if (gameObject.tag == "Player")
yield WaitForSeconds (4);
Destroy (carl);
}
According to, http://docs.unity3d.com/Documentation/ScriptReference/$$anonymous$$onoBehaviour.OnTriggerEnter.html """OnTriggerEnter can be a co-routine, simply use the yield statement in the function."""
It is strange that the Destroy still happens instant, even after specifically doing a StartCoroutine call. Perhaps make the delay a little longer, like 60 seconds, just to be 100% sure you can see what is happening there.
I've worked it out: I needed to put the yield function before the if (other.gameObject.tag == "Player")
. I didn't realise that.
This script works now:
var carl : GameObject;
var check;
function Start () {
carl.SetActive (true);
}
function OnTriggerEnter(other: Collider){
yield WaitForSeconds (4);
if (other.gameObject.tag == "Player")
carl.SetActive (false);
}
I'm still struggling to work out why the original script posted in the question doesn't work though.
I would assume ExTheSea meant this code snippet, where the tag of the other gameobject is checked.
function OnTriggerEnter(...){
if (other.gameObject.tag == "Player"){
yield WaitForSeconds (4);
Destroy (carl);
}
}
Yes i meant that part like Jamora pointed out.
@laurienvictoria: Hmm for some reason i think that you may disable the object the script is attached to in the part before the yield. This way the rest doesn't get executed.