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
相关产品推荐
相关产品推荐

