Unity中立方体移动:能否修改脚本实现仅在玩家滑动时改变方向?
当然可行啦!教你实现立方体仅在滑动时切换滚动方向
先聊聊核心逻辑差异
你的原脚本是每帧盯着方向键的按住状态,所以按住就会一直响应滚动。现在要改成「只有玩家完成滑动动作(不管是触屏 swipe 还是按一次方向键模拟滑动)才切换方向」,核心就是把「持续输入检测」改成「单次触发式检测」,同时让立方体保持当前方向滚动,直到下一次滑动触发新指令。
实现方案
我给你分两种常见场景写了实现代码,你可以按需选用:
场景1:键盘操作(按一次方向键=一次滑动触发)
我们把GetKey换成GetKeyDown——这个方法只会在按键按下的第一帧触发,刚好模拟“滑动一次”的动作,同时加个状态锁防止滚动过程中乱改方向:
public float tumblingDuration = 0.2f; public float rollSpeed = 5f; // 控制滚动速度,可根据你的立方体大小调整 private Vector3 currentRollDir = Vector3.forward; // 默认初始滚动方向 private bool isRolling = false; private Vector3 targetPos; void Update() { // 检测单次方向键按下(模拟滑动触发) if (Input.GetKeyDown(KeyCode.UpArrow)) SetNewRollDirection(Vector3.forward); if (Input.GetKeyDown(KeyCode.DownArrow)) SetNewRollDirection(Vector3.back); if (Input.GetKeyDown(KeyCode.LeftArrow)) SetNewRollDirection(Vector3.left); if (Input.GetKeyDown(KeyCode.RightArrow)) SetNewRollDirection(Vector3.right); // 持续朝当前方向滚动 if (isRolling) { transform.position = Vector3.MoveTowards(transform.position, targetPos, rollSpeed * Time.deltaTime); // 到达目标位置后结束本次滚动(可选:如果要保持同一方向连续滚动,取消下面注释即可) if (Vector3.Distance(transform.position, targetPos) < 0.01f) { isRolling = false; // SetNewRollDirection(currentRollDir); } } } // 设置新的滚动方向并计算目标位置 void SetNewRollDirection(Vector3 newDir) { if (isRolling) return; // 滚动过程中不响应新输入,避免运动混乱 currentRollDir = newDir; // 计算滚动后的目标位置(假设立方体边长为1,可根据实际模型大小调整) targetPos = transform.position + currentRollDir; isRolling = true; // 可选:用协程实现平滑翻滚动画(替代简单的位置移动,更贴合真实滚动效果) // StartCoroutine(TumbleCube(newDir)); } // 可选:用协程实现带旋转的平滑翻滚 IEnumerator TumbleCube(Vector3 dir) { isRolling = true; Quaternion startRot = transform.rotation; Quaternion targetRot = startRot * Quaternion.FromToRotation(Vector3.up, dir); Vector3 startPos = transform.position; Vector3 targetPos = startPos + dir; float elapsed = 0f; while (elapsed < tumblingDuration) { elapsed += Time.deltaTime; float t = elapsed / tumblingDuration; t = Mathf.SmoothStep(0, 1, t); // 加入平滑过渡,让翻滚更自然 transform.rotation = Quaternion.Lerp(startRot, targetRot, t); transform.position = Vector3.Lerp(startPos, targetPos, t); yield return null; } transform.rotation = targetRot; transform.position = targetPos; isRolling = false; }
场景2:触屏滑动操作(移动端)
如果是做移动端游戏,就需要检测触摸的起始和结束位置,计算滑动方向,还要加个阈值过滤误触:
public float tumblingDuration = 0.2f; public float rollSpeed = 5f; private Vector3 currentRollDir = Vector3.forward; private bool isRolling = false; private Vector2 touchStartPos; void Update() { // 检测触屏滑动 if (Input.touchCount > 0) { Touch touch = Input.GetTouch(0); switch (touch.phase) { case TouchPhase.Began: touchStartPos = touch.position; break; case TouchPhase.Ended: Vector2 touchEndPos = touch.position; Vector2 swipeDir = touchEndPos - touchStartPos; // 判断滑动方向(设置50像素阈值,过滤小幅度误触) if (Mathf.Abs(swipeDir.x) > Mathf.Abs(swipeDir.y)) { // 左右滑动 if (swipeDir.x > 50f) SetNewRollDirection(Vector3.right); else if (swipeDir.x < -50f) SetNewRollDirection(Vector3.left); } else { // 上下滑动 if (swipeDir.y > 50f) SetNewRollDirection(Vector3.forward); else if (swipeDir.y < -50f) SetNewRollDirection(Vector3.back); } break; } } // 持续滚动逻辑和键盘版一致 if (isRolling) { transform.position = Vector3.MoveTowards(transform.position, targetPos, rollSpeed * Time.deltaTime); if (Vector3.Distance(transform.position, targetPos) < 0.01f) { isRolling = false; // 可选:自动持续滚动同一方向 // SetNewRollDirection(currentRollDir); } } } // 复用键盘版的SetNewRollDirection和TumbleCube方法 void SetNewRollDirection(Vector3 newDir) { if (isRolling) return; currentRollDir = newDir; targetPos = transform.position + currentRollDir; isRolling = true; StartCoroutine(TumbleCube(newDir)); } IEnumerator TumbleCube(Vector3 dir) { // 和键盘版的协程代码完全一致 isRolling = true; Quaternion startRot = transform.rotation; Quaternion targetRot = startRot * Quaternion.FromToRotation(Vector3.up, dir); Vector3 startPos = transform.position; Vector3 targetPos = startPos + dir; float elapsed = 0f; while (elapsed < tumblingDuration) { elapsed += Time.deltaTime; float t = elapsed / tumblingDuration; t = Mathf.SmoothStep(0, 1, t); transform.rotation = Quaternion.Lerp(startRot, targetRot, t); transform.position = Vector3.Lerp(startPos, targetPos, t); yield return null; } transform.rotation = targetRot; transform.position = targetPos; isRolling = false; }
几个小细节帮你避坑
isRolling状态锁:立方体正在滚的时候,就算再按方向键/滑动也不会响应,避免滚到一半变方向的混乱情况- 平滑翻滚协程:比起直接挪位置,这个协程会同步旋转和移动,更像真实的立方体滚动效果,你可以替换掉简单的位置移动代码
- 触屏滑动阈值:设了50像素的门槛,玩家不小心碰一下屏幕不会触发滚动,减少误操作
内容的提问来源于stack exchange,提问作者Don_Huan
相关产品推荐
相关产品推荐

