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

Unity中AddExplosionForce无法作用于GameObject子对象问题求助

问题原因
  • 物理引擎状态同步延迟:你在同一帧内为子对象动态添加BoxCollider、解除父子关系后,立即调用Physics.OverlapSphere进行物理检测,此时物理引擎还未完成新一帧的状态同步,刚添加的碰撞体不会被检测到。你打印的碰撞体名称实际是场景中原本就存在碰撞体的其他物体,并不包含刚拆分的子对象,因此爆炸力没有加到目标对象上。
  • 冗余检测逻辑问题:你完全不需要通过球形检测来找子对象,解除父子关系前已经可以直接获取所有子对象的引用,绕一圈用物理检测反而增加了出错概率。
  • 隐含空引用风险:如果球形检测到没有挂载Rigidbody的物体,GetComponent<Rigidbody>()会返回null,调用AddExplosionForce会直接报错。
  • 参数适配问题:10f的基础爆炸力偏小,如果子对象Rigidbody的质量设置较大,也会出现推不动的视觉效果。
解决方法
  • 直接在遍历子对象的阶段记录每个子对象的Rigidbody引用,跳过冗余的球形检测步骤,既避免物理同步问题,也提升执行效率。
  • 确认子对象预制体上的Rigidbody没有开启Is Kinematic属性,同时根据子对象质量调整爆炸力参数,测试阶段可以先把力调到50-200区间验证效果。
  • 不需要动态修改碰撞体的话,可以提前把BoxCollider做到预制体上,减少运行时开销。
修正后代码
using System.Collections.Generic;
using UnityEngine;

private void OnCollisionEnter(Collision collision)
{
    Vector3 explosionPos = transform.position;
    // 先收集所有子对象的Rigidbody
    List<Rigidbody> childRbs = new List<Rigidbody>();
    while (transform.childCount > 0)
    {
        Transform child = transform.GetChild(0);
        child.parent = null;
        // 提前在预制体加了Collider可以删掉下面这行
        child.gameObject.AddComponent<BoxCollider>();
        Rigidbody rb = child.GetComponent<Rigidbody>();
        if (rb != null && !rb.isKinematic)
        {
            childRbs.Add(rb);
        }
    }
    // 直接给所有子对象加爆炸力
    foreach (var rb in childRbs)
    {
        // 可根据实际效果调整力的大小
        rb.AddExplosionForce(100f, explosionPos, 10f, 2f);
    }
    Destroy(gameObject);
}

如果你确实需要同时检测爆炸范围内的其他非子对象物体,可以用协程等待物理同步后再执行球形检测:

using System.Collections;
using UnityEngine;

private void OnCollisionEnter(Collision collision)
{
    Vector3 explosionPos = transform.position;
    // 处理子对象分离
    while (transform.childCount > 0)
    {
        Transform child = transform.GetChild(0);
        child.parent = null;
        child.gameObject.AddComponent<BoxCollider>();
    }
    // 启动协程等物理同步后再检测
    StartCoroutine(ApplyExplosionAfterPhysicsSync(explosionPos));
    Destroy(gameObject);
}

private IEnumerator ApplyExplosionAfterPhysicsSync(Vector3 explosionPos)
{
    // 等待一次物理更新完成
    yield return new WaitForFixedUpdate();
    Collider[] colliders = Physics.OverlapSphere(explosionPos, 10);
    foreach (var collider in colliders)
    {
        Rigidbody rb = collider.GetComponent<Rigidbody>();
        if (rb != null && !rb.isKinematic)
        {
            rb.AddExplosionForce(100f, explosionPos, 10f, 2f);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:27:01