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
1
Question by evildead9000 · Jan 07, 2020 at 03:56 PM · variablespawncomponentprefab-instance

How can I access a GameObjects components using an instantiation variable?

I am trying to dynamically spawn enemies. All variables are declared and set prior to the instantiation code.

_enemy_1 = Zombie; (Zombie is a prefab.) _zombie_level is a variable, which is in a Zombie script attached to its prefab.

 _spawned_enemy_1 = Instantiate(_enemy_1, _enemy_1_spawn_position, Quaternion.identity);
 Zombie _Zombie = _spawned_enemy_1.GetComponent<Zombie>();
 _Zombie._zombie_level = _enemy_1_level;

This is what I have so far and it works fine. However, I don't want to hard-code anything (if possible), which means not using the prefab name Zombie to GetComponent.

Is there a way I can access the _zombie_level variable using _spawned_enemy_1 as the GameObject? _spawned_enemy_1 is not a prefab, so I am receiving errors. I hope my explanation was clear and I appreciate any suggestions.

Thank you!

Comment
Add comment · Show 3
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 Anis1808 · Jan 07, 2020 at 04:21 PM 0
Share

I am not sure if it is what you want, but you could simply skip the 2nd line

 _spawned_enemy_1.GetComponent<Zombie>()._zombie_level = _enemy_1_level;
avatar image evildead9000 Anis1808 · Jan 07, 2020 at 04:42 PM 0
Share

Thanks for the quick response. However, I'm trying not to use "Zombie" at all. Perhaps, I'll need to change "_zombie_level" to just "_level" since it may not end up being a zombie. I hope I make sense!

Since _enemy_1 = Zombie, I attempted to use: _spawned_enemy_1.GetComponent<_enemy_1>();

It didn't work. I wanted to use: _spawned_enemy_1._zombie_level = (an integer variable; 1, 2, etc.);

With the above mentioned changed it would then be: _spawned_enemy_1._level = 1 or another integer.

Any other suggestions would be much appreciated. Is my implementation way off?

avatar image IINovaII evildead9000 · Jan 07, 2020 at 08:38 PM 0
Share

I'm asking a question out of confusion. Are there other enemy types which has _level field named differently but has same purpose?

4 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by IINovaII · Jan 08, 2020 at 03:43 PM

Doing it that way will only lead to bloating code and can become unmanageable as the number of enemies grows. Using the game object name to differentiate enemies is a terrible practice. If all you wanted to do is access level variable which all the enemies have, you can do this either through inheritence or by composition.

Inheritance Method
All enemies should inherit from the same class which contains the variable level. It would look something like this.

 public class Enemy : Monobehaviour
 {
        public int Level;
 }
 
 public class Zombie : Enemy {}


You can get the component to set the zombie's level like this.

 Enemy enemy = _spawned_enemy_1.GetComponent<Enemy>();
 enemy.Level = _enemy_1_level;


You can check if it's a zombie or not by doing something like this.

 if(enemy is Zombie)
 Debug.Log("This is a zombie.");


Composition Method
You can do the similar thing using interfaces. Add an interface called ILevelable to Zombie class. It would look something like this.

 public interface ILevelable{
 int Level {get;set;}
 }
 
 public class Zombie : Monobehaviour, ILevelable{
 public int Level {get; set;}
 }

You can just access the enemy via the interface like this as long as they contain this interface.

 ILevelable enemy = _spawned_enemy_1.GetComponent<ILevelable>();
 enemy.Level =  _enemy_1_level;

Comment
Add comment · Show 4 · 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 MrBunny · Jan 08, 2020 at 06:09 PM 0
Share

Using interfaces would also benefit making it easier for Unit testing. Breaking it down into more components as you did with levelable is what I think aligns with Unity's patterns.

avatar image IINovaII MrBunny · Jan 08, 2020 at 10:02 PM 1
Share

It's encouraged to use composition over inheritance in games development, at least. You can easily swap in/out easily unlike in inheritances. Inheritances can get too difficult to maintain when the level of inheritance is too high.

avatar image evildead9000 · Jan 09, 2020 at 03:16 AM 0
Share

That's exactly what I was trying to do.

I've already implemented it and cleaned up a LOT of my code in the process. Your explanation was great as well.

Item marked as Best Answer. Reputation point granted.

Thanks much!

avatar image IINovaII evildead9000 · Jan 09, 2020 at 03:19 AM 0
Share

I'm glad that I was able to help you out. -Nova

avatar image
1

Answer by Brithingr · Jan 07, 2020 at 04:42 PM

_spawned_enemy_1.getComponent<neededComponent>();. Dont forget to use an explicit typification when instatiat and object

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 evildead9000 · Jan 07, 2020 at 05:05 PM 0
Share

I'm not sure how to use explicit typification.

The only way I've been able to get it to work is by specifically using "Zombie" as such: _spawned_enemy_1.getComponent(Zombie);

I am unable to replace "Zombie" with a variable, since the variable is not a prefab GameObject. Would an explicit typification at instantiation resolve it? Can you give an example?

If explicit typification does not work (although I hope it does), would it be possible to create a blank "_enemy_1" prefab without a sprite or script attached to it. Afterward instantiation, set a parent, script, and sprite?

avatar image
0

Answer by MrBunny · Jan 07, 2020 at 06:30 PM

Something like this might work. I believe unity will try and pull the first component it can find that is using the IZombie interface.

 public interface IZombie
 {
     int zombie_level { set; }
 }
 
 public class Zombie : MonoBehaviour, IZombie
 {
     public int _zombie_level = 0;
     public int zombie_level { set => _zombie_level = value; }
 }
 
 public class mySpawner : MonoBehaviour
 {
     GameObject _enemy_1;
     Vector3 _enemy_1_spawn_position;
     GameObject _spawned_enemy_1;
 
     public void SpawnMe(int _enemy_1_level)
     {
         _spawned_enemy_1 = Instantiate(_enemy_1, _enemy_1_spawn_position, Quaternion.identity);
         var _Zombie = _spawned_enemy_1.GetComponent<IZombie>();
         _Zombie.zombie_level = _enemy_1_level;
     }
 }
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
avatar image
0

Answer by evildead9000 · Jan 08, 2020 at 02:41 PM

Thanks for all for the suggestions. However, they weren't quite what I was looking for. I didn't want any reference at all to Zombie or to hard code it. I was only able to get it to work using a function, which contained a switch if the _spawned_enemy_1.name matches, so it would still work dynamically.

 Get_Enemy_Component(_spawned_enemy_1.name, _enemy_1_level);

Here is the function:

 private void Get_Enemy_Component(string enemy_Type, int _enemy_level)
 {
     switch(enemy_Type)
     {
         case "Zombie(Clone)":
             Zombie _Zombie = _spawned_enemy_1.GetComponent<Zombie>();
             _Zombie._level = _enemy_level;
             break;
     }
 }

As I add more enemies, I can add more switch cases. I didn't want any reference to Zombie because I will make "_enemy_1" equal a different prefab (for game level 2 and so forth), like "Creature" for example. I'll then add a case to it in the switch; that way I can use the same code to call upon whatever prefab I choose.

I'm still kind of new to Unity, and there may be a better way, but it's working well now.

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 evildead9000 · Jan 09, 2020 at 03:19 AM 0
Share

As per IINovaII's comments above, this way does indeed get messy.

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

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

Enable/Disable a Component by using a String Variable for the Component name 2 Answers

Problem: Random Instantiating more than one prefab? 1 Answer

Accessing a variable of a script from another scene. 7 Answers

Change variable of ex2D Sprite using the component ExScreenPosition via code .js script 0 Answers

Access the same component 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