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 Shindy117 · Jul 11, 2017 at 10:20 PM · gameobjectinstantiateenemyaccessspawner

Access a instantiated gameobject from a enemy spawner

Hey guys I am stuck on a issue.

Okay I have two scripts a enemy health script and a spawner script. They are very basic however I am running into a issue that has to do with the enemy is being destroyed.

What is happening?

  • when the enemy is instantiated the "int" value numTargets gets incremented by 1;

  • When it reaches the spawn limit the enemies spawner will stop spawning.

My problem:

  • cant seem to access the spawner script from my enemyHealth script to reduce the numTargets value by one. Because I want a new enemy to spawn after the current one is defeated.

I want several different spawn points using this script and I want the enemy that was spawned from a certain spawner only access that particular game object to reduce the numTargets variable.

Note: you will notice in my code I tried to use a spawnID to identify the particular spawner I wanted the enemy to target but I couldn't get it working.

I am stuck on this and would love any help. Scripts below: Enemy spawner script

 public class EnemySpawn : MonoBehaviour 
 {
     public GameObject enemy;
     public float spawnTimer;
     public int spawnLimit;
     public int spawnID;
 
     private EnemyHealth enemyHealth;
     private int spawnNum;
     private float timer;
 
     void Awake()
     {
        enemyHealth = enemy.GetComponent<EnemyHealth>();
     }
 
     void Start()
     {
         spawnID = Random.Range(1, 20);
     }
 
     void Update()
     {
         timer += Time.deltaTime;
 
         SpawnEnemy();
     }
 
     void SpawnEnemy()
     {
         if (spawnNum < spawnLimit)
         {
             if (timer > spawnTimer)
             {
                 Instantiate(enemy, transform.position, transform.rotation);
                 enemyHealth.spawnID = spawnID;
                 timer = 0f;
                 spawnNum++;
             }
         }
     }
 
     public void EnemyDestroyed()
     {
         spawnNum--;
     }
 }

Enemy Health script:

 public int startingHealth = 100;
     public int currentHealth;
     public int spawnID;
 
     private EnemyMovement enemyMovement;
     private EnemySpawn enemySpawn;
 
     void Awake()
     {
         enemyMovement = GetComponent<EnemyMovement>();
     }
 
     void OnEnable()
     {
         currentHealth = startingHealth;
     }
 
     void Update()
     {
        
     }
 
     public void TakeDamage(int amount)
     {
         currentHealth -= amount;
 
         if(currentHealth <= 0)
         {
             Death();
         }
     }
     
     void Death()
     {
         //Add enemy spawner script here.
         Destroy(gameObject);
     }
 }

Are there any suggestions other than tags? Cause that would take more work and more problems.

Thank you in advance.

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

4 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Cornelis-de-Jager · Jul 11, 2017 at 10:46 PM

Here is an alternative script you can use. Attach this to a single spawner. It will Have a set number of spawns. And will keep spawning an enemy when the previous one was killed, until it runs out of spawns. It Does not affect the number of spawns in other spawners. (Because I think that is what you want).

In addition with this you don't have to worry about the scripts interacting with each other. The spawner script will take care of spawning and tracking.

 public class EnemySpawn : MonoBehaviour 
  {
      /* Public Variables */
      public GameObject enemy;
      
      /* private Variables */ 
      [SerializeField] // makes it so it will show in inspector but still private
      int spawnNum;
      Transform trackedEnemy;
 
      void Start()
      {
        trackedEnemy = null;
        spawnNum = 5; // <-------------- Set the spawn Num here 
      }
     
      void LateUpdate () {
           
          if (trackedEnemy == null) // Only spawns when other is killed
             if (spawnNum > 0) // Only spawns when it has spawns left
                SpawnEnemy ();
             else
                // Out of spawns so deactivate
                GetComponent<EnemySpawn> ().enabled = false; 
       }
 
      void SpawnEnemy()
     {         
            // Instantiate Enemy
            GameObject enemyObj =  Instantiate(enemy, transform.position, transform.rotation) as GameObject;
                                         
             // Start Tracking this particular enemy
             trackedEnemy = enemyObj.transform;

            // Reduce number of spawns
           spawnNum--;

 
      }
  }
 

Comment
Add comment · Show 1 · 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 Shindy117 · Jul 12, 2017 at 03:16 PM 0
Share

Cool ill give it a try and let you know if it works for me

avatar image
0

Answer by Cynikal · Jul 11, 2017 at 11:45 PM

In your enemy health script, on void Death(),

You could do: GetComponent().EnemyDestroyed();

Furthermore, when creating the enemy, you should pass which Spawner spawned it, then reference it in the GetComponent portion..

mySpawner.GetComponent().EnemyDestroyed();

Comment
Add comment · Show 1 · 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 Shindy117 · Jul 12, 2017 at 03:16 PM 0
Share

Regarding the "which spawner spawned it" that's what I am trying to figure out. I tried using a public void function I could call but I still need to identify it.

avatar image
0

Answer by Scruffy250 · Jul 12, 2017 at 03:58 PM

