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

Unity C#如何实现游戏对象触碰其他物体时暂停,按键可恢复移动

功能实现修改方案

原有代码核心问题

  • 使用Input.GetKey监听按键,需要持续按住按键才会保持移动状态,不符合「按一次就持续移动」的需求
  • OnTriggerEnter2D方法中isCol = isCol的写法没有修改变量值,碰撞后状态不会更新,无法触发停止逻辑
  • 缺少碰撞停止后,按按键恢复移动的切换逻辑
  • 混用了Trigger和Collision的回调,如果你给物体挂的是触发碰撞体(Is Trigger勾选),就不会触发OnCollisionExit2D,状态会错乱

修改后完整代码

using UnityEngine;

public class PlayerMove : MonoBehaviour
{
    Rigidbody2D rb2d;
    // 移动速度,可在Inspector面板调整
    public float speed = 10;
    // 标记当前是否在移动状态
    bool isMoving = false;
    // 标记当前是否碰撞到了其他物体
    bool isCollided = false;
    // 存储当前移动的方向,1是右,-1是左
    int moveDir = 0;

    public GameObject Rainbow_1;
    public GameObject Rainbow_0;

    void Start() 
    { 
        rb2d = GetComponent<Rigidbody2D>(); 
    }

    void Update() 
    {
        // 监听右方向键按下(按一次触发一次,不需要按住)
        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            // 如果已经碰撞停下了,按一次就恢复移动
            if (isCollided)
            {
                isCollided = false;
                isMoving = true;
                moveDir = 1;
            }
            // 没碰撞的话,按一次切换移动/停止状态
            else
            {
                isMoving = !isMoving;
                moveDir = 1;
            }
        }
        // 左方向键逻辑和右一致,需要的话可以打开注释
        // if (Input.GetKeyDown(KeyCode.LeftArrow))
        // {
        //     if (isCollided)
        //     {
        //         isCollided = false;
        //         isMoving = true;
        //         moveDir = -1;
        //     }
        //     else
        //     {
        //         isMoving = !isMoving;
        //         moveDir = -1;
        //     }
        // }
    }

    private void FixedUpdate()
    {
        // 只有在移动中、没有碰撞的时候才给速度
        if (isMoving && !isCollided)
        {
            rb2d.velocity = new Vector2(moveDir * speed, rb2d.velocity.y);
        }
        // 否则速度设为0,停下
        else
        {
            rb2d.velocity = Vector2.zero;
        }
    }

    // 如果你用的是Trigger碰撞(碰撞体勾选了Is Trigger)就用这个方法
    private void OnTriggerEnter2D(Collider2D other)
    {
        Debug.Log("碰撞到了:" + other.gameObject.name);
        // 碰撞后标记为碰撞状态,停止移动
        isCollided = true;
        // 你原来的彩虹位置逻辑,保留
        Rainbow_0.transform.position = Rainbow_1.transform.position;
    }

    // 如果你没用Trigger,是普通碰撞体,就把上面的OnTriggerEnter2D删掉,用下面这个
    // private void OnCollisionEnter2D(Collision2D other)
    // {
    //     Debug.Log("碰撞到了:" + other.gameObject.name);
    //     isCollided = true;
    //     Rainbow_0.transform.position = Rainbow_1.transform.position;
    // }
}

配置注意事项

  • 给玩家对象挂上Rigidbody2D组件,重力缩放设为0(如果是2D横版不需要重力的话)
  • 玩家和要碰撞的对象都要挂碰撞体组件(BoxCollider2D/CircleCollider2D都可以)
  • 如果你勾选了碰撞体的Is Trigger,就用代码里的OnTriggerEnter2D,没勾选就用OnCollisionEnter2D,二选一就行

逻辑说明

  • 按一次右方向键,玩家就会持续向右走,不需要按住
  • 碰到其他物体的时候自动停下,位置固定
  • 停下后再按一次右方向键,就会继续向右移动
  • 不需要的左方向键逻辑我注释了,需要的话打开就行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:39:01