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 /
  • Help Room /
avatar image
0
Question by An3Apps · Jul 11, 2019 at 05:10 AM · nullcomponentsgame objects

Why I have inconsistencies in getting a component

I'm working on an FPS game and I am using a bullet projectile with a rigidbody. I am using SphereCast to detect collisions. The SphereCast works fine, but I'm having problems with doing damage to the enemy.

This is my code attached to the bullet:

 RaycastHit rayhit = new RaycastHit();
         if (Physics.SphereCast(transform.position, radius, transform.forward, out rayhit, collisionDistance, layerMask, QueryTriggerInteraction.Collide))
         {
            
 
             if (rayhit.transform.tag != "Player")
             {
                 Debug.Log("NotPlayer");
 
                 if (rayhit.transform.GetComponent<Health>() == null)
                 {
                     Debug.Log("No Health Script");
                 }
                 if (rayhit.transform.GetComponent<Health>() != null && rayhit.transform.tag == "MetallicEnemy")
                 {
                     rayhit.transform.GetComponent<Health>().TakeDamage(Variables.pistolBaseDamage);
                     Debug.Log("DoDamage");
                 }
                 //Detach trail from bullet so that it shows after the bullet is destroyed
                 if (transform.childCount > 0)
                 {
                     Transform trail = transform.GetChild(0).parent = null;
                     Destroy(trail, 0.5f);
                 }
                 Destroy(gameObject);
             }
         }
 

As you can see, I get the health script of the enemy by getting the component from the rayhit game object. This works most of the time, but sometimes, the script is not found(it's null) even though it is on the enemy. By the way, I instantiate the enemies during runtime so I can't make the health script a public variable. I have no idea what causes this inconsistency. Does anyone know why this is happening and how I can stop this from happening?

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

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Bunny83 · Jul 13, 2019 at 03:05 PM

Well it's pretty unlikely this happens. The only cases where this might happen is when you have attached a child object to your enemy which also has a rigidbody attached. RaycastHit.transform will return either the transform of the rigidbody component the hit collider belongs to or if there's no rigidbody up the hierarchy it will just return the transform of the object the collider is on. Note that a collider can only belong to one rigidbody. So when you nest rigidbodies a collider will only belong to the rigidbody that is found first when going up the hierarchy starting at the collider that was hit.


So for example if the enemy has a rigodbody on it's root object and you hit any child collider of that enemy, you get the transform of the root object. However if you added another rigidbody as child to your enemy (for example a weapon that can be dropped), then the colliders of that child and sub child objects will belong to that rigidbody.


If that is the case you have several choices.

  • First prevent hitting that child rigidbody object in the first place by using layers for the objects and a layermask in the spherecast.

  • Instead of using rayhit.transform.GetComponent you can use rayhit.collider.GetComponentInParent.

GetComponentInParent will start searching for a component of that type on the object the collider is attached to. If no such component is found on that object it will go up the hierarchy and try again. This repeats until it reaches the topmost / root object. This would be similar to rayhit.transform.root.GetComponentInChildren however the other way round. So GetComponentInParent has the advantage that it will find the component that is as closest to the collider up the hierarchy while when starting at the root and going down the hierarchy it will find the topmost component.


Finally some other things I've noticed about your code:

  • You should use rayhit.transform.CompareTag("sometag") instead of using rayhit.transform.tag == "sometag". The CompareTag is faster and doesn't allocate memory

  • The way you treat your trail renderer can't work. First of all relying on a certain child index is prone to cause all sorts of errors when the hierarchical structure changes. It would be much better to just have a public GameObject variable to reference that trail renderer sub object. You can initialize this reference in the inspector. When you instantiate objects, the reference will reference the instantiated child correctly.

  • Next thing is this line Transform trail = transform.GetChild(0).parent = null; will actually store null in the "trail" variable. Assignments are handled from right to left.

  • Finally assuming trail now actually contains a valid reference to the trail child object, you can not destroy a transform component. You have to destroy the gameobject instead.

If you want to keep the code with the GetChild approach, you have to do:

 if (transform.childCount > 0)
 {
     Transform trail = transform.GetChild(0);
     trail.parent = null;
     Destroy(trail.gameObject, 0.5f);
 }

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

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

Use of if(Component) 1 Answer

ArgumentException: The prefab you want to instantiate is null. 2 Answers

Having issues with a NullReferenceException error. Code does as expected in some instances but I receive the error in others. Debugger directs me to line where if(hit.collider.tag == (DestructibleCube")). 1 Answer

Modify Custom Array Data 0 Answers

Array of scripts on 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