使用2D Raycast检测鼠标悬停在对象碰撞器上的问题

时间:2016-06-18 17:49:40

标签: c# unity3d 2d

我目前正在使用Unity中的2D角色选择屏幕,该屏幕应该与真人快打角色选择屏幕类似地操作。目前,我在主摄像头上安装了一个名为CharacterSelector的班级。该类包含选择/取消选择字符,悬停事件和选择确认的方法。我能够使用RayCast2D来构建我的角色选择方法;但是,我遇到了将其用于悬停事件的问题。

在我的场景中,我有一组角色图像供玩家选择(如果他们已解锁)。当玩家用他/她的鼠标悬停在角色上时,角色图像应该被黄色边框包围。当用户单击所需字符时,将在字符图像组的左侧弹出较大版本的图像。

现在,我有以下悬停方法的代码:

    public void onHover(Ray ray, RaycastHit2D hit)
    {
        if(hit.collider == null)
        {
            Debug.Log("nothing hit");

        }            
        if (Physics2D.Raycast(ray.origin, ray.direction, Mathf.Infinity))
        {
            print(hit.collider.name);
        }
    }

此方法属于CharacterSelection类继承的类。以下是CharacterSelection类:

class CharacterSelector : Selector
{
    Ray ray;
    RaycastHit2D hit;        

    public void Start()
    {
        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    }

    void Update()
    {
        onHover(ray, hit); 

        if (Input.GetMouseButtonDown(0))
        {                               
            selectCharacter();
        }
    }                   
}

此外,我试图悬停的所有角色图像目前都有2D Box Colliders。截至目前,我无法让悬停操作工作。它不会将字符图像的名称打印到控制台。我正在使用它作为第一步,看看Unity是否识别出角色图像。如果我能提供更多信息,请告诉我们!

1 个答案:

答案 0 :(得分:1)

鼠标几乎每一帧都会在屏幕上更改位置。这意味着您的光线应根据鼠标位置每帧更新。所以我将相应的语句从Start()移到了Update();

class CharacterSelector : Selector
{
    Ray ray;    
    RaycastHit2D hit;   

    public void Start()
    {

    }

    void Update()
    {
        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        onHover(ray, hit); 

        if (Input.GetMouseButtonDown(0))
        {                               
            selectCharacter();
        }
    }                   
}

其次,如果你查看the definition of Physics2D.Raycast,你会发现它会让你回到RaycastHit2D对象。这是你应该检查对象的对象,而不是你应该抛出NullReferenceException的命中对象,我不知道它为什么没有。所以这个:

public void onHover(Ray ray, RaycastHit2D hit)
{
    hit = Physics2D.Raycast(ray.origin, ray.direction, Mathf.Infinity);
    if(hit.collider == null)
    {
        Debug.Log("nothing hit");

    }            
    else
    {
        print(hit.collider.name);
    }
}

除此之外,你真的不需要onHover()函数中的hit参数,它可以是函数中的局部变量。但是,如果您计划在CharacterSelector脚本中使用命中变量,则应将onHover的声明更改为:onHover(Ray ray, out RaycastHit2D hit) out关键字通过引用而不是其值的副本传递变量。

另外,我认为检查鼠标是否悬停在一个对象上不应该在onHover上进行,这有点误导,对我来说似乎不合逻辑。我将onHover的主体移动到另一个函数,如RaycastChecker()。只有当鼠标实际上悬停在精灵上时我才会调用onHover()。 (就像在OnCollisionEnter中一样,你认为碰撞确实发生了,所以onHover也应该如此)