Coroutine couldn't be started because the the game object is inactive!

I have a CastManager that gets notified when the player cast a spell.

public void setTarget(GameObject targ){
     ((ProjectileSpell)currSpell).target = targ.transform.parent.gameObject;
    }

After this has happened, in the Update() function, cast() in the currSpell is called. cast() then does this:

modelInstance = (GameObject)Instantiate(model, source.transform.position + new Vector3(0.4f, 0.6f), Quaternion.identity);
startMovement(GameObject.Find(target.name+"/DefaultTarget").transform);

startMovement is in ProjectileSpell which is the super class of SimpleFireballSpell:

/** Moves to model into the direction of targ */
public void startMovement(Transform targ){
    isTravelling = true;
    StartCoroutine(moveToTarget(targ));
}
   
IEnumerator moveToTarget(Transform targ) {
    while(Vector3.Distance(modelInstance.transform.position, targ.position) > 0.1f) {
            modelInstance.transform.position = Vector3.MoveTowards(modelInstance.transform.position, targ.position, speed * Time.deltaTime);
            yield return null;
        }

But after the instantiation, my fireball doesn’t move. The error at runtime is

I debugged the code while running and in public void startMovement, the target was filled but when the coroutine is called, target is null Ă´.O can someone elaborate on this? Thanks in advance :slight_smile:

1 Like

In order to run a Coroutine on SimpleFireballSpell it has to be active. Make it active before you start the coroutine.

1 Like

But how can it be not active if it gets rendered in the scene? I mean, my prefab looks like this:
New Empty

SimpleFireballSpell script
Model and Particle system

When it is rendered in the scene, it contains all 3 components. Is there anything I missed about Instantiate()? I assume that all Components have the active status as I defined in the prefab.
Also, when debugging, it is active and enabled :-?

1 Like

Insert, between lines 3 and 4, a check to see if the object is active:

Debug.Log("Active? "+gameObject.activeInHierarchy);
4 Likes

It says false. I dont understand that O.O
Why is that? And how can I change it? Sorry if this sounds noob but I must have missed sth

Insert a Debug.Break() statement in right before you attempt the coroutine spawn.

When that statement triggers the Unity game engine will still be running but paused and you can go inspect the object in your hierarchy and make sure the object is SetActive and also the component containing the coroutine is enabled.

Debug.Break() is really awesome for stuff like this because you get control of the system precisely where you need to check it.

Kurt

1 Like

Well, almost precisely. In a traditional break (programming-wise), code execution stops at the actual line on which the break is placed. You can then step through line by line and watch local variables change each line, and so on.

Debug.Break() is different in that it pauses execution at the end of the frame. So you’ll get the correct frame, and it’s useful for debugging this sort of thing, it’s just important to note that that isn’t what “break” usually means.

(Unity + MonoDevelop does support a traditional breakpoint as well, if stepping through lines is what you actually need.)

3 Likes

But as I mentioned earlier, when I debug, before calling the coroutine targ will be filled while when I step INTO the coroutine, it is null right as a parameter. I don’t know what more I can debug here.
So why is activeInHierarchy false while enabled and active are true in all lines when I debug?

Maybe I should notice once more that I am a Unity beginner and maybe I miss sth about Instantiate(), “activation/enabling” or coroutines. If this is an easy problem (and I am sure it is nothing fancy), please just explain for dummies and/or post the line of code I need. I really appreciate your help guys :slight_smile:

Another remark: I can not activate or deactivate my script in my prefab. Can this have something to do with this?

Are you calling StartCoroutine from an object inheriting monobehaviour?

StartCoroutine() is called from ProjectileSpell which indirectly inherits from MovoBehaviour, yes.

Something is making SimpleFireballSpell inactive. It could be inactive in the prefab or some other code could be making it inactive. The solution is to ensure it’s active while the coroutine is running. Beyond that there isn’t much more assistance to provide.

Seems I made something wrong when setting up the prefab. How to fix this?

A button in the scene evokes a fireball being cast. I want to connect my spell with that button. But what I did is to create a prefab that has this script in it. But my CastManager takes a Spell. How can this even work? I can connect a prefab (new empty type GameObject) with a function in my CastManager that takes a spell?

So, this is the problem and I wired it totally weird. I tried for hours but cant get the right approach.

How would one handle this? Button calls a function that takes a Spell and then delegates it to the more specific Spell (e.g. SimpleFireballSpell). This specific spell should know the prefab.

SimpleFireballSpell : ProjectileSpell : Spell : MonoBehaviour

1 Like

Did you found the issue?
I just met this. the gameobject active ticked. Component enable ticked. But don’t know why?
activeInHierarchy false.

Update : I just found the issue, For those who stuck with this.
The GameObject just have been created it passed Awake, but didn’t pass Start method yet.
Occur when I instantiate from a prefab and do StartCoroutine immediately.

However this is strange…

4 Likes

Hey! deLord, or anyone. if this happens , where it says “object is inactive” make that object a prefab, delete it. drag the prefab on and it should be fixed. it happened to me!! your welcome ~

6 Likes

Thank you. I had an altogether similar issue and this fixed it. Really made my evening!

1 Like

Adding another solution for a similar problem.

If you’re using a Singleton that is a prefab, make sure you’re calling the instance of the prefab otherwise it won’t be using the active Singleton but the prefab instead (which is not active in the scene)

5 Likes

How can I know which instance I’m calling on?

When you instantiate the object into the scene, you have to grab a reference to it then. If you don’t do that, you’re probably calling on the prefab.

public GameObject somePrefab;
void Start() {
GameObject someInstance = Instantiate(somePrefab);
SomeScript ss = someInstance.GetComponent<SomeScript>();
ss.StartCoroutine(ss.SomeCoroutine() );
}

Generally, for any public GameObject references in my scripts, I’ll add “prefab” to their name if I intend them to be prefabs. That helps keeps the objects in scene separate from the prefabs.

6 Likes

That worked for me! As StarManta correctly pointed out: The problem is that you’re referencing the actual prefab itself - which is not active in the scene. You need to create a gameobject and set that to equal the instantiated prefab. Something like
GameObject go = Instantiate(prefab);
go.GetComponent().SomeCoroutine();

1 Like

That didnt work for me do you have any other solutions