• 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
Question by changled · Feb 14, 2018 at 11:31 AM · instantiatedestroyspawnchildinvokerepeating

Spawned Enemies: How to Destroy child objects inside their own attached scripts without Destroying the parent object for InvokeRepeating??

I'm creating a (early version) tower defense shooter game with spawned enemies. I have GameObject called SpawnLocation that contains the location in w$$anonymous$$ch I would like to spawn my enemies, with a EnemyManager.cs script attached to it. In that, I call InvokeRepeating ("Spawn", 3f, 3f) in my Start(), and in Spawn(), I call Instantiate (enemy, transform.position, transform.rotation) (enemy being the game object prefab). Attached to that enemy prefab, I have an EnemyController.cs script w$$anonymous$$ch detects collisions and Destroy(gameObject).


When I destroy the first enemy, however, I receive an error preventing further spawns:

The object of type 'GameObject' has been destroyed but you are still trying to access it

I believe it is because since I passed in my enemy object, destroying itself after instantiation in its own separate function still destroys the parent object passed in, w$$anonymous$$ch means if I try to invokerepeat with that destroyed object, I'll have no object to instantiate. So how do I go about t$$anonymous$$s?


I've been frustratingly searc$$anonymous$$ng for an answer for aw$$anonymous$$le but couldn't find one specific to destroying multiple c$$anonymous$$ld game objects wit$$anonymous$$n their own instantiated scripts. I know Instantiate() returns the clone object when called in the parent, but how do I destroy it from that other attached c$$anonymous$$ld function, not the parent function? Deactivate() likely does the same t$$anonymous$$ng. If I instead Destroy() inside the parent function, how do I get the clone object if that object does not have a distinctive ID (and its position moves)? Using an array of enemy clone objects doesn't really allow me to know if it's been $$anonymous$$t 10 (or however many) times and needs to be destroyed. I've tried using coroutines, but seemed to run into problems as well. Here's a sample code:


 public class EnemyManager : MonoBehaviour {
     public GameObject enemy;
     public int playerHealth, spawnCount, deathCount, numEnemies;
 
     void Start() {
         numEnemies = playerHealth = spawnCount = 10;
         deathCount = 0;
 
         InvokeRepeating("Spawn", 3f, 3f); //give some time before spawning
     }
 
     void Update() {
     if(playerHealth <= 0)
         //end game somehow
     }
 
     void Spawn() {
         if(playerHealth <= 0 || deathCount >= numEnemies)
             return;
 
         Instantiate(enemy, transform.position, transform.rotation);
         spawnCount += 1; // keeps track of number of enemies spawned
     }
 }
 
 public class EnemyController : MonoBehaviour {
     public int enemyHealth;
 
     void Start() {
         enemyHealth = 10; //$$anonymous$$t each enemy 10 times to destroy it
         manager = GameObject.Find ("Spawn Location");
         managerScript = manager.GetComponent<EnemyManager>();
     }
 
     void Update() {
         //move player on a path
         if(enemyHealth <= 0) {
             managerScript.deathCount += 1; //successful kill of an enemy
             Destroy(gameObject); //or deactivate
         }
     }
 
     void OnTriggerEnter2D(Collider2D other) {
         if(other.gameObject.CompareTag("Bullet")) { //many triggers on board
             enemyHealth -= 1;
         }
         else if(other.gameObject.CompareTag("EndPath")) {
             managerScript.playerHealth -= 1;
             Destroy(gameObject); //so it doesn't keep on walkin forever
         }
     }
 }















Comment

People who like this

0 Show 1
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 changled · Feb 14, 2018 at 08:14 PM 0
Share

As I have added below, my main issue is Destroy()-ing each Instantiate()-ed child object within its own attached script without affecting my continued calls to Instantiate() in the parent script! I have noticed that I actually create ELEVEN new enemies even though spawnCount remains 10 at max. Additionally, I can Destroy() any of the enemies except the first one without affecting anything (aka I ignore the first enemy that appears and just attack the second onwards, which is ridiculous in actual gameplay). If I modify the first enemy, however, every additional enemy created using Instantiate() will have that modification... Why is this and how can I fix this so a player can kill all enemies on the field?

NOTE: (I'm not sure if my use of "parent" and "child" are correct since each Instantiation creates a new object in the first level of the hierarchy, not actually created as a child of the GameObject with the script that calls the Instantiate(). Maybe if I can somehow make them actual children this will work??)

1 Reply

· Add your reply
  • Sort: 
avatar image

Answer by LiamofElites · Feb 14, 2018 at 12:33 PM

Here are a few t$$anonymous$$ngs that I would do that might help you with your code logic,


  • in the OnTriggerEnter2D in the first if statement ( if(other.gameObject.CompareTag("Bullet")) ) after enemyHealth -= 1 add the if(enemyHealth <= 0) block after that line so right after taking damage you'll check if there's no health left instead of always checking in the update method

  • When declaring manager in the EnemyController class use gameObject.transform.parent.gameObject so if you want to create more spawn locations you don't have to worry about being limited to only 1 because you're using GameObject.Find();
  • I hope t$$anonymous$$s helps you somewhat, I'll be experiementing with your code in my practice project.

    Comment
    changled

    People who like this

    1 Show 2 · Share
    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 changled · Feb 14, 2018 at 07:54 PM 0
    Share

    Thank you for your response. I think checking for enemyHealth is a great idea and good practice.

    In regards to the second part, my problem isn't being able to spawn in different locations, but how to destroy each of those children after they die (aka their individual health reaches zero) without destroying the original game object used to continue spawning new enemies! Because in EnemyController, as soon as I call Destroy(gameObject), I seem to have an effect on the spawning capabilities of the parent going on at the same time. As I continued testing yesterday, I realized that Destroy()-ing the first enemy created will only produce me 4 enemies in total (aka it'll stop instantiating new children), likely because that's how long it took me to destroy the first enemy.

    avatar image changled · Feb 14, 2018 at 07:57 PM 0
    Share

    IN FACT, I put a Debug.Log("Enemy Spawned"); print right before the Instantiate() call in Spawn(), and I only get that log starting from the second enemy spawned!! This makes me suspect that the first time either Instantiate() or InvokeRepeating() is called, that first Instantiate() is called immediately with the actual GameObject passed in, and THEN the following Instantiate() calls return instances/clones of that original GameObject?? Not sure if I'm explaining this correctly.

    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

    99 People are following this question.

    avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

    Related Questions

    Instantiating prefab at child (spawnlocations are arrays) 2 Answers

    Stacking problem in my project 1 Answer

    Destroying childs and Instantiate [C#] 0 Answers

    Ontriggerenter and InvokeRepeating problem 1 Answer

    Why not can't spawn the object? 1 Answer


    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