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

如何程序化获取带旋转GameObject的四个外围点?

解决方案:获取随GameObject旋转同步的外围点

你的问题核心是原来的方法计算的是世界空间轴对齐的包围盒,当父物体旋转时,这个包围盒不会跟随物体的局部坐标系旋转,导致外围点位置不符合预期。可以通过先计算父物体局部空间的包围盒,再将其转换到世界空间的方式解决。

步骤1:计算父物体局部空间的总包围盒

这个方法会遍历所有子物体的Renderer,把它们的包围盒转换到父物体的局部空间后合并,得到能反映物体自身形状的局部包围盒:

private Bounds GetLocalBounds()
{
    var renderers = GetComponentsInChildren<Renderer>();
    if (renderers.Length == 0) return new Bounds();

    // 初始化第一个子物体的局部包围盒(转换到父物体局部空间)
    Renderer firstRenderer = renderers[0];
    Bounds localBounds = firstRenderer.localBounds;
    // 将子物体的世界空间中心点转换为父物体局部空间坐标
    localBounds.center = transform.InverseTransformPoint(firstRenderer.bounds.center);
    // 考虑子物体自身缩放对包围盒大小的影响
    localBounds.extents = Vector3.Scale(firstRenderer.localBounds.extents, firstRenderer.transform.localScale);

    // 合并剩余子物体的局部包围盒
    for (int i = 1; i < renderers.Length; i++)
    {
        Renderer renderer = renderers[i];
        Bounds childLocalBounds = renderer.localBounds;
        childLocalBounds.center = transform.InverseTransformPoint(renderer.bounds.center);
        childLocalBounds.extents = Vector3.Scale(renderer.localBounds.extents, renderer.transform.localScale);
        localBounds.Encapsulate(childLocalBounds);
    }

    return localBounds;
}

步骤2:获取世界空间的同步外围点

基于局部包围盒,定义你需要的四个外围点(比如局部空间的左、右、前、后侧面中心点,或四个角点),再通过TransformPoint转换到世界空间——这个方法会自动应用父物体的旋转、缩放和位移,让点的位置完全跟随物体变换:

public List<Vector3> GetSyncedOuterPoints()
{
    Bounds localBounds = GetLocalBounds();
    List<Vector3> outerPoints = new List<Vector3>();

    // 示例:获取局部包围盒的四个侧面中心点(可根据需求调整)
    Vector3 leftCenter = localBounds.center + Vector3.left * localBounds.extents.x;
    Vector3 rightCenter = localBounds.center + Vector3.right * localBounds.extents.x;
    Vector3 frontCenter = localBounds.center + Vector3.forward * localBounds.extents.z;
    Vector3 backCenter = localBounds.center + Vector3.back * localBounds.extents.z;

    // 转换为世界空间点
    outerPoints.Add(transform.TransformPoint(leftCenter));
    outerPoints.Add(transform.TransformPoint(rightCenter));
    outerPoints.Add(transform.TransformPoint(frontCenter));
    outerPoints.Add(transform.TransformPoint(backCenter));

    // 如果你需要的是包围盒的四个角点,可替换为以下代码:
    // Vector3 cornerBLF = new Vector3(localBounds.min.x, localBounds.min.y, localBounds.max.z); // 左下前
    // Vector3 cornerBRF = new Vector3(localBounds.max.x, localBounds.min.y, localBounds.max.z); // 右下前
    // Vector3 cornerBLB = new Vector3(localBounds.min.x, localBounds.min.y, localBounds.min.z); // 左下后
    // Vector3 cornerBRB = new Vector3(localBounds.max.x, localBounds.min.y, localBounds.min.z); // 右下后
    // outerPoints.Add(transform.TransformPoint(cornerBLF));
    // outerPoints.Add(transform.TransformPoint(cornerBRF));
    // outerPoints.Add(transform.TransformPoint(cornerBLB));
    // outerPoints.Add(transform.TransformPoint(cornerBRB));

    return outerPoints;
}

原理说明

  • 世界空间的Renderer.bounds是轴对齐的,无论物体怎么旋转,它的包围盒始终贴合世界坐标轴,所以无法反映物体自身的朝向。
  • 局部空间的包围盒是以父物体的局部坐标系为基准的,再通过transform.TransformPoint转换时,会自动叠加父物体的旋转、缩放和位移,最终得到的世界空间点会完全跟随物体的姿态变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:30:42