为UnityEditor增加Maya一些功能的工具包

本文介绍了一款用于Unity的场景编辑工具,提供了多个实用功能,如SetCollection打组、SetCollectionByName按名打组、DuplicateAddTrans特殊复制等,极大地提高了场景编辑效率。

你是否有这样的经历,导入一个编辑了一半的场景,面对几百个散片一样的场景模型无从下手。

使用过Maya都知道,按下G键可以打组,但是Unity没有这个功能,这里把Maya里边几个好用的场景编辑功能搬运到Unity中实现。

1.SetCollection:打组,把选定的Gameobject变成一个新建的父物体的子物体,并且放到Hierarchy最下方。UnderFather决定新的父物体是否在原本的父物体下方,还是放在Hierarchy最下方。

2.SetCollectionByName:按照名字打组,在如果选定的Gobj名字含有关键词,就会打组。

3.DuplicateAddTrans:特殊复制,和Maya中特殊复制类似,只支持位置变化,例如,指定一个地砖之后,可以快速铺满整个场景。

4.GoToLast/First:置于Hierarchy窗口的最上方或者最下方

5.ReplaceGameobject:将选定的Prefab快速替换成另一个,例如选定场景中的一块或者几块白色地砖,快速替换为彩色。

使用方法,将脚本拷贝到项目中任意位置,在菜单栏打开Tools/LevelEditorWindow,就可以使用。推荐拷贝到Editor目录下,防止被打爆。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;//引入编辑器类命名空间
public class LevelEditorWindow : EditorWindow
{
    [MenuItem("Tools/LevelEditorWindow")]//菜单栏下的路径
    static void OpenWindow()
    {
        //获取窗口并打开
        LevelEditorWindow window = EditorWindow.GetWindow<LevelEditorWindow>();
        window.Show();//显示窗口

    }
    Color colorField = Color.red;
    string inputStr = "";
    string groupName = "";
    string objectName = "";
    string collectName = "";
    public Object replaceObject;
    Vector3 addTrans = Vector3.zero;
    int duplicateCount = 0;
    bool ignoreFather = false;
    private void OnGUI()
    {
        
        EditorGUILayout.BeginVertical();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("SetCollection", GUILayout.Width(150), GUILayout.Height(20)))
        {//自动打组的功能
            SetCollection();
        }
        GUILayout.Label("组名称", GUILayout.Width(40), GUILayout.Height(20));
        groupName = EditorGUILayout.TextField(groupName);

