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 oliver82957 · May 23, 2017 at 02:49 PM · gameobjectprefabs

How to get a component from a prefab.

When creating an Enemy AI and then creating a prefab for it there seems to be a problem when I do damage to it. After I shoot at the prefab and kill it the other enemy seems to be invincible. I know where the problem is but don't know how to fix it. Here is some code from my bullet script which causes the problem.

  void OnTriggerExit(Collider enemyTarget)
     {
         if (enemyTarget.gameObject.tag.Equals("Enemy") == true)
         {
             GameObject enemy = GameObject.Find("ToonSoldier_WW2_German_Infantry");
             EnemyHealthScript enemyHealthScript = enemy.GetComponentInChildren<EnemyHealthScript>(true);
             enemyHealthScript.enemyHealth -= damage;
             Destroy(gameObject);
         }
     }

Comment
Add comment · Show 14
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 leech54 · May 23, 2017 at 06:51 PM 0
Share

When you say the "other enemy seems to be invincible" which object are you talking about? This script appears to find one object named ToonSoldier_WW2_German_Infantry and decrement it's child objects health and then destroy the gameobject the script is attached to.

avatar image danmartelly_caliper · May 23, 2017 at 07:04 PM 0
Share

GameObject.Find looks in the entire scene for the first instance of an object with that name. If you have multiple enemies with that same name, there's no way to guarantee which one is being returned. It's very likely that the enemy that you're reducing the health of is not the same one that you're shooting at.

If the Collider is attached to the enemy, then you may be able to get the correct enemy health script by doing enemyTarget.gameObject.GetComponentInChildren<EnemyHealthScript>()

Alternatively, you may want to look at the documentation for Transform.Find. You would write enemyTarget.transform.Find("ToonSoldier_WW2_German_Infantry") to get the child gameobject of the enemy that you want.

avatar image jmgek · May 23, 2017 at 08:15 PM 0
Share
  1. Do not use "tags" they are slow because they have to be converted to C#, ins$$anonymous$$d use gameobject.name since I can guarantee all your enemies are named "Enemy"

  2. Don't use GameObject.Find either, it looks through every gameobject in the scene and is INCREDIBLY slow. And you're also using it wrong, since once your Enemy collides with your trigger you're looking for it again AND doing it on every single trigger of this function.

  3. Take a look at using a class system for your Enemy and Infantry, you're using some things that can easily be contained in their own objects, you don't want to rely this much on Unity scene functions.

avatar image RobAnthem jmgek · May 23, 2017 at 10:12 PM 0
Share

I think tags are a lot more secure than names, names are nearly useless considering how easily they can be changed. I don't think the overhead for checking a tag is significant in any way at all. I pretty much consider names as "Editor-only organization helpers", even when I use a na$$anonymous$$g system I add my own Name field to a class.

avatar image jmgek RobAnthem · May 23, 2017 at 10:21 PM 0
Share

When you instance a prefab yes the change but normally you should not be expecting to change your gameObjects names. Also .Equals() returns a boolean, so you don't need to check if its true, you're basically doing this:

 if(True == True)

Either way if I was designing this I would do it like this, it's faster than any string or tag comparison:

     Enemyhealth enemy = collider.gameObject.GetComponent<Enemyhealth >();
     if (enemy != null)
     { }
Show more comments
Show more comments
avatar image Vollmondum · May 23, 2017 at 09:08 PM 0
Share

People are right, and here's how I'd do it.

Should be gameObject, if that's the one from the scene, and don't forget to add (Clone) to the name since instances are called that way if you don't change the name manually.

"Find" is a great function, you just need to use it right: when instantiating, use smth like:

 var allEnemies = GameObject.FindGameObjectsWithTag("Enemy");
 var totalEnemiesSpawned: int;
 
 function Spawn()
 {
 var newEnemy = Instantiate(bla bla bla);
 totalEnemiesSpawned++;
 newEnemy.name = "ToonSoldier_WW2_German_Infantry" + totalEnemiesSpawned;
 }
 
 function OnTriggerExit()
 {
 for(var thisEnemy in allEnemies)
 {
 //your code including thisEnemy variable...
 }
 }

That will give unique names for all instances of the enemy. And THAT's when you use find by name among those with tags.

avatar image oliver82957 · May 23, 2017 at 11:06 PM 0
Share

I am new to unity and the general field of game design and code. I could tell that the flaw was that it was searching for all of the enemy with the same name and that the code was over complicated (which I had earlier simplified but did not update). I could tell the flaws but did not have the experience to figure out so thanks for helping and I will probably be asking a lot more questions in the future. By the way @jmgek what do you mean by hardest names.

avatar image jmgek oliver82957 · May 23, 2017 at 11:12 PM 0
Share

Hard set hard coded names, values you have assigned in your code that is not generated or obtained through data and logic in your code:

 string myString = "This String";

There can be many problems with this, mainly what happens if your Enemy tag or name gets changed, it's hard to track down the values like that. A better way is to have this.

 public enum eTypesOfEntities{
     Enemy, 
     Player, 
     Dogs,
 };

Show more comments

5 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by HolgEntertain · May 25, 2017 at 02:54 PM

When you use GameObject enemy = GameObject.Find("ToonSoldier_WW2_German_Infantry"); I think you'll find the first gameobject of that type. I think you want to to GameObject enemy = enemyTarget.gameObject; Saves you a lookup and also should reduce the health of the correct enemy.

Also you should probably read some more about prefabs. You can't "shoot at the prefab" You're shooting at an instance created from a prefab. Just a friendly tip.

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 Zooow · May 25, 2017 at 04:21 PM

Not sure what's making your enemies invincible, but here's at least an issue i see with your code : GameObject.Find("ToonSoldier_WW2_German_Infantry"); will return the first object tag with "ToonSoldier_WW2_German_Infantry", not the one your bullet collide with.

I think you actually don't need to search for this object as you already have it with enemyTarget.gameObject

So you could write something like :

         if(enemyTarget.gameObject.tag.Equals("Enemy"))
         {
             EnemyHealthScript = enemyTarget.gameObject.GetComponentInChildren<EnemyHealthScript>();
             if(EnemyHealthScript != null)
             {
                 enemyHealthScript.enemyHealth -= damage;
                 Destroy(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
avatar image
0

Answer by Headzup · May 25, 2017 at 04:29 PM

Maybe you destroy the script from the other enemies then?

I don't know your comeplete code, but so far I understand it, you search for enemies and then destory them.

I would search the problem at line 7-9 and trying to work with this

Update: Do you have an enemy as a prefab from the beginning in the scene or do you spawn via. script all enemies?

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 Bill9009 · May 24, 2017 at 03:06 AM

When you use Component.GetComponentInChildren it only searches for the component in the first enemy.Component.GetComponentInChildren Unity Manual

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 oliver82957 · May 25, 2017 at 03:20 PM

I fixed the problem and I could update the script to this answer if wanted.

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 danmartelly_caliper · May 25, 2017 at 03:29 PM 1
Share

You should choose an answer and/or explain what went wrong and how you fixed it in case it helps someone else one day.

avatar image RobAnthem danmartelly_caliper · May 25, 2017 at 03:40 PM 1
Share

+1 This goes undone far too often, I'd have a much higher answer ratio if that wasn't the case lol.

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

12 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

Related Questions

Reinitialize prefab 0 Answers

Is it necessary to assign the result of Instantiate() to a variable and is there a need to always typecast? 1 Answer

Problem to play animation in C# 5 Answers

using Contains(gameObject) to find and destroy a gameObject from a list 2 Answers

how to show coordinates on the prefab? Using multidimensional arrays? 0 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