You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity象棋游戏Hover效果与Input.GetMouseButton冲突问题

问题诊断与修复

你的Hover效果失效核心原因是代码分支逻辑错误:Input.GetMouseButtonUp(0)的if块后面跟着的else分支,会在每帧未触发鼠标抬起操作时都执行,强制重置currentHover并还原格子图层,直接覆盖了Hover效果的设置。

具体问题点

看这段代码:

// Releasing the mouse Button
if (currentlyDragging != null && Input.GetMouseButtonUp(0))
{
    // ... 移动棋子逻辑
}
else
{ 
    if (currentHover != -Vector2Int.one)
    {
        // 重置currentHover并还原图层
        Squares[currentHover.x, currentHover.y].layer = (containsValidMove(ref availableMoves, currentHover)) ? LayerMask.NameToLayer("Highlight") : LayerMask.NameToLayer("Square");
        currentHover = -Vector2Int.one;
        // ... 其他逻辑
    }
}

这个else和Input.GetMouseButtonUp(0)的if绑定,意味着只要不是“拖拽中抬起鼠标”的帧,都会进入else块,把已经设置好的Hover状态清空,自然看不到格子变色效果。

修复方案

把“清空Hover状态”的逻辑移到Raycast检测失败的分支里——也就是只有当鼠标没有悬停在任何棋盘格子上时,才重置currentHover,而不是每帧都执行。

修正后的完整代码:

RaycastHit info;
Ray ray = currentCamera.ScreenPointToRay(Input.mousePosition);

if (Physics.Raycast(ray, out info, 150, LayerMask.GetMask("Square","Hover","Highlight")))
{
    //Get the indexes of the Square you hit
    Vector2Int hitPosition = LookUpSquareIndex(info.transform.gameObject);

    // From not hovering to hovering
    if (currentHover == -Vector2Int.one)
    {
        currentHover = hitPosition;
        Squares[hitPosition.x, hitPosition.y].layer = LayerMask.NameToLayer("Hover");
    }

    // From hovering one square to hovering another square
    if (currentHover != hitPosition)
    {
        Squares[currentHover.x, currentHover.y].layer = containsValidMove(ref availableMoves, currentHover) ? LayerMask.NameToLayer("Highlight") : LayerMask.NameToLayer("Square");
        currentHover = hitPosition;
        Squares[hitPosition.x, hitPosition.y].layer = LayerMask.NameToLayer("Hover");
    }
    //pressing the mouse button
    if (Input.GetMouseButtonDown(0))
    {
        if (chessPieces[hitPosition.x, hitPosition.y] != null)
        {
            //Is it Our Turn
            if ((chessPieces[hitPosition.x, hitPosition.y].team==0 && isWhiteTurn) || (chessPieces[hitPosition.x, hitPosition.y].team == 1 && !isWhiteTurn))
            {
                currentlyDragging = chessPieces[hitPosition.x, hitPosition.y];
                //getting a list of available Moves , heighlight the available moves
                availableMoves = currentlyDragging.GetAvailableMoves(ref chessPieces, SQUARE_COUNT_X, SQUARE_COUNT_Y);
                //Getting a Special Moves List 
                specialMove = currentlyDragging.GetSpecialMoves(ref chessPieces, ref moveList, ref availableMoves);
                highlightSquares();
            }
        }
    }
    // Releasing the mouse Button
    if (currentlyDragging != null && Input.GetMouseButtonUp(0))
    {
        Vector2Int previousPosition = new Vector2Int(currentlyDragging.currentX, currentlyDragging.currentY);
        bool validMove = MoveTo(currentlyDragging, hitPosition.x, hitPosition.y);
        if (!validMove)
            currentlyDragging.setPosition(GetSquaresCenter(previousPosition.x, previousPosition.y));
        currentlyDragging = null;
        removehighlightSquares();
    }

    // while dragging a piece
    if (currentlyDragging)
    {
        Plane horizontalePlane = new Plane(Vector3.up , Vector3.up*Yoffset/1000);
        float distance = 0.0f;
        if(horizontalePlane.Raycast(ray, out distance))
            currentlyDragging.setPosition(ray.GetPoint(distance)+Vector3.up*dragOffset);
    }
}
// 只有当鼠标没有命中棋盘格子时,才重置Hover状态
else 
{ 
    if (currentHover != -Vector2Int.one)
    {
        Squares[currentHover.x, currentHover.y].layer = (containsValidMove(ref availableMoves, currentHover)) ? LayerMask.NameToLayer("Highlight") : LayerMask.NameToLayer("Square");
        currentHover = -Vector2Int.one;

        if (currentlyDragging && Input.GetMouseButtonUp(0))
        {
            currentlyDragging.setPosition(GetSquaresCenter(currentlyDragging.currentX, currentlyDragging.currentY));
            currentlyDragging = null;
            removehighlightSquares(); 
        }
    }
}

额外优化建议

  • 把Hover、鼠标按键、拖拽逻辑拆分成独立函数(比如UpdateHoverState()、HandleMouseInput()),代码可读性更高,也更容易排查问题;
  • 可以缓存LayerMask.NameToLayer的结果,避免每帧重复计算,提升性能。

内容的提问来源于stack exchange,提问作者Dziri Mootez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:32:05