C# 检测光标的更好方法?

C# 检测光标的更好方法?,c#,unity3d,C#,Unity3d,目标:检测光标何时进入玩家定义的半径 您好,我正在尝试从一个名为CrossCode的游戏中复制作战系统。这个想法是,当光标在玩家的某个半径范围内时,我将能够切换到近战,并在光标离开该半径后返回远程 我已经实现了一种我认为可以实现的方法,但是它感觉很慢或不可靠,我只是想知道是否还有其他方法可以实现更平滑的结果 这就是我所做的 附属于玩家的 void Update() { attackStyleSwitchRadius = colRef.radius; playerCenter =

目标:检测光标何时进入玩家定义的半径

您好,我正在尝试从一个名为CrossCode的游戏中复制作战系统。这个想法是,当光标在玩家的某个半径范围内时,我将能够切换到近战,并在光标离开该半径后返回远程

我已经实现了一种我认为可以实现的方法,但是它感觉很慢或不可靠,我只是想知道是否还有其他方法可以实现更平滑的结果

这就是我所做的

附属于玩家的

void Update()
{
    attackStyleSwitchRadius = colRef.radius;
    playerCenter = colRef.transform.position;

    if(Physics2D.OverlapCircle(playerCenter, attackStyleSwitchRadius, cursor))
    {
        meleeMode = true;
        rangeMode = false;
    }
    else
    {
        meleeMode = false;
        rangeMode = true;
    }

}
在一个小的2D对象上,我有这个脚本,它跟随光标的位置

void Update()
{
    pos = Input.mousePosition;
    gameObject.transform.position = Camera.main.ScreenToWorldPoint(pos);
}

当小对象进入重叠圆时,它会改变周围的边界。

您可以通过执行类似操作来消除碰撞检测开销

void Update ()
{
    attackStyleSwitchRadius = colRef.radius;
    playerCenter = colRef.transform.position;

    var mouse = Input.mousePosition;
    mouse.z = Vector3.Distance(Camera.main.transform.position, playerCenter);

    var range = Vector2.Distance(Camera.main.ScreenToWorldPoint(mouse), playerCenter);    
    var inside = range < attackStyleSwitchRadius;

    meleeMode = inside;
    rangeMode = !inside;
}
void更新()
{
attackStyleSwitchRadius=colRef.radius;
playerCenter=colRef.transform.position;
var mouse=Input.mousePosition;
mouse.z=Vector3.Distance(Camera.main.transform.position,playerCenter);
var range=Vector2.距离(Camera.main.ScreenToWorldPoint(鼠标)、playerCenter);
var inside=范围<攻击样式开关半径;
meleeMode=内部;
rangeMode=!内部;
}

您可以通过这样做来消除碰撞检测开销

void Update ()
{
    attackStyleSwitchRadius = colRef.radius;
    playerCenter = colRef.transform.position;

    var mouse = Input.mousePosition;
    mouse.z = Vector3.Distance(Camera.main.transform.position, playerCenter);

    var range = Vector2.Distance(Camera.main.ScreenToWorldPoint(mouse), playerCenter);    
    var inside = range < attackStyleSwitchRadius;

    meleeMode = inside;
    rangeMode = !inside;
}
void更新()
{
attackStyleSwitchRadius=colRef.radius;
playerCenter=colRef.transform.position;
var mouse=Input.mousePosition;
mouse.z=Vector3.Distance(Camera.main.transform.position,playerCenter);
var range=Vector2.距离(Camera.main.ScreenToWorldPoint(鼠标)、playerCenter);
var inside=范围<攻击样式开关半径;
meleeMode=内部;
rangeMode=!内部;
}

