提问人:eClick_studio 提问时间:10/24/2022 最后编辑:eClick_studio 更新时间:10/24/2022 访问量:552
getComponent 的方法实现接口。Unity C#
Method to getComponent implements interface. Unity C#
问:
我需要可以找到组件实现接口 T 的方法。 我有这个方法,但我无法正常工作。它应该像 TryGetComponent(out Interface interface) 一样工作。你能帮忙吗?
public T RaycastFindComponent<T>(T targetType) where T : Type
{
RaycastHit2D[] raycastHits = Physics2D.RaycastAll(_mainCamera.ScreenToWorldPoint(Input.mousePosition), new Vector2());
foreach (RaycastHit2D raycastHit in raycastHits)
{
foreach (MonoBehaviour component in raycastHit.transform.GetComponents(typeof(MonoBehaviour)))
{
Type componentType = component.GetType();
Debug.Log($"GetComponent = {componentType is T}"); //true
if (componentType is T)
{
return component as T; //null but (componentType is T = true)
}
}
}
return null;
}
如果我使用具体的接口,它会起作用:
public Interface RaycastFindComponent()
{
RaycastHit2D[] raycastHits = Physics2D.RaycastAll(_mainCamera.ScreenToWorldPoint(Input.mousePosition), new Vector2());
foreach (RaycastHit2D raycastHit in raycastHits)
{
foreach (MonoBehaviour component in raycastHit.transform.GetComponents(typeof(Interface)))
{
Type componentType = component.GetType();
Debug.Log($"GetComponent = {componentType is Interface}"); //true
if (componentType is T)
{
return component as Interface; //(Interface)component
}
}
}
return null;
}
答:
0赞
user585968
10/24/2022
#1
代码的问题在于您正在尝试返回一个类型的类,但是约束定义为:T
T
Type
public T RaycastFindComponent<T>(T targetType) where T : Type
...相当于:
public Type RaycastFindComponent(Type targetType)
...这不是你想要的。
它应该显示(请注意,我们不再需要该参数):
public T RaycastFindComponent<T>() where T : Component, IMyInterface // NEW
{
var targetType = typeof(T); // <--- NEW
RaycastHit2D[] raycastHits = Physics2D.RaycastAll(_mainCamera.ScreenToWorldPoint(Input.mousePosition), new Vector2());
foreach (RaycastHit2D raycastHit in raycastHits)
{
foreach (MonoBehaviour component in raycastHit.transform.GetComponents(targetType))
{
if (component is T)
{
return component as T;
}
}
}
return null;
}
你基本上是想说哪个是苹果和橙子,结果失败了。Type
IMyInterface
评论
0赞
eClick_studio
10/24/2022
我理解。但是我想传递要找到的接口类型。在您的示例中,接口已写入方法签名中。
0赞
10/24/2022
T
将是您要查找的具体类或接口。例如。该约束仅限制可以使用哪些类型。即它必须是一个组件
,实现接口 IMyInterface
或派生。如果您总是要查找接口,则可以将 放入约束中。IMyInterface
where
Component
where
0赞
eClick_studio
10/24/2022
public interface 接口 {} 调用应如下所示: _raycastHandler.RaycastFindComponent<Interface>();
0赞
10/24/2022
这是完全正确的。
0赞
eClick_studio
10/24/2022
但 IDE 会抛出异常:类型“Interface”不能用作泛型类型或方法“RaycastHandler.RaycastFindComponent”中的类型参数“T<T>()”。没有从“Interface”到“UnityEngine.Component”的隐式引用转换。
0赞
derHugo
10/24/2022
#2
它应该像 TryGetComponent(out Interface interface) 一样工作
因此,首先要将类型传入泛型,而不是将其实例作为参数!
其次,为了真正让它像TryGetComponent
- 您想要使用参数并返回
out
bool
- 为什么不实际使用支持接口的接口
TryGetComponent
所以像这样的东西,例如
public bool RaycastFindComponent<T>(out T result) where T : class
{
var raycastHits = Physics2D.RaycastAll(_mainCamera.ScreenToWorldPoint(Input.mousePosition), new Vector2());
foreach (RaycastHit2D raycastHit in raycastHits)
{
if (raycastHit.transform.TryGetComponent<T>(out result))
{
return true;
}
}
result = default;
return false;
}
该约束还包括接口,因为它们也是引用类型,因此可以(就像 Unity 的 / 一样)将任何类或接口作为泛型类型参数。class
GetComponent
TryGetComponent
if(RaycastFindComponent<ISomeInterface>(out var instance))
{
Debug.Log("You hit {instance}", instance);
}
当然,如果需要,你可以进一步限制它,但我会从最通用和可重用的方式开始,然后你仍然可以制作更受约束的版本
评论