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

