简体   繁体   English

使用2D Raycast来检测对象对撞机上的鼠标悬停时的问题

[英]Issues using a 2D Raycast to detect mouse hover on object colliders

Im currently working on a 2D character selection screen in Unity that should operate similarly to the Mortal Kombat character selection screen. 我目前在Unity中的2D角色选择屏幕上工作,该屏幕应与真人快打角色选择屏幕类似。 Currently, I have a class called CharacterSelector attached to the main camera. 目前,我有一个名为CharacterSelector的类附加到主摄像机。 The class holds methods for selection/deselection of characters, hover events, and selection confirmation. 该类包含用于选择/取消选择字符,悬停事件和选择确认的方法。 I was able to use a RayCast2D to build my character selection method; 我能够使用RayCast2D构建我的角色选择方法。 however, I am running into issues using it for hover events. 但是,在将其用于悬停事件时遇到了问题。

In my scene, I have a group of character images that the player can choose from (if they are unlocked). 在我的场景中,我有一组角色图像可供玩家选择(如果它们已解锁)。 When the player hovers over the character with his/her mouse, the character image should be surrounded by a yellow border. 当玩家用鼠标悬停在角色上时,角色图像应被黄色边框包围。 When the user clicks on the desired character, a larger version of the image will popup to the left of the character image group. 当用户单击所需的字符时,较大版本的图像将弹出到字符图像组的左侧。

Right now, I have the following code for the hover method: 现在,我有以下代码用于悬停方法:

    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);
        }
    }

This method belongs to a class that the CharacterSelection class inherits from. 此方法属于CharacterSelection类继承的类。 The following is on the CharacterSelection class: 以下是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();
        }
    }                   
}

Also, all the character images that I am trying to hover over currently have 2D Box Colliders. 另外,我现在要悬停的所有角色图像都具有2D Box Colliders。 As of right now, I am unable to get hover operation to work. 截至目前,我无法进行悬停操作。 It does not print the name of the character image to the console. 它不会将字符图像的名称打印到控制台。 I am using this as a first step to see if Unity recognizes the character image or not. 我将其用作第一步,以了解Unity是否能够识别字符图像。 Let me know if I can provide additional information! 让我知道是否可以提供其他信息!

Mouse changes position on screen almost every frame. 鼠标几乎每帧都会改变屏幕上的位置。 This means your ray should be updated every frame according to mouse position. 这意味着您的光线应根据鼠标位置的每一帧进行更新。 So I moved the corresponding statement from Start() to Update(); 所以我将相应的语句从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();
        }
    }                   
}

Secondly, if you look in the definition of Physics2D.Raycast you'll find that it gives you back the RaycastHit2D object. 其次,如果查看Physics2D.Raycast的定义,您会发现它使您返回了RaycastHit2D对象。 This is the object you should check the collider of, not your hit object which should have thrown an NullReferenceException, I don't know why it didn't. 这是您应该检查对撞机的对象,而不是应该抛出NullReferenceException的命中对象,我不知道为什么没有这样做。 So this: 所以这:

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);
    }
}

Apart from this you don't really need the hit argument in onHover() function, it can be a local variable in the function. 除此之外,您实际上不需要onHover()函数中的hit参数,它可以是函数中的局部变量。 But if you are planning on using your hit variable in CharacterSelector script than you should change the declaration of onHover to: onHover(Ray ray, out RaycastHit2D hit) the out keyword passes the variable by reference instead of a copy of its value. 但是,如果您打算在CharacterSelector脚本中使用hit变量,则应将onHover的声明更改为: onHover(Ray ray, out RaycastHit2D hit) out关键字通过引用而不是其值的副本传递变量。

Also, I think checking if mouse is hovering over an object shouldn't be done in onHover, it's kinda misleading and doesn't seem logical to me. 另外,我认为不应该在onHover中检查鼠标是否悬停在对象上,这有点误导并且对我来说似乎不合逻辑。 I'd move the body of onHover to another function like RaycastChecker(). 我将onHover的主体移至另一个函数,如RaycastChecker()。 I'd call onHover() only if mouse is actually hovering over the sprite. 仅当鼠标实际上悬停在精灵上时,我才调用onHover()。 (like in OnCollisionEnter you take it granted that the collision did happen, so should the onHover, I think) (就像在OnCollisionEnter中一样,您认为碰撞确实发生了,所以我认为onHover也应该如此)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM