7

I am writing a method to check if a gameObject has a component.

Here it is:

public static bool HasComponent <T>(this GameObject obj)
{
    return obj.GetComponent<T>() != null;
}

And I'm using it like this:

void Update()
{

    if (Input.GetKey("w"))
    {
        if (gameObject.HasComponent<Rigidbody>())
        {
            print("Has a rigid body.");
            return;
        }

        print("Does not have rigid body.");
    }
}

The gameObject does NOT have a rigid body but it is still printing that it does have.

derHugo
  • 83,094
  • 9
  • 75
  • 115
messedupsongguy
  • 319
  • 2
  • 4
  • 10
  • Try debug.logging the object name to make sure that you didn't accidentally place this script on another object, maybe? – andeart Feb 03 '16 at 01:18
  • I did, still prints that it has a rigidbody even though it does not. – messedupsongguy Feb 03 '16 at 01:21
  • I don't see anything wrong with the code. But I am able to replicate it on my PC! :O Good one. Debugging... – andeart Feb 03 '16 at 01:24
  • are you sure `GameObject` has a non-static public method of `HasComponent`. As you wrote it in your own class and trying to access it via gameObject?? If anybody can help me to understand this?? As he is getting proper logs :|, irrespective of he is calling it via gameObject which should not be and even using wrong signature (with void parameter)? :O – Hamza Hasan Feb 03 '16 at 05:47
  • @JoeBlow OP mentioned "The gameObject does NOT have a rigid body but it is still printing that it does have." This is my question – Hamza Hasan Feb 03 '16 at 13:16
  • 1
    Hi @HamzaHasan ... the answer is that OP **made a syntax error** in the generic. You have to have a **where** clause on the end or the return value will be nonsense from the call GetComponent() .... it's returning I believe **whether it has *any component at all* attached**. It's just a syntax error, Hamza. – Fattie Feb 03 '16 at 13:21
  • 1
    @JoeBlow Ok, so it is returning a non null value. Is it because of this too? – Hamza Hasan Feb 03 '16 at 13:27
  • 1
    Hi Hamza, sorry if I am not being clear. I believe since "T" is basically "blank" ... you are asking it "GetComponent<>()". Note there is ***NOTHING*** in the angle braces. That means you are asking it ***IF IT HAS ANY COMPONENT AT ALL -- OF ANY TYPE WHATSOEVER.*** Am I explaining this ok? Of course, it has to have components attached (of some type!) so it is returning "true". Makes sense? – Fattie Feb 03 '16 at 13:30
  • But note that it is **really just "undefined" to not "where" the "T" there** -- the result is just nonsensical. Just like any syntax error. Do you know what I mean? – Fattie Feb 03 '16 at 13:31
  • wowwww... Now, all is well. Thank you so much @JoeBlow – Hamza Hasan Feb 03 '16 at 14:23

2 Answers2

14

It is just...

public static bool HasComponent <T>(this GameObject obj) where T:Component
    {
    return obj.GetComponent<T>() != null;
    }

Note that you forgot the

where T:Component

part of the first line!

With that syntax error, the extension is meaningless: it's always finding "some component" since T is "blank".


NOTE.

Explanation of "what the heck is an Extension".

For anyone reading this who is not familiar with categories in c# .. that is to say "Extensions" in c# ... here's a easy tutorial ...

enter image description here

Extensions are critical in Unity.

You use them in pretty much every line of code.

Basically in Unity you do almost everything in an Extension.

Note that because extensions are so common, the OP did not even bother showing the wrapper class. Extensions always sit in a file like this:

public static class ExtensionsHandy
// The wrapper class name is actually irrelevant - it is not used at all.
// Choose any convenient name for the wrapper class.
    {
    
    public static bool HasComponent <T>(this GameObject obj) where T:Component
        {
        return obj.GetComponent<T>() != null;
        }
    
    public static bool IsNear(this float ff, float target)
        {
        float difference = ff-target;
        difference = Mathf.Abs(difference);
        if ( difference < 20f ) return true;
        else return false;
        }
    
    public static float Jiggle(this float ff)
        {
        return ff * UnityEngine.Random.Range(0.9f,1.1f);
        }
    
    public static Color Colored( this float alpha, int r, int g, int b )
        {
        return new Color(
            (float)r / 255f,
            (float)g / 255f,
            (float)b / 255f,
            alpha );
        }
  
    }

In the example I included three typical extensions. Normally you'd have dozens or even hundreds of extensions in a project.

(You may prefer to group them in different HandyExtensions files, or just have one enormous HandyExtensions file.)

Every engineer and team has their own "common extensions" they use all the time.

Here's a typical example question about a subtlety of extensions in C#.

Note that in older languages you usually call extensions a "category".

In c# it is an "extension", but "category" or "extension" are both common.

As I say, you use these constantly in Unity.


If you like that sort of thing, here's a beautiful one:

// Here's an unbelievably useful array handling category for games!

public static T AnyOne<T>(this T[] ra) where T:class
    {
    int k = ra.Length;
    int r = UnityEngine.Random.Range(0,k);
    return ra[r];
    }
Fattie
  • 27,874
  • 70
  • 431
  • 719
  • 1
    Defaulters :P.. Similar users also exists in gamedev like [this one](http://gamedev.stackexchange.com/users/78138/alexandru-gurita) :D – Hamza Hasan Feb 04 '16 at 12:14
  • 2
    You bet I am. Thanks for the help and sorry for not coming back. Unity answers solved it first so I never looked back here. Still, thanks! – messedupsongguy Feb 05 '16 at 15:22
0

I found even easier way to achieve that,

 if (gameObject.TryGetComponent(out Rigidbody rb))
 {
     rb.useGravity = true;
 }

Read this article for more info: here

Fahim kamal Ahmed
  • 195
  • 1
  • 2
  • 6