Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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
0
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 which 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 which 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, which means if I try to invokerepeat with that destroyed object, I'll have no object to instantiate. So how do I go about this?


I've been frustratingly searching for an answer for awhile but couldn't find one specific to destroying multiple child game objects within 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 child function, not the parent function? Deactivate() likely does the same thing. 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 hit 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; //hit 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
Add comment · 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(). $$anonymous$$aybe if I can somehow make them actual children this will work??)

1 Reply

· Add your reply
  • Sort: 
avatar image
1

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

Here are a few things 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 this helps you somewhat, I'll be experiementing with your code in my practice project.

    Comment
    Add comment · 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.

    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

    GetChild(0) returns nonexistent object 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