【问题标题】:How to check if a game object has a component method in Unity?如何在 Unity 中检查游戏对象是否具有组件方法?
【发布时间】:2016-05-12 00:58:51
【问题描述】:

我正在编写一个方法来检查一个游戏对象是否有一个组件。

这里是:

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

我是这样使用它的:

void Update()
{

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

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

游戏对象没有刚体,但它仍然在打印它的刚体。

【问题讨论】:

  • 尝试 debug.logging 对象名称,以确保您没有不小心将此脚本放在另一个对象上,也许?
  • 我做了,仍然打印出它有一个刚体,即使它没有。
  • 嗨@HamzaHasan ...答案是OP在泛型中犯了语法错误。您必须在末尾有一个 where 子句,否则调用 GetComponent() 的返回值将是无意义的......它正在返回我相信 它是否有 任何组件都附加。这只是一个语法错误,Hamza。
  • @JoeBlow 好的,所以它返回一个非空值。也是因为这个吗?
  • 嗨哈姆扎,如果我不清楚,对不起。我相信因为“T”基本上是“空白”......你在问它“GetComponent ()”。请注意,尖括号中有 NOTHING。这意味着您要问它它是否有任何组件——任何类型的任何组件。我可以解释一下吗?当然,它必须附加组件(某种类型!)所以它返回“true”。有意义吗?

标签: c# unity3d generics types


【解决方案1】:

只是……

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

请注意,您忘记了

其中 T:组件

第一行的一部分!

由于语法错误,扩展是没有意义的:它总是在寻找“某些组件”,因为 T 是“空白”。


注意。

“什么是扩展”的解释。

对于阅读本文但不熟悉 c# 中的类别的任何人......也就是说 c# 中的“扩展”......这是一个简单的tutorial......

扩展在 Unity 中至关重要。

您几乎在每一行代码中都使用它们。

基本上,在 Unity 中,您几乎可以在 Extension 中执行所有操作。

请注意,由于扩展非常普遍,OP 甚至没有费心显示包装类。扩展始终位于这样的文件中:

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 );
        }
  
    }

在示例中,我包含了三个典型的扩展。通常一个项目中会有几十个甚至上百个扩展。

(您可能更喜欢将它们分组到不同的HandyExtensions 文件中,或者只拥有一个巨大的HandyExtensions 文件。)

每个工程师和团队都有自己的“通用扩展”,他们一直在使用。

这是一个典型的example question,关于 C# 中的一些细微扩展。

请注意,在旧语言中,您通常将扩展称为“类别”。

在c#中它是一个“扩展”,但“类别”或“扩展”都是常见的。

正如我所说,您在 Unity 中经常使用这些。


如果你喜欢那种东西,这里有一个漂亮的:

// 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];
    }

【讨论】:

  • Defaulters :P.. 类似的用户也存在于 gamedev 中,例如 this one :D
  • 你打赌我是。感谢您的帮助,很抱歉没有回来。 Unity 的答案首先解决了它,所以我再也没有回头看这里。不过,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-17
  • 1970-01-01
  • 1970-01-01
  • 2018-04-17
相关资源
最近更新 更多