        GUILayout.Label("物体名称", GUILayout.Width(60), GUILayout.Height(20));
        objectName = EditorGUILayout.TextField(objectName);
        if (GUILayout.Button(ignoreFather? "IgnoreFather":"UnderFather", GUILayout.Width(150), GUILayout.Height(20)))
        {
            ignoreFather = !ignoreFather;
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("SetCollectionByName", GUILayout.Width(150), GUILayout.Height(20)))
        {//按照名字自动打组的功能
            CollectByName();
        }
        GUILayout.Label("查找名称", GUILayout.Width(60), GUILayout.Height(20));
        collectName = EditorGUILayout.TextField(collectName);

        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("DuplicateAddTrans", GUILayout.Width(150), GUILayout.Height(20)))
        {//特殊复制的功能
            DuplicateAddTrans(duplicateCount);
        }
        //GUILayout.Label("查找名称", GUILayout.Width(60), GUILayout.Height(20));
        addTrans = EditorGUILayout.Vector3Field("addTrans:", addTrans);
        duplicateCount = EditorGUILayout.IntField(duplicateCount);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("GoToLast", GUILayout.Width(150), GUILayout.Height(20)))
        {//置于Hierarchy最后面
            GoToLast();
        }
        if (GUILayout.Button("GoToFirst", GUILayout.Width(150), GUILayout.Height(20)))
        {//置于Hierarchy最前面
            GoToFirst();
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("ReplaceGameobject", GUILayout.Width(150), GUILayout.Height(20)))
        {//替换当前的prefab
            ReplaceGameobjectByPrefab(replaceObject);
        }
        replaceObject = EditorGUILayout.ObjectField(replaceObject, typeof(Object), false);
        EditorGUILayout.EndHorizontal();

        //结束控件的自动布局
        EditorGUILayout.EndVertical();
    }
    void SetCollection()
    {
        GameObject[] gobjs = Selection.gameObjects;
        GameObject group;

        group = new GameObject();
        group.transform.parent = null;
        group.name = groupName == "" ? "Default" : groupName;

        if(gobjs[0].transform.parent != null && !ignoreFather)
        {
            group.transform.parent = gobjs[0].transform.parent;
        }

        //Object[] objs = Selection.objects;
        foreach (GameObject gobj in gobjs)
        {
            if (objectName != "")
                gobj.name = "objectName";
            gobj.transform.parent = group.transform;
        }
        group.transform.SetAsLastSibling();
    }
    void CollectByName()
    {
        if (collectName == "") return;
        GameObject father = new GameObject();
        father.transform.parent = null;
        father.name = collectName + "Collection";


        Object[] objs = Selection.objects;
        foreach (Object obj in objs)
        {
            if (obj.name.Contains(collectName))
            {
                GameObject gobj = obj as GameObject;
                gobj.transform.parent = father.transform;
            }
        }
        father.transform.SetAsLastSibling();
    }
    void DuplicateAddTrans(int count)
    {
        // Event e = new Event();
        // e = new EventModifiers
        GameObject[] gobjs = Selection.gameObjects;
        for (int i = 1; i <= count; i++)
        {
            foreach (GameObject gobj in gobjs)
            {
                if (PrefabUtility.IsOutermostPrefabInstanceRoot(gobj))
                {
                    //string path = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot (gobj);
                    Object source = PrefabUtility.GetCorrespondingObjectFromSource(gobj);
                    GameObject clone = PrefabUtility.InstantiatePrefab(source) as GameObject;

                    AlignLocalTransform(clone, gobj);

                    clone.transform.position += addTrans * i;
                    Undo.RegisterCreatedObjectUndo(clone, "Create object");
                }
                else
                {
                    Debug.Log("RootNo");
                    GameObject insObj = Instantiate(gobj);
                    insObj.name = gobj.name;
                    if (gobj.transform.parent != null)
                        insObj.transform.parent = gobj.transform.parent;
                    insObj.transform.position = gobj.transform.position + addTrans * i;
                    insObj.transform.SetAsLastSibling();
                }
            }
        }
    }
    void GoToLast()
    {
        GameObject[] gobjs = Selection.gameObjects;
        foreach (GameObject gobj in gobjs)
        {
            gobj.transform.SetAsLastSibling();
        }
    }
    void GoToFirst()
    {
        GameObject[] gobjs = Selection.gameObjects;
        foreach (GameObject gobj in gobjs)
        {
            gobj.transform.SetAsFirstSibling();
        }
    }
    void ReplaceGameobject()
    {
        GameObject[] gobjs = Selection.gameObjects;
        foreach (GameObject gobj in gobjs)
        {
            Transform tempT = gobj.transform;
            Object replace = Instantiate(replaceObject, tempT.position, tempT.rotation);

            GameObject.DestroyImmediate(gobj);
        }
    }
    void ReplaceGameobjectByPrefab(Object obj)
    {
        GameObject[] gobjs = Selection.gameObjects;
        foreach (GameObject gobj in gobjs)
        {
            GameObject clone = PrefabUtility.InstantiatePrefab(obj) as GameObject;

            AlignLocalTransform(clone, gobj);
            Undo.RegisterCreatedObjectUndo(clone, "Create object");

            Undo.DestroyObjectImmediate(gobj);
        }
    }
    void AlignLocalTransform(GameObject g1, GameObject g2)
    {
        g1.transform.parent = g2.transform.parent;
        g1.transform.localPosition = g2.transform.localPosition;
        g1.transform.localRotation = g2.transform.localRotation;
        g1.transform.localScale = g2.transform.localScale;
        g1.transform.SetAsLastSibling();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值