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

Unity 2D滑块拼图开发:如何在方块移动时禁用玩家输入

解决方案

以下是修改后可满足两个需求的完整代码,核心改动没有破坏你原有滑动逻辑,仅新增状态控制和锁定逻辑:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movementver2: MonoBehaviour
{
    public Rigidbody2D rb;
    private float moveSpeed = 10f;
    public bool canMove = false;
    private bool isMoving = false; // 新增移动状态标记

    public const string UP = "up";
    public const string DOWN = "down";
    public const string LEFT = "left";
    public const string RIGHT = "right";

    string moveDirection;


    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        // 初始状态匹配可移动属性
        rb.isKinematic = !canMove;
        // 碰撞检测设为连续模式,避免高速滑动穿模
        rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
    }

    void Update()
    {
        // 只有未锁定且不在移动中时才响应输入
        if(canMove && !isMoving)
        {
            if (Input.GetKeyDown(KeyCode.W))
            {
                moveDirection = UP;
                LockInput();
            }
            if (Input.GetKeyDown(KeyCode.S))
            {
                moveDirection = DOWN;
                LockInput();
            }
            if(Input.GetKeyDown(KeyCode.D))
            {
                moveDirection = RIGHT;
                LockInput();
            }
            if(Input.GetKeyDown(KeyCode.A))
            {
                moveDirection = LEFT;
                LockInput();
            } 
        }
    }

    void FixedUpdate()
    {
        // 原有移动逻辑保留
        if(moveDirection == UP)
        {
            rb.velocity = new Vector2(0, moveSpeed);
        }
        if(moveDirection == DOWN)
        {
            rb.velocity = new Vector2(0, -moveSpeed);
        }
        if(moveDirection == RIGHT)
        {
            rb.velocity = new Vector2(moveSpeed, 0);
        }
        if(moveDirection == LEFT)
        {
            rb.velocity = new Vector2(-moveSpeed, 0);
        }

        // 新增停稳检测逻辑
        if (isMoving && rb.velocity.magnitude < 0.1f)
        {
            LockBlockPermanently();
        }
    }

    // 触发移动后立刻锁死输入,避免移动中重复响应按键
    void LockInput()
    {
        isMoving = true;
        canMove = false;
    }

    // 停稳后永久锁定方块,无法移动也不会被其他方块推动
    void LockBlockPermanently()
    {
        moveDirection = null;
        rb.velocity = Vector2.zero;
        // 开启运动学属性后,刚体不会受任何外力、碰撞影响,位置完全固定
        rb.isKinematic = true;
        isMoving = false;
    }
}

关键逻辑说明

  • 移动时禁输入:通过isMoving状态标记,触发移动后立刻锁定输入响应,直到方块停稳也不会再放开输入权限,完全符合第一个需求
  • 静止后防推动:方块停稳后开启Rigidbody2D.isKinematic属性,开启后该刚体不会受重力、碰撞推力的影响,位置完全固定,不会被其他滑动的方块带动,完全符合第二个需求
  • 静止检测用rb.velocity.magnitude < 0.1f判断,比协程定时检测更准确,不会出现还在滑动就提前锁死、或者已经停下还没触发锁定的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:54:05