Unity3D:GetComponent(string)和GetComponent(Type)之间的结果差异?

时间:2019-01-17 08:59:48

标签: c# unity3d

我有在Start()

中调用了以下代码的脚本
GameObject newTerrain = Instantiate(terrainPrefab);
if (newTerrain.GetComponent<Terrain>()) // Returns true
    Debug.Log("I am type");
if (newTerrain.GetComponent("Terrain")) // Returns false
    Debug.Log("I am string");

虽然Debug.Log向我显示I am type的输出,但没有向我显示第二个。稍后,我需要在代码中使用GetComponent(string),但是它不起作用。

是什么导致这种差异,对此是否有解决方案/解决方法?

编辑:

因此,在阅读了一些评论和建议之后,我尝试了newTerrain.GetComponent("Terrain") != nullnewTerrain.GetComponent("Terrain") as Terrain语句中的if,但两者均仍返回false。

我尝试使用GetComponent(string)的唯一原因是因为我正在尝试学习对象池,并且the tutorial提供了以下代码:

public GameObject GetPooledObject(string type)
{
    for (int i = 0; i < pooledObjects.Count; i++)
    {
        Debug.Log(pooledObjects[i].GetComponent(type));
        if (!pooledObjects[i].activeInHierarchy && pooledObjects[i].GetComponent(type))
        {
            return pooledObjects[i];
        }
    }

    foreach (ObjectPoolItem item in itemsToPool)
    {
        if (item.objectToPool.GetComponent(type))
        {
            if (item.shouldExpand)
            {
                // Create 5 for shits and giggles
                for (int i = 0; i < 5; i++)
                {
                    GameObject obj = Instantiate(item.objectToPool);
                    obj.SetActive(false);
                    pooledObjects.Add(obj);
                }

                return pooledObjects[pooledObjects.Count - 1];
            }
        }
    }

    return null;
}

我整理了一些东西,但大部分都保持不变。即使在我可以在检查器中从字面上看到附加了Debug.Log组件的情况下, this 函数中的null也会返回一个Terrain

2 个答案:

答案 0 :(得分:2)

标题“有什么区别”的实际答案是:

newTerrain.GetComponent("Terrain")

返回一个Component引用
newTerrain.GetComponent<Terrain>()

返回一个Terrain引用。

因此,要实际使用引用,您必须像

那样键入第一个引用
(Terrain) newTerrain.GetComponent("Terrain")

但是,两者都具有运算符bool(因为Terrain继承自Behaviour,而Component继承自Object),因此仅用于检查是否存在,两者的行为应完全相同...除了string版本较慢。

因此,占用string的重载行为不符合预期是很奇怪的。


您也可以使用带有Type作为参数的重载,例如

public GameObject GetPooledObject(Type type)
{
    ... GetComponent(type)
}

并使用

GameObject newTerrain = ObjectPool.Instance.GetPooledObject(typeof(Terrain));

或再次使整个对象池化方法通用

public GameObject GetPooledObject<T>() where T : Component 
{
    ... GetCompoment<T>()
}

并使用

GameObject newTerrain = ObjectPool.Instance.GetPooledObject<Terrain>();

答案 1 :(得分:-1)

我在文档中看不到GameObject.GetComponent(字符串组件)。猜猜它已被弃用。 我建议您改用反射。