If I came across a problem like this, I would make it so when the enemies spawn they become a child of the spawner. Then what you can do is set the numTargets to the child count of the spawner.

So in example the spawn limit is 4, one of the enemies die. The spawner now only has 3 children. You would then Instantiate a new enemy.

This means you don't need to search for other GameObjects or Scripts.

I hoped this helped.

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 Shindy117 · Jul 12, 2017 at 07:46 PM 0
Share

Hmmm okay I would just need to find out how to put a instantiated gameobject all a child. Ill give it a try

avatar image Shindy117 · Jul 12, 2017 at 08:05 PM 0
Share

Hey your method worked the based for me thanks. What do you think?

  void Start()
     {
         spawnNum = transform.childCount;
     }
 
     void Update()
     {
         timer += Time.deltaTime;
         spawnNum = transform.childCount;
 
         SpawnEnemy();
     }
 
     void SpawnEnemy()
     {
         if (spawnNum < spawnLimit)
         {
             if (timer > spawnTimer)
             {
                 GameObject enemyObj = Instantiate(enemy, transform.position, transform.rotation) as GameObject;
                 enemyObj.transform.parent = this.gameObject.transform;
                 
                 timer = 0f;
                 
             }
         }
     }
avatar image
0

Answer by Milo_del_mal · Jul 12, 2017 at 04:39 PM

Here is the answer, analyze it, I made it into a unityPackage:

Then, adapt it to your needs, I did not touch your code at all, I made just fresh code so you can figure stuff yourself.

https://drive.google.com/file/d/0ByN7a5K93ruaUzd2U0R2MjBKd2s/view?usp=sharing

Spawner test grabs a gameobject to spawn. When you press the key, it checks if it can spawn, then, it adds one to the count, spawns the object, stores the GameObject in a variable, and gets the Object's class, which has a public method call "Register", I will explain that later, but basically you register the method OnSpawnedObjectDeath to the newly spawned object's event.

Finally, when OnSpawnedObjectDeath is called, one is reduced from your count, allowing you to spawn another one.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
     public class SpawnerTest : MonoBehaviour {
         [SerializeField] GameObject goToSpawn; //Appears on inspector, but is private.
         [SerializeField] KeyCode keyToSpawn;
         [SerializeField] int spawnLimit = 4;
         int numOfSpawnedObjects = 0;
     
         
         // Update is called once per frame
         void Update () {
             if (Input.GetKeyDown (keyToSpawn)) {
                 bool canSpawn = numOfSpawnedObjects < spawnLimit;
                 if (canSpawn) {
                     Spawn ();
                 }
             }
         }
             
         void Spawn(){
             numOfSpawnedObjects++;
             var spawnOffset = new Vector3 (Random.Range (1f, 3f), Random.Range (1f, 3f), 0f);
             var spawnedGO = GameObject.Instantiate (goToSpawn, transform.position + spawnOffset, Quaternion.identity) as GameObject;
             spawnedGO.GetComponent<SpawnedObjectTest> ().RegisterDelegateTo (this);
             //This is a SpawnerTest, specifically, this Spawner test, so, the method OnSpawnedObjectDeath from
             // this object is called when the object dies.
     
         }
     
         public void OnSpawnedObjectDeath(){ //Public to be accesible by references
             numOfSpawnedObjects--;
             Debug.Log (gameObject.name + " delegate was called ");
         }
     }



Next script is: SpawnedObjectTest

The first method is called is "RegisterDelegateTo(SpawnerTest spawner)". This method is called by the spawner. It grabs the spawner and caches the reference into m_spawner; why? because when you register events, you must unregister them as well... Then adds the OnSpawnedObjectDeath Method to the ObObjectDeath event. Fianlly, it invokes a method to destroy itself in the ammount of time you specify.

When that method is called, you trigger the event, which calls the spawners method, and then you unregister and destroy.

ez.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class SpawnedObjectTest : MonoBehaviour {
 
     public delegate void ObjectEvent();
     public ObjectEvent OnObjectDeath;
 
     [SerializeField] float tToDestroy;
     SpawnerTest m_spawner;
 
     public void RegisterDelegateTo(SpawnerTest spawner){
         //Register you method to the event
         m_spawner = spawner;
         OnObjectDeath += m_spawner.OnSpawnedObjectDeath;
         Invoke ("DestroySpawnedObject", tToDestroy);
     }
 
 
     void DestroySpawnedObject(){
         if (OnObjectDeath != null) { //Check delegates for null, running 
             //null delegates causes errors.
             OnObjectDeath();
             OnObjectDeath -= m_spawner.OnSpawnedObjectDeath;
         }
         Destroy (this.gameObject);
     }
 }



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

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

104 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 avatar image avatar image avatar image avatar image avatar image

Related Questions

instantiating objects problem 1 Answer

copy enemy prefabs 1 Answer

NavMesh giving jerky like motion 0 Answers

SOLVED - Accessing a C# script value from another GameObject's JavaScript 2 Answers

Combine objects instantiated at runtime 2 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