How to check if a game object has a component meth

2020-07-17 02:17发布

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.

1条回答
再贱就再见
2楼-- · 2020-07-17 02:58

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 extensinos a "category".

In c# it is an "extension", but people use the terms either "category" or "extension" all the time.

As I say, you use these constantly in Unity. Cheers


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];
    }
查看更多
登录 后发表回答