Unity3d,得到具体的组件类型
的唯一实体我知道,如果我有像Unity3d,得到具体的组件类型
Component tmp = (myClass)gameObject.GetComponent<myClass>();
可以返回空值,或者输入“MyClass的”的实例,如果它存在于我的具体游戏对象。现在,让我们假设我有一个来自给定半径的物理球体捕获的对象数组。我有20个游戏对象返回。
如何创建一个例程以仅返回具有组件的游戏对象,因此我不必一遍又一遍地编写自己的迭代器。再次是泛型,因为在一个领域我可能需要另一个地方。我不想为了使可读性变得很痛苦而全力投入类型转换。
反馈(每西普里安的答案)
我想你的方法逐字,并没有得到任何人的“类”,我想,即使它是一个附加组件。所以,我试着稍微修改一下例程。首先,确保一个合适的“游戏对象”。然后从那里,尝试拨打GameObject's .GetComponent<T>()
。但是这会导致错误,即使<T>
与我通过获取组件的类型相同。
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)
现在我想我理解你的问题,所以这就是为什么我作为一个单独的答案发布。
您有一个复合对象,并且您想调用基于游戏对象中存在的自定义类“属性”混合的自定义操作。
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;
}
我更新了更改并从您的答案中删除了不需要的转换。从这些问题的一个重要的变化是:
使用游戏对象[]数组不能用手使你蒙上
使用其中T:组件,而不是T:类
我了解,你需要两个代码的情况下,可以实现对对象的数组:
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(),或使用它们作为一个列表中使用.ToList()
后来 如果您熟悉使用LINQ,你可以只使用第一种方法,后来使用Linq组合功能,使的最后一行代码就可以改写为:
items.GetItemsAsT<Circle>().Where(c => c.Radius < 30);
另外,如果你的名字GetItemsAsT是冗长的,选择只是他们的一个较短的名称:AST。
外貌很有前途,但如果我有一个包含3个与其关联的类别脚本的游戏对象,那么您如何/在哪里确认整个游戏对象包含我特别寻找的组件之一。如果连接了3个,我无法确认哪个“myGameObject是someClass”,我必须转到特定的GetComponent
感谢修改后的问题,稍后将在家中尝试,但认为这是因为我错过了“where T:class”子句 – DRapp 2014-09-24 13:19:48
我试过并更新了我的帖子和修改后的实现。你能看看它,看看它对你有意义吗? – DRapp 2014-09-24 21:09:09
经过反馈后更新了回复 – 2014-09-25 07:01:57