Unity跳棋游戏棋子单次移动动画后无法再次移动问题求助
嘿,我来帮你捋捋这个问题!从你描述的情况来看,棋子第一次触发动画完成移动后没法再移到下一格,大概率是动画结束后棋子的实际位置和逻辑坐标没同步,或是状态标记没更新导致的。咱们一步步拆解分析:
可能的核心原因 & 解决办法
1. 动画结束后Transform位置与逻辑坐标脱节
你现在的代码里,可能是播放动画后直接修改了逻辑坐标(比如x1/y1),但棋子的Transform位置是由动画驱动的——动画播放过程中Transform在慢慢移动,如果你没等动画结束就更新逻辑坐标,或者动画结束后没把Transform位置同步到目标Tile的位置,下次调用ValidMove时,棋子的实际位置和你记录的逻辑坐标对不上,直接导致移动判定失败。
解决思路:
在动画的最后一帧添加Animation Event(Unity动画系统里的功能,右键动画帧就能加),然后在回调函数里执行同步操作:
// 动画结束时的回调方法 public void OnMoveAnimationComplete(int targetX, int targetY, Transform targetTile) { // 把棋子的Transform位置直接设到目标Tile的位置 transform.position = targetTile.position; // 更新棋子自身记录的逻辑坐标(假设你的棋子脚本里有x、y字段) this.x = targetX; this.y = targetY; // 重置移动状态(如果有isMoving这类标记的话) isMoving = false; }
这样就能保证动画结束后,逻辑坐标和实际位置完全匹配,下次移动判定才会准确。
2. 移动状态标记未重置
如果你在触发移动时设置了类似isMoving = true的标记,防止移动过程中重复操作,但动画结束后没把这个标记改回false,后续点击时程序会认为棋子还在移动中,直接忽略新的移动请求。
解决思路:
- 播放动画前:
selectedPiece.isMoving = true; - 动画结束的回调里:
selectedPiece.isMoving = false; - 同时在选中棋子的逻辑里加判断:只有
!isMoving的棋子才能被选中。
3. ValidMove方法依赖了实时Transform位置
如果你的ValidMove方法里,是用selectedPiece.transform.position来计算x1/y1的,那动画播放过程中这个位置一直在变,会导致判定逻辑混乱。正确的做法应该是用棋子自身记录的逻辑坐标(比如脚本里的x、y字段)来做移动合法性判断。
比如你现有代码片段里的x1、y1,应该取棋子脚本里的selectedPiece.x、selectedPiece.y,而不是从Transform.position转换过来的数值。
4. Animator的Wrap Mode设置错误
如果你的动画Wrap Mode设成了Loop或者Default,动画播放完可能会跳回第一帧,导致棋子又回到原来的位置——这时候看起来移动成功了,但实际位置又回去了,自然没法再移动。
解决思路:
选中Animator组件里的移动动画,把Wrap Mode改成Clamp Forever,确保动画播放完停在最后一帧。
结合你给出的代码片段的修改建议
你现有代码里的单格移动逻辑,可以调整成这样的流程:
if(selectedPiece.ValidMove(pieces, selectedPiece.x, selectedPiece.y, x2, y2, hasKilled)) { // Tile jump check if (Mathf.Abs (x2 - x1) == 1) { if(selectedPiece.isWhite) { if(selectedPiece.transform.position.x < mouseOver.x) { // 播放对应的移动动画 selectedPiece.animator.Play("MoveRight"); // 记录目标位置,传给动画回调 selectedPiece.SetTargetPosition(x2, y2, targetTile.transform); // 标记为移动中 selectedPiece.isMoving = true; } // 其他方向的动画逻辑... } } }
内容的提问来源于stack exchange,提问作者Sherzodkh

