【Unity】解决父物体和子物体们相差十万八千里问题

参考资料:

Unity3D研究院之自动计算所有包围盒的中心点(七)

本文是上面链接文章的改进版本,解决问题有:

一、兼容父物体有Renderer情况,具体在代码里面会大量注释解释

二、解决上面链接源码的问题,如:父物体和子物体们相差非常大(1000以上)就不能一次性解决本章标题所说问题

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

public class FixedOffset
{
    [MenuItem("MyMenu/Do Test")]
    private static void Test5()
    {
        Transform parent = Selection.activeGameObject.transform;
        Vector3 center = Vector3.zero;
        //如果父物体有Renderer组件,GetComponentsInChildren是包含父物体Renderer的!我们要去除这个才能保证中心点准确!
        Renderer[] rendersArr = parent.GetComponentsInChildren<Renderer>();
        List<Renderer> renders = new List<Renderer>();
        for (int i = 0; i < rendersArr.Length; i++)
        {
            renders.Add(rendersArr[i]);
        }
        if (parent.GetComponent<Renderer>() != null)
        {
            renders.RemoveAt(0);//去除父物体的Renderer!
        }
        //计算所有子物体bounds中心点的平均值
        foreach (Renderer child in renders)
        {
            center += child.bounds.center;
        }
        center /= rendersArr.Length;
        //根据center和子物体bounds通过Encapsulate方法计算一个恰好容纳子物体们的容器bounds
        Bounds bounds = new Bounds(center, Vector3.zero);
        foreach (Renderer child in renders)
        {
            bounds.Encapsulate(child.bounds);
        }
        //注意!!center != bounds.center(已测试),我想应该是center仅仅是提供一个参考坐标,
        //而经过上面Encapsulate计算后bounds.center已经改变成最佳的

        //**********************这里可以注释掉,下面添加BoxCollider可注释
        BoxCollider box = parent.gameObject.GetComponent<BoxCollider>();
        if (box == null)
        {
            box = parent.gameObject.AddComponent<BoxCollider>();
        }
        box.center = Vector3.zero;
        box.size = bounds.size;
        //********************上面可注释

        //一个世界坐标系上的三维向量:父物体->[恰好容纳子物体们的容器中心点]
        Vector3 parentToCenter = bounds.center - parent.position;
        //一个世界坐标系上的三维向量:[恰好容纳子物体们的容器中心点]->父物体
        Vector3 centerToParent = -parentToCenter;

        //*******至此,拿到了2个向量,我们开始进行偏移!************
        //①.开始偏移子物体们将子物体从自身位置+centerToParent向量,从而偏移到父物体附近
        //可能到这里会有些疑问:子物体偏移过去了,那位置不就变了吗?这可不行啊!
        //无需担心,因为子物体偏移后还有另一个物体要进行偏移,仔细看②
        foreach (Transform t in parent)
        {
            t.position = t.position + centerToParent;
        }
        //②.父物体加上parentToCenter偏移到中心点
        parent.transform.position = parent.position + parentToCenter;

        //PS:
        //如果不理解这个过程,可以放到Unity上试试,观察子物体位置变化和父物体位置变化;
        //可以注释掉parent.transform.position = parent.position + parentToCenter;代码进行观察①情况
        //再取消注释测试完整代码,是不是父物体移动到了中心点...还是不懂的话,可能没救了..
    }
}

先选中父物体再去点击Do Test按钮进行解决标题所说问题

 

点击之后效果:

大概就这样,如果有什么问题,评论留言,我注释已经写的够详细的了。。。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值