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

Unity 2D开发中如何根据距爆炸中心距离计算刚体作用力乘数

Unity 2D火箭跳跃动态爆炸力实现

问题原因

当前代码的力计算逻辑存在三个核心错误:

  • CalculateForceMultiplier直接返回距离值,逻辑反向:距离越远返回值越大,施加的力反而越高,和「近大远小」的预期完全相反
  • 弹射方向向量launchPos未做归一化处理:向量本身的长度已经包含了距离信息,会导致力值计算重复叠加距离因子,数值完全不受控
  • 缺少爆炸有效范围限制:力值没有上下限约束,手感无法稳定调优

实现思路

参考《军团要塞2》《雷神之锤》的火箭跳跃手感,采用范围钳制+比例衰减+可选非线性曲线的计算逻辑:

  1. 新增爆炸有效半径参数,超出半径的目标不受爆炸力
  2. 将玩家与爆炸点的距离钳制在0~爆炸半径区间内,避免异常值
  3. 对弹射方向向量做归一化,仅保留方向信息,力的大小完全由输入参数控制
  4. 计算距离占爆炸半径的比例,用1-距离比例得到基础衰减值,支持通过指数调整衰减曲线:
    • 指数为1时是线性衰减,力随距离均匀下降
    • 指数大于1时是非线性衰减,贴脸推力拉满、距离稍远时力快速下降,匹配经典FPS火箭跳的爽感

修正后完整代码

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

public class HandleExplosion : MonoBehaviour
{
    [SerializeField] float launchSpeed;
    [SerializeField] float explosionTime;
    [Header("爆炸力参数")]
    [Tooltip("爆炸有效作用半径")]
    [SerializeField] float explosionRadius = 4f;
    [Tooltip("衰减指数,1为线性,值越大近点推力越强、远距离衰减越快,经典火箭跳推荐1.5~2.5")]
    [SerializeField] float falloffExponent = 2f;

    private void Start()
    {
        StartCoroutine(DeleteExplosion());
    }

    private void OnCollisionEnter2D(Collision2D player)
    {
        if (player.gameObject.CompareTag("Player"))
        {
            Rigidbody2D playerRb = player.gameObject.GetComponent<Rigidbody2D>();
            // 计算从爆炸点指向玩家的方向,归一化后仅保留方向
            Vector2 launchDir = (player.transform.position - transform.position).normalized;
            float forceMultiplier = CalculateForceMultiplier(player);
            // 施加冲量
            playerRb.AddForce(launchDir * launchSpeed * forceMultiplier, ForceMode2D.Impulse);
        }
    }

    float CalculateForceMultiplier(Collision2D player)
    {
        // 计算两点距离
        float distance = Vector2.Distance(player.transform.position, transform.position);
        // 将距离钳制在有效范围内,避免超出半径后出现负数、零距离除0等异常
        distance = Mathf.Clamp(distance, 0f, explosionRadius);
        // 计算基础衰减比例
        float falloffRatio = 1 - (distance / explosionRadius);
        // 应用指数曲线后返回最终乘数,范围固定在0~1之间
        return Mathf.Pow(falloffRatio, falloffExponent);
    }

    IEnumerator DeleteExplosion() {
        yield return new WaitForSeconds(explosionTime);
        Destroy(gameObject);
    }
}

调参参考

  • 想要更接近《雷神之锤》的爽快手感:把falloffExponent调到22.5,`explosionRadius`设为3.54.5,适当调高launchSpeed,贴脸弹射高度会非常高,距离爆炸点1个单位以上推力快速下降
  • 想要更写实的爆炸效果:把falloffExponent设为1,采用线性衰减即可
  • 如果需要实现范围爆炸(不需要碰撞接触,只要在半径内就受推力),把OnCollisionEnter2D的逻辑移到Start里,用Physics2D.OverlapCircleAll检测半径内所有带Player标签的物体逐一施加力即可

内容的提问来源于stack exchange,提问作者licco-twentythree

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:42:18