我知道如果我有像
这样的东西Component tmp = (myClass)gameObject.GetComponent<myClass>();
可以返回null值,也可以返回类型为&#34; myClass&#34;的实例。如果它存在于我的特定游戏对象上。现在,让我们假设我有一个来自给定半径的物理球体捕获的对象数组。我有20个游戏对象返回。
如何创建一个例程来仅返回那些具有组件的游戏对象,这样我就不必一遍又一遍地编写自己的迭代器。再次成为泛型,因为在一个领域我可能想要另一个和另一个地方。我不想全身心地进行类型转换,以使可读性变得痛苦。
反馈(按照Ciprian的回答)
我逐字尝试了你的方法,并没有得到任何&#34; Class&#34;我想要它即使它是一个附加组件。所以,我试着略微修改例程。首先,确保一个合适的游戏对象&#34;。然后,尝试拨打GameObject's .GetComponent<T>()
。但这导致错误,即使<T>
与我通过get Component寻找的类型相同。
public static IEnumerable<T> GetItemsAsT<T>(this object[] objects)
where T:class
{
GameObject gObj;
foreach(var obj in objects)
{
if( obj is GameObject )
{
gObj = (GameObject)obj;
if( gObj.GetComponent<T>() != null )
{
Debug.Log ( "Found via IEnumerable" );
yield return gObj.GetComponent<T>();
}
}
}
yield break;
}
对Ciprian的回答略有修改。
Error CS0311: The type 'T' cannot be used as type parameter 'T' in the generic type or method 'UnityEngine.GameObject.GetComponent<T>()'. There is no implicit reference conversion from 'T' to 'UnityEngine.Component'. (CS0311) (Assembly-CSharp)
答案 0 :(得分:1)
我知道你需要两个可以实现对象数组的代码案例:
static class GenericUtils
{
public static IEnumerable<T> GetItemsAsT<T>(this object[] objects)
where T:class
{
foreach(var obj in objects)
{
var t = obj as T;
if(t != null)
yield return t;
}
yield break;
}
public static IEnumerable<T> GetItemsWhere<T>(this object[] objects, Predicate<T> predicate)
where T:class
{
foreach(var tObj in objects.GetItemsAsT<T>())
{
if(predicate(tObj))
{
yield return tObj;
}
}
yield break;
}
}
要使用它们,您可以让我们说出一个圆圈列表:
items.GetItemsAsT<Circle>();
或使用谓词来过滤它们:
items.GetItemsWhere<Circle>(c => c.Radius < 30);
所有项目都是IEnumerable,因此如果您需要将它们转换为数组,请使用.ToArray(),或将它们用作List使用.ToList()
<强>后来强> 如果你熟悉Linq,你可以只使用第一种方法,然后使用Linq组合函数,这样你可以重写最后一行代码:
items.GetItemsAsT<Circle>().Where(c => c.Radius < 30);
此外,如果您的名字GetItemsAsT很详细,请为它们选择一个较短的名称:AsT。
答案 1 :(得分:1)
现在我觉得我理解你的问题,所以这就是我作为一个单独答案发布的原因。
您有一个复合对象,并且您希望根据游戏对象中存在的自定义类“属性”的混合来调用自定义操作。
public static IEnumerable<T> GetItemsAsT<T>(this GameObject[] objects)
where T:UnityEngine.Component
{
foreach(var obj in objects)
{
var t = obj.GetComponent<T>();
if(t != null)
yield return t;
}
yield break;
}
我更新了更改并从您的答案中删除了不必要的演员表。问题的唯一重要变化是:
使用GameObject []数组不能手动制作你的演员阵容
使用T:Component而不是T:class