如何确定鼠标位置的对象 class (Unity3d)
How do I determine class of object at mouse position (Unity3d)
我的 2D 项目中有一个 class("foo" 说),当我在鼠标位置获得对游戏对象的引用时,我想确定该对象是否属于富class。我用
获得对象
GameObject objAtMouse = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(mousePos), Vector2.zero).transform.gameObject;
其中 mousePos 是我鼠标的位置,它似乎按预期工作。为了测试 class 我尝试了以下方法:
- 如果(objAtMouse 是 foo){...}
- foo fooAtMouse = objAtMouse as foo;
如果(fooAtMouse){...}
- if ((objAtMouse.GetComponent("foo") as foo) != null){...}
选项 1. 被建议 here,并且是唯一一个不会产生错误但会产生警告的选项
The given expression is never of the provided ('foo') type
选项 2.,也在上面 link 中建议,产生错误
Cannot convert type 'UnityEngineGameObject' to 'foo' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion
建议选项 3 here 并产生错误
NullReferenceException: Object reference not set to an instance of an object
这似乎是一项简单的任务,但我在这方面遇到了一些麻烦。那么,如何确定我的鼠标悬停的对象的 class/type 呢?
非常感谢任何帮助!
如果 Foo
是一个组件,它可能是因为您将它附加到 GameObject
,那么选项 3 非常接近。但你不需要施放它 as Foo
.
Foo fooComponent = objAtMouse.GetComponent<Foo>();
if (fooComponent == null) .. //no Foo component.
请注意,您应该先检查 objAtMouse
是否为 null
..
场景中的所有对象都是游戏对象本身,不会被调用class。您要查找的其他 class 是组件
所以你必须使用obj.GetComponents
从游戏对象中取出它
您也可以为其分配一个标签,然后使用
objAtmouse.compareTag('your tag name');
首先,第一行无法按原样计算:
GameObject objAtMouse = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(mousePos), Vector2.zero).transform.gameObject;
这假设你有一个持续的成功命中。
Raycast2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(mousePos), Vector2.zero);
if(hit.transform != null)
{
GameObject objAtMouse = hit.transform.gameObject;
if(objAtMouse.GetComponent<Foo>() != null){
// Object has component Foo on it
}
}
另一个解决方案是让 Foo 类型讲述自己:
public class Foo:MonoBehaviour{
private static HashSet<Transform>fooCollection;
private void Awake()
{
if(fooCollection == null)
{
fooCollection = new HashSet<Transform>();
}
fooCollection.Add(this.transform);
}
private void OnDestroy()
{
fooCollection.Remove(this.transform);
}
public static bool CompareFooObject(Transform tr)
{
if(tr == null) return false;
return fooCollection.Contains(tr);
}
}
那么您可以将其用作:
Raycast2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(mousePos), Vector2.zero);
if(Foo.CompareFooObject(hit.transform))
{
// Is Foo type
}
HashSet的优点是查找项的速度相当快。您还可以扩展该模式的用法,以便它可以与具有泛型的任何类型一起使用,但我想现在这已经足够了。
我的 2D 项目中有一个 class("foo" 说),当我在鼠标位置获得对游戏对象的引用时,我想确定该对象是否属于富class。我用
获得对象GameObject objAtMouse = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(mousePos), Vector2.zero).transform.gameObject;
其中 mousePos 是我鼠标的位置,它似乎按预期工作。为了测试 class 我尝试了以下方法:
- 如果(objAtMouse 是 foo){...}
- foo fooAtMouse = objAtMouse as foo; 如果(fooAtMouse){...}
- if ((objAtMouse.GetComponent("foo") as foo) != null){...}
选项 1. 被建议 here,并且是唯一一个不会产生错误但会产生警告的选项
The given expression is never of the provided ('foo') type
选项 2.,也在上面 link 中建议,产生错误
Cannot convert type 'UnityEngineGameObject' to 'foo' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion
建议选项 3 here 并产生错误
NullReferenceException: Object reference not set to an instance of an object
这似乎是一项简单的任务,但我在这方面遇到了一些麻烦。那么,如何确定我的鼠标悬停的对象的 class/type 呢?
非常感谢任何帮助!
如果 Foo
是一个组件,它可能是因为您将它附加到 GameObject
,那么选项 3 非常接近。但你不需要施放它 as Foo
.
Foo fooComponent = objAtMouse.GetComponent<Foo>();
if (fooComponent == null) .. //no Foo component.
请注意,您应该先检查 objAtMouse
是否为 null
..
场景中的所有对象都是游戏对象本身,不会被调用class。您要查找的其他 class 是组件
所以你必须使用obj.GetComponents
从游戏对象中取出它
您也可以为其分配一个标签,然后使用
objAtmouse.compareTag('your tag name');
首先,第一行无法按原样计算:
GameObject objAtMouse = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(mousePos), Vector2.zero).transform.gameObject;
这假设你有一个持续的成功命中。
Raycast2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(mousePos), Vector2.zero);
if(hit.transform != null)
{
GameObject objAtMouse = hit.transform.gameObject;
if(objAtMouse.GetComponent<Foo>() != null){
// Object has component Foo on it
}
}
另一个解决方案是让 Foo 类型讲述自己:
public class Foo:MonoBehaviour{
private static HashSet<Transform>fooCollection;
private void Awake()
{
if(fooCollection == null)
{
fooCollection = new HashSet<Transform>();
}
fooCollection.Add(this.transform);
}
private void OnDestroy()
{
fooCollection.Remove(this.transform);
}
public static bool CompareFooObject(Transform tr)
{
if(tr == null) return false;
return fooCollection.Contains(tr);
}
}
那么您可以将其用作:
Raycast2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(mousePos), Vector2.zero);
if(Foo.CompareFooObject(hit.transform))
{
// Is Foo type
}
HashSet的优点是查找项的速度相当快。您还可以扩展该模式的用法,以便它可以与具有泛型的任何类型一起使用,但我想现在这已经足够了。