Unity中讓父物體的位置調(diào)整到子物體的中心位置(子物體位置不變)

image.png

image.png

image.png

邏輯原理:

  1. 遍歷所有的子Transform
  2. 查找?guī)enderer的取Renderer的世界位置的Bound中心值,不帶Renderer的看是否只有一個(gè)Transform或者沒有子物體的取世界坐標(biāo)每次計(jì)算xyz分量的最大和最小值
  3. 最后把最大和最小的取中

上代碼:

using UnityEditor;
using UnityEngine;

public class TransformCenterOnChildren : Editor
{
    [MenuItem("Tools/坐標(biāo)歸到子物體中心點(diǎn)位置")]
    static void Start()
    {
        GameObject[] seGO = Selection.gameObjects;
        if (seGO.Length == 0)
        {
            return;
        }
        for (int i = 0; i < seGO.Length; i++)
        {
            Transform curTr = seGO[i].transform;
            Vector3 curPos = curTr.position;

            Vector3 cenPos = Center(curTr);

            int childCount = curTr.childCount;

            for (int k = 0; k < childCount; k++)
            {
                Vector3 offset = cenPos - curPos;
                curTr.GetChild(k).position -= offset;
            }
            Undo.RecordObject(curTr, "變換當(dāng)前位置");
            curTr.position = cenPos;
        }
    }

    /// <summary>
    /// 計(jì)算子層級的物體中心點(diǎn)
    /// </summary>
    /// <param name="parentTransform">當(dāng)前的 Transform</param>
    /// <returns>返回子物體的中心點(diǎn)</returns>
    static Vector3 Center(Transform parentTransform)
    {
        // 獲取當(dāng)前 Transform 的所有子物體
        Transform[] allTrans = parentTransform.GetComponentsInChildren<Transform>(true);
        if (allTrans.Length == 1)
        {
            return parentTransform.position;
        }

        //初始化初始值
        float xMax = allTrans[1].position.x,
            yMax = allTrans[1].position.y,
            zMax = allTrans[1].position.z,
            xMin = allTrans[1].position.x,
            yMin = allTrans[1].position.y,
            zMin = allTrans[1].position.z;



        foreach (var tran in allTrans)
        {
            if (tran.TryGetComponent(out Renderer renderer))
            {
                // 獲取子物體包圍盒中心點(diǎn)(在世界坐標(biāo)系中)
                Vector3 childBoundsCenter = renderer.bounds.center;
                // 計(jì)算所有子物體中心點(diǎn)的最大最小值
                xMax = Mathf.Max(childBoundsCenter.x, xMax);
                yMax = Mathf.Max(childBoundsCenter.y, yMax);
                zMax = Mathf.Max(childBoundsCenter.z, zMax);

                xMin = Mathf.Min(childBoundsCenter.x, xMin);
                yMin = Mathf.Min(childBoundsCenter.y, yMin);
                zMin = Mathf.Min(childBoundsCenter.z, zMin);
            }
            else if (tran.GetComponents<Component>().Length > 1 || tran.childCount == 0)
            {
                // 如果當(dāng)前物體的 Component 數(shù)量除了 Transform 以外還有其他 Component ,或者子物體是空的,也考慮在內(nèi)
                xMax = Mathf.Max(tran.position.x, xMax);
                yMax = Mathf.Max(tran.position.y, yMax);
                zMax = Mathf.Max(tran.position.z, zMax);

                xMin = Mathf.Min(tran.position.x, xMin);
                yMin = Mathf.Min(tran.position.y, yMin);
                zMin = Mathf.Min(tran.position.z, zMin);
            }
        }

        // 組合大小值
        Vector3 min = new Vector3(xMin, yMin, zMin);
        Vector3 max = new Vector3(xMax, yMax, zMax);
        // 計(jì)算中心點(diǎn)
        Vector3 averageBoundsCenter = (min + max) / 2;

        return averageBoundsCenter;
    }
}

使用方法:

在任何一個(gè)路徑下帶有Editor文件夾的里面創(chuàng)建一個(gè)C#腳本,命名交TransformCenterOnChildren,把代碼完整復(fù)制進(jìn)去。
等Unity編譯完成在上方有一個(gè)Tools的菜單,選中要調(diào)整的父層級Gameobject,點(diǎn)擊坐標(biāo)歸到子物體中心點(diǎn)位置。

image.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、Unity簡介 1. Unity界面 Shift + Space : 放大界面 Scene界面按鈕渲染模式2D...
    MYves閱讀 8,662評論 0 22
  • 最先執(zhí)行的方法是: 1、(激活時(shí)的初始化代碼)Awake,2、Start、3、Update【FixUpdate、L...
    困卡閱讀 4,494評論 0 8
  • 前言:這篇文章是之前自己博客里的,這次重新用Markdown排下版,給需要的人, 想要成為一個(gè)優(yōu)秀的U3D程序員...
    道阻且長_行則將至閱讀 1,828評論 0 20
  • 更新:【面試題含答案】http://bbs.9ria.com/thread-288394-1-1.html 高頻問...
    好怕怕閱讀 5,081評論 3 53
  • 111. [動(dòng)畫系統(tǒng)]如何將其他類型的動(dòng)畫轉(zhuǎn)換成關(guān)鍵幀動(dòng)畫? 動(dòng)畫->點(diǎn)緩存->關(guān)鍵幀 112. [動(dòng)畫]Unit...
    胤醚貔貅閱讀 13,516評論 3 88

友情鏈接更多精彩內(nèi)容