光标

  • 创建一个对象,将其命名为游标
  • 将小型碰撞器添加到光标对象
  • 向光标对象添加脚本,使其始终位于鼠标位置
  • 近战范围区域

  • 添加一个游戏对象作为玩家的子对象,将其命名为MeleRangeZone
  • 向其添加碰撞器,将其设置为触发器。这个对撞机的大小将是玩家的近战范围
  • 向其添加刚体以便可以检测碰撞,但请将刚体设置为不旋转或不更改其位置
  • 向对象添加脚本,并使用OnTiggerEnter和OnTiggerExit方法检测光标是否已进入近战区域
  • 您现在可以使用OnTiggerEnter和OnTiggerExit方法在玩家攻击模式之间切换,这意味着当光标进入时,它将变为近战模式,当光标退出时,它将变为远程模式

    可以激发光线以检测光标应有的位置,如下所示:

    public LayerMask RaycastCollidableLayers;
    public RaycastHit Hit;
    public float CheckDistance = 200f;
    public Transform Cursor;
    
    void PerformRaycast(){
    //Set up ray
    ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    //Fire ray
    Physics.Raycast(ray, out Hit, CheckDistance + 0.1f, RaycastCollidableLayers);
    if (Hit.collider == null)
    {
        //Debug.Log("Raycast hit nothing");
        return;
    }
    else //Ray hit something
        {
        //Move cursor to Hit.point;
        Cursor.position = Hit.point;
        }
    }
    

    光标

  • 创建一个对象,将其命名为游标
  • 将小型碰撞器添加到光标对象
  • 向光标对象添加脚本,使其始终位于鼠标位置
  • 近战范围区域

  • 添加一个游戏对象作为玩家的子对象,将其命名为MeleRangeZone
  • 向其添加碰撞器,将其设置为触发器。这个对撞机的大小将是玩家的近战范围
  • 向其添加刚体以便可以检测碰撞,但请将刚体设置为不旋转或不更改其位置
  • 向对象添加脚本,并使用OnTiggerEnter和OnTiggerExit方法检测光标是否已进入近战区域
  • 您现在可以使用OnTiggerEnter和OnTiggerExit方法在玩家攻击模式之间切换,这意味着当光标进入时,它将变为近战模式,当光标退出时,它将变为远程模式

    可以激发光线以检测光标应有的位置,如下所示:

    public LayerMask RaycastCollidableLayers;
    public RaycastHit Hit;
    public float CheckDistance = 200f;
    public Transform Cursor;
    
    void PerformRaycast(){
    //Set up ray
    ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    //Fire ray
    Physics.Raycast(ray, out Hit, CheckDistance + 0.1f, RaycastCollidableLayers);
    if (Hit.collider == null)
    {
        //Debug.Log("Raycast hit nothing");
        return;
    }
    else //Ray hit something
        {
        //Move cursor to Hit.point;
        Cursor.position = Hit.point;
        }
    }
    

    你不能用球形准直器和光线投射器吗?另外,您可能需要使用
    PreUpdate
    来移动“CursorObject”,否则对象可能会被移动到bevore或其他更新之后。我明白了,我从未想过这一点。我现在就要试一试,我不确定什么是
    PreUpdate
    ,我会尝试
    FixedUpdate
    ,因为我认为在这种情况下,它会比常规更新更好。我认为FixedUpdate不会有帮助
    PreUpdate
    Uptate
    应该可以解决您的“不可靠性”。您不能使用球形准直器和光线投射吗?另外,您可能需要使用
    PreUpdate
    来移动“CursorObject”,否则对象可能会被移动到bevore或其他更新之后。我明白了,我从未想过这一点。我现在就要试一试,我不确定什么是
    PreUpdate
    ,我会尝试
    FixedUpdate
    ,因为我认为在这种情况下,它会比常规更新更好。我认为FixedUpdate不会有帮助
    PreUpdate
    Uptate
    应该可以解决你的“不可靠性”。这可能是最好的方法,也可能不是,但我喜欢它的独创性!谢谢:-)。我相信这个方法会奏效。它还具有自动显示可见半径的附加好处。什么会阻止接受的答案在所有分辨率上工作?它不会失败,只是不一致,因为它们基于像素距离进行范围检查(如果我理解正确的话),这对于不同的屏幕分辨率是不同的。i、 例如,1080p屏幕上的100px可能是1个单位,而2160p屏幕上的100px可能是.25个单位。我相信你也可以调整窗口的大小,以实现类似的效果,而不是使用不同的屏幕分辨率。啊,是的,我相信你是对的,它可能不一致,因为它不是在世界空间内。可能是或可能不是最好的方法,但我喜欢它的独创性!谢谢:-)。我相信这个方法会奏效。它还具有自动显示可见半径的附加好处。什么会阻止接受的答案在所有分辨率上工作?它不会失败,