• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Kahn_Shawnery · Mar 18, 2015 at 01:24 PM · gameobjectscript.disabledisabling

How to prevent a script on a disabled object from firing?

I am making a simple level system for my game. There is a LevelManager class attached to an empty object with 3 animated spawners childed to it. When the game starts the child spawners are all disabled. When the first wave begins a random spawner is enabled. The spawner carries out it's animation and a script attached to it fires off projectiles randomly. When the level is over, all children are disabled like this:

 foreach(Transform child in transform)
             child.gameObject.SetActive(false);  

I can see in the editor that they are all disabled, I assign all the spawners a color and they only appear when a spawner is activated. When the next wave starts, a new random spawner will activate. The problem is that the original spawner from the previous wave begins to fire projectiles. I can see that spawner is disabled in the editor, and it's not animating, but a steady stream of random projectiles continues to fire our in a straight line from it's parked position. It's clear the deactivated spawner is both disabled and parked at it's origin and that the script attached to it is firing..

So how do you tell a GameObject that has been deactivated to not fire off it's scripts? Why does it still fire them when disabled? Below is the code I use to activate and deactivate the spawners.

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 
 public class LevelManager : MonoBehaviour {
 
     public List<Transform> spawners;
     public float levelLengthTime = 45.0f;
     public GameManager gameManager;
 
 
     // Use this for initialization
     void Start () {
 
         spawners = new List<Transform>();
 
         foreach(Transform child in transform)
         {
             child.gameObject.SetActive(false);
             spawners.Add(child);
         }
     }
 
     void StartWave()
     {
         foreach(Transform child in transform)
             child.gameObject.SetActive(false);
 
         int spawnerToEnable = Random.Range(0, spawners.Count);
         spawners[spawnerToEnable].gameObject.SetActive(true);
         Invoke("StopWave", levelLengthTime);
     }
 
     void StopWave()
     {
         foreach(Transform child in transform)
             child.gameObject.SetActive(false);           
         
         gameManager.SendMessage("PrepareForNextWave");
     }    
 }

Also, if it helps, here is the script attached to the spawners themselves. This is the script that is firing even after the spawner is disabled:

 public class SpawnMissiles : MonoBehaviour {
 
     public GameObject projectileToLaunch;
     public float delay = 1.0f;
     public int numberToSpawn;
 
     private int enemyCount;
     private int spawnCounter;
 
     // Use this for initialization
     void Start ()
     {
         enemyCount = numberToSpawn;
         Invoke("Spawn", Random.Range(0.1f, delay));
     }
 
     void Spawn()
     {
         enemyCount--;
         GameObject instance = Instantiate(projectileToLaunch, transform.position, transform.rotation) as GameObject;
         instance.transform.SetParent(transform.parent, true);
 
         if (enemyCount > 0)
             Invoke("Spawn", Random.Range(0.1f, delay));
     }
     
     // Update is called once per frame
     void Update ()
     {
     
     }
 }

Comment
Add comment · Show 6
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bonfire-Boy · Mar 18, 2015 at 03:10 PM 1
Share

I think it's because you're using Invoke. Once you've made a call to Spawn(), that call itself generates the next call, and so on. $$anonymous$$aking a component/object inactive doesn't prevent its functions being called so, unlike things like calls to Update() and Coroutines, your self-invocation idiom doesn't need the object to be active.

So, ins$$anonymous$$d you could make Spawn() into a Coroutine, with the delay implemented using WaitForSeconds, and with the Coroutine starting itself as its final action.

That way, when the object is deactivated the spawning will stop, because the Coroutine will be killed.

Another way would be for the Spawn() function to check that the gameobject is active and get it to quit if the object isn't active (the critical part being to make sure that it doesn't Invoke another Spawn() call).

avatar image maccabbe · Mar 18, 2015 at 04:11 PM 2
Share

You could also use OnEnable() and OnDisable() to manually enable/disable Invokes.

avatar image Bonfire-Boy · Mar 18, 2015 at 04:44 PM 2
Share

Ah yes, or even just call CancelInvoke on the objects as well as (or ins$$anonymous$$d of) deactivating them.

avatar image Kahn_Shawnery · Mar 18, 2015 at 07:06 PM 0
Share

Thanks. These methods are unfamiliar to me. I'm sure CancelInvoke() will do the trick.

avatar image Kahn_Shawnery · Mar 18, 2015 at 07:17 PM 0
Share

I added Invoke() under OnEnable() and CancelInvoke() under OnDisable() and it works as expected now. Thanks to you both.

avatar image Bonfire-Boy · Mar 19, 2015 at 12:01 AM 0
Share

No problem, glad it helped. I have admit I find it a little unnatural using Invoke in this way. Because you have to manage things more, as you're finding, I tend to avoid the repeating Invoke thing in favour of coroutines, unless I need exactly the behaviour you don't want (ie something that continues regardless of whether the object is active). If you want the process to stop when the object is deactivated, then the coroutines way gives you that for free (and a lot more control if you want it). Probably just a matter of taste though, and I may be missing something in favour of repeating invokes.

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

How to create gameobject with different setting 1 Answer

Hi im trying to set a Gameobject variable in a script not in the inspector. 3 Answers

Access the a child of a GameObject through a script that is assigned to it 2 Answers

Prefab Script List not being assigned as unique - can you see why? 1 Answer

How to add a Script to a GameObject during Runtime [2016] 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges