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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:41:20