如何为已有设定速度的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); } } } }
注意事项
- 给蹦床添加
Collider2D(比如BoxCollider2D),并勾选Is Trigger(如果用OnTriggerEnter2D)或保持非触发(用上面的OnCollisionEnter2D) - 确保玩家的Rigidbody2D没有被设置为
Kinematic,否则力不会生效
内容的提问来源于stack exchange,提问作者Erram
相关产品推荐
相关产品推荐

