- Home /
Invoke method not working
I am using a Invoke call to call a method after 2 seconds, but the problem is that invoke call is not working. My code is
public class collision : MonoBehaviour {
public GameObject explosionPrefab;
public GameObject enemyPrefab;
void enemyRespawn()
{
if (enemyLives.lives > 0)
{
Vector3 enemyClonePosition = new Vector3(Random.Range(13,40),-13.647f,0);
GameObject enemyClone = Instantiate(enemyPrefab,enemyClonePosition,Quaternion.Euler(6,230,6)) as GameObject;
}
else
{
Debug.Log ("game over"); // load game over page
}
}
void OnCollisionEnter (Collision objectCollided)
{
if (objectCollided.gameObject.name == "enemy" ||
objectCollided.gameObject.name == "enemy(Clone)")
{
this.gameObject.renderer.enabled = false;
GameObject explosion = Instantiate(explosionPrefab,transform.position,Quaternion.identity) as GameObject;
Destroy(explosion,3);
Destroy(GameObject.Find("enemy"));
Destroy(GameObject.Find("enemy(Clone)"));
enemyLives.lives--;
Invoke("enemyRespawn",2);
}
}
}
Instead of invoke, i also tried to use yield statement for time delay but that also doesnt work because some of the objects have been destroyed. The script is attached to BulletPrefab. I also debugged my program in Monodevelop. The execution stops at invoke and nothing happens.
Any kind of help/suggestion is useful.
is there a chance you could edit your code? note that that formatting didn't really work
@Fattie, whats the appropreate thing to do when we see a unformatted code question in the queue? Like this one. I wasn't sure, so I just left it there
I just try to fix bad formatting myself, but this wasn't too unreadable.
Except then sometimes people complain about me editing their questions -.-
@ben, in my opinion -- or at any rate what I do -- I just click "reject" and then i click "send message" and I type "Code must be formatted, please post again"
it's only a moment's work for the OP to post again
@Fattie, I will do that from now on. Thanks for the advice :)
Answer by Ashkan_gc · Jun 04, 2013 at 09:08 AM
The problem is that the gameObject which is StartCoroutine/Invoke is called from it's scripts is being destroyed (i.e. the bullet). You should call player.Invoke("EnemyRespawn",2);
Which in it player should reference a gameObject which is not being destroyed before Invoke times out.
But i am not destroying the bullet in this script. I am just making it disappear using renderer.enabled=false
yes but the bullet is aparently being destroyed somewhere else sooner than it should be.
ya...you were right. i increased the time after which the bullet will be destroyed. But there is another problem. Since i made the bullet invisible but it still exist there. So, sometimes that bullet hits the new clone of enemy and creates problem. To solve this, i wrote a new script for enemy respawn and attached it to enemy gameobject. And then from collision script, i called this function and then destroyed the bullet. It worked fine but i can not put the time delay function. I tried to use StartCouroutine in enemy respawn script but it shows error "Object reference is needed to access non static members". How to solve this problem?
You're probably using a capital letter somewhere where you should only be using a lower-case letter. Show the exact code, it's probably something trivial.
The script for collision attached to BulletPrefab is:
public class collision : $$anonymous$$onoBehaviour {
public GameObject explosionPrefab;
void OnCollisionEnter (Collision objectCollided)
{
if (objectCollided.gameObject.name == "enemy" ||
objectCollided.gameObject.name == "enemy(Clone)")
{
this.gameObject.renderer.enabled = false;
Destroy(objectCollided.gameObject);
enemyLives.lives--;
Destroy(this.gameObject);
yield return new WaitForSeconds(3.0f);
enemyLives.enemyRespawn();
}
}
}
And the script for respawning enemies attached to ground is:
public class enemyLives : $$anonymous$$onoBehaviour {
public static int lives = 3;
public GameObject enemyPrefab;
public static void enemyRespawn()
{
yield return new WaitForSeconds (3.0f);
if (enemyLives.lives > 0)
{
Vector3 enemyClonePosition = new Vector3
(Random.Range(15,40),-13.647f,0);
GameObject enemyClone = Instantiate
(enemyPrefab,enemyClonePosition,Quaternion.Euler(6,230,6)) as GameObject;
}
else
{
Debug.Log ("game over");
}
}
}
I have figured out the time problem. In this code, there is an error in the line Instantiate (enemyPrefab). The error is "Object reference is required to access non static member". Please tell me how to solve this problem.
Answer by syclamoth · Jun 04, 2013 at 02:49 AM
First suggestion- instead of using 'GameObject.Find("name")' to destroy your objects, just use 'objectCollided.gameObject'. It's much cleaner.
Second suggestion: Instead of using Invoke, use StartCoroutine, like so:
delegate void InvokedFunction();
IEnumerator WaitAndInvoke(float secondsToWait, InvokedFunction func) {
yield return new WaitForSeconds(secondsToWait);
func();
}
...
// Now, in your collision function where you want to
// make the delayed function call:
StartCoroutine(WaitAndInvoke(2, enemyRespawn));
Notice that I am referencing the 'enemyRespawn' function by a direct token, instead of a string: this means that there's no way for the program to compile without being correct (for example, if you used a string you could spell it wrong and nothing would tell you).
thanks syclamoth. your code works but only when i hit the enemy from front. If i hit the enemy on the top of head by a projectile motion, then script stops at the line StartCoroutine(WaitAndInvoke(2, enemyRespawn)); for enemy i have used mesh collider. Any suggestions on how to get it working.
That is a fairly strange problem. You should not normally get different behaviour in this situation. Does your enemy have more than one collider?
now its working fine. i just increased the time after that bullet will be destroyed. thanks for the help.
After some trials, i figured out that a single bullet sometimes hits multiple instantiated enemies. How to correct this one? A single bullet should only hit one time. I tried using active=false statement but then the script stop execution.
Answer by Yuneza · Mar 19, 2015 at 12:14 PM
try giving it float instead of int like Invoke("abc",2.0f,2.0f);
Your answer

Follow this Question
Related Questions
How does Invoke cope with mapping on frames 1 Answer
Invoke and Yield fail together- bug or feature? 1 Answer
Invoke Repeating Rate 1 Answer
Delay If statement in Update c# 2 Answers
Why does this not work? 1 Answer