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

如何为已有设定速度的Rigidbody2D实现全方位发射?

解决玩家全方位蹦床发射问题

核心问题分析

你的玩家移动脚本在FixedUpdate中直接覆盖了水平方向的速度值:rb.velocity = new Vector2(move.x * speed, rb.velocity.y);,这会导致任何外部施加的水平方向力(比如蹦床的发射力)被强制清零,只要玩家没有输入。要实现全方位发射,首先需要修改移动逻辑,避免无输入时强制重置水平速度。


方案一:修改玩家移动脚本(保留直接速度控制+自然减速)

这种方式既保留原有的移动手感,又允许外部力的水平分量生效:

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    Rigidbody2D rb;
    [SerializeField] float speed;
    [SerializeField] float horizontalDrag = 3f; // 无输入时的自然减速系数

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

    void FixedUpdate()
    {
        float inputH = Input.GetAxisRaw("Horizontal");
        if (Mathf.Abs(inputH) > 0.1f)
        {
            // 有输入时,直接设置目标移动速度
            rb.velocity = new Vector2(inputH * speed, rb.velocity.y);
            rb.drag = 0; // 关闭拖拽,避免影响主动移动
        }
        else
        {
            // 无输入时,通过拖拽让水平速度自然衰减,不强制清零
            rb.drag = horizontalDrag;
        }
    }
}

方案二:改用AddForce实现移动(力叠加模式)

如果希望移动力和发射力可以自然叠加,推荐用这种方式,同时限制最大速度防止失控:

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    Rigidbody2D rb;
    [SerializeField] float moveForce = 20f;
    [SerializeField] float maxHorizontalSpeed = 5f;

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

    void FixedUpdate()
    {
        float inputH = Input.GetAxisRaw("Horizontal");
        if (Mathf.Abs(inputH) > 0.1f)
        {
            // 施加水平移动力,与外部发射力叠加
            rb.AddForce(new Vector2(inputH * moveForce, 0), ForceMode2D.Force);
            // 限制最大水平速度,避免无限加速
            float clampedXSpeed = Mathf.Clamp(rb.velocity.x, -maxHorizontalSpeed, maxHorizontalSpeed);
            rb.velocity = new Vector2(clampedXSpeed, rb.velocity.y);
        }
    }
}

编写蹦床发射脚本

完成移动脚本修改后,编写蹦床的碰撞触发逻辑,根据自身旋转方向发射玩家:

using UnityEngine;

public class Trampoline : MonoBehaviour
{
    [SerializeField] float launchForce = 15f;
    [SerializeField] LayerMask playerLayer; // 选择玩家所在的层级,避免误触发

    void OnCollisionEnter2D(Collision2D collision)
    {
        // 验证碰撞对象是否为玩家
        if (((1 << collision.gameObject.layer) & playerLayer) != 0)
        {
            Rigidbody2D playerRb = collision.gameObject.GetComponent<Rigidbody2D>();
            if (playerRb != null)
            {
                // 以蹦床的向上方向作为发射方向(旋转时会自动适配角度)
                Vector2 launchDirection = transform.up;
                // 用Impulse模式瞬间施加力,模拟蹦床弹跳的爆发力
                playerRb.AddForce(launchDirection * launchForce, ForceMode2D.Impulse);
            }
        }
    }
}

注意事项

  1. 给蹦床添加Collider2D(比如BoxCollider2D),并勾选Is Trigger(如果用OnTriggerEnter2D)或保持非触发(用上面的OnCollisionEnter2D)
  2. 确保玩家的Rigidbody2D没有被设置为Kinematic,否则力不会生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:57:35