编辑器扩展

自定义类型的显示:

public class TestClass
{
    public int value;
    public string name = "";
}

public class TestEditor : EditorWindow
{
    public static TestEditor window = null;

    [MenuItem("Test/MyEditor &t")]
    public static void ShowWindow()
    {
        window = EditorWindow.GetWindow(typeof(TestEditor), false, "TestEditor") as TestEditor;
    }

    private List<TestClass> lst = new List<TestClass>();
    private bool showFoldout = true;
    private Vector2 scrollPosition = Vector2.zero;

    int count
    {
        get { return lst.Count; }
        set 
        { 
            if(value < lst.Count)
            {
                lst.RemoveRange(value, lst.Count - value);
            }
            else if(value > lst.Count)
            {
                for(int i = 0; i < value; ++i)
                {
                    lst.Add(new TestClass());
                }
            }
        }
    }

    void OnGUI()
    {
        GUILayout.BeginArea(new Rect(0, 0, Screen.width, Screen.height), "", "box");
        GUILayout.BeginVertical("box");
        scrollPosition = GUILayout.BeginScrollView(scrollPosition, "box");      // 创建自适应滚动条

        // 创建折叠标签
        showFoldout = EditorGUILayout.Foldout(showFoldout, "Array");
        if (showFoldout)
        {
            GUILayout.BeginHorizontal();
            GUILayout.Label("count", GUILayout.Width(50));
            count = System.Convert.ToInt32(GUILayout.TextField(count.ToString()));
            GUILayout.EndHorizontal();

            // 逐行显示数据
            for (int i = 0; i < count; ++i)
            {
                GUILayout.BeginHorizontal();

                GUILayout.Label("name", GUILayout.Width(50));
                lst[i].name = GUILayout.TextField(lst[i].name);

                GUILayout.Label("value", GUILayout.Width(50));
                lst[i].value = System.Convert.ToInt32(GUILayout.TextField(lst[i].value.ToString()));

                GUILayout.EndHorizontal();
            }
        }

        GUILayout.EndVertical();
        GUILayout.EndScrollView();
        GUILayout.EndArea();
    }

}

  上述代码在自定义编辑器中显示了自定义结构TestClass的列表,效果如下所示:

  有个小细节值得一提,TestClass.name一定要初始化为"",不然现实会报错。

添加Project界面自定义菜单:

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

[CreateAssetMenu(menuName="Test/CreateMyObject")]
public class MyObject : ScriptableObject
{
    // 中心点
    public Vector3 Center;

    // 受击点
    public List<Vector3> HitPos = new List<Vector3>();

    // 受击点朝向
    public List<Vector3> HitDir = new List<Vector3>();
}

获取Hierarchy中gameobject所关联的本地资源prefab:

  var prefabSource = PrefabUtility.GetPrefabParent(prefab);

自定义ScriptableObject:

    [CreateAssetMenu(menuName = "Test/Numbers")]
    public class DataNumbers : ScriptableObject
    {
        public List<int> Values = new List<int>();
    }

    // 加载
    var numberAsset = AssetDatabase.LoadAssetAtPath<DataNumbers>(filePath);
    for(int i = 0; i < numberAsset.Values.Count; ++i)
    {
        Debug.Log(numberAsset.Values[i]);
    }
    }

    // 保存
    numberAsset.Values.Add(1);
    numberAsset.Values.Add(2);
    numberAsset.Values.Add(3);
    EditorUtility.SetDirty(numberAsset);
    AssetDatabase.SaveAssets();

SceneView显示当前鼠标位置:

 

using UnityEngine;
using UnityEditor;

public class WildTerrainEditor : EditorWindow
{
    private void OnEnable()
    {
        SceneView.onSceneGUIDelegate -= OnSceneGUI;
        SceneView.onSceneGUIDelegate += OnSceneGUI;
    }

    private void OnDestroy()
    {
        SceneView.onSceneGUIDelegate -= OnSceneGUI;
    }

    private void OnSceneGUI(SceneView sceneView)
    {
        UpdateMousePosition();

        Handles.BeginGUI();
        GUI.color = Color.red;
        GUI.Label(new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y - 20, 100, 20),
            SceneViewMousPos.ToString());
        Handles.EndGUI();
    }
    
    private void UpdateMousePosition()
    {
        Event e = Event.current;

        Ray r = Camera.current.ScreenPointToRay(new Vector3(e.mousePosition.x, -e.mousePosition.y + Camera.current.pixelHeight));
        Vector3 mousePos = r.origin;
        SceneViewMousPos = mousePos;
    }
}

统一调整渲染深度信息:

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

namespace James
{
    [ExecuteInEditMode]
    public class UniformRenderDepth : MonoBehaviour
    {
        private const int   Invalid = -10000;
        public string       SortingLayerName;                       // 空表示不设置
        public int          SortingOrder = Invalid;                 // -10000表示不设置
        public int          RenderQueue = Invalid;                  // -10000表示不设置

        private void Start()
        {
            Set();
        }

        [ContextMenu("Set")]
        public void Set()
        {
            Renderer[] renderers = GetComponentsInChildren<Renderer>(true);
            foreach (var r in renderers)
            {
                if (RenderQueue != Invalid)
                {
                    if (Application.isPlaying)
                    {
                        r.material.renderQueue = RenderQueue;
                    }
                    else
                    {
                        r.sharedMaterial.renderQueue = RenderQueue;
                    }
                }
                if (string.IsNullOrEmpty(SortingLayerName) == false)
                {
                    r.sortingLayerName = SortingLayerName;
                }
                if (SortingOrder != Invalid)
                {
                    r.sortingOrder = SortingOrder;
                }
            }
        }

        [ContextMenu("Get")]
        public void Get()
        {
            Renderer[] renderers = GetComponentsInChildren<Renderer>(true);
            foreach (var r in renderers)
            {
                if (Application.isPlaying)
                {
                    RenderQueue = r.material.renderQueue;
                }
                else
                {
                    RenderQueue = r.sharedMaterial.renderQueue;
                }
                SortingLayerName = r.sortingLayerName;
                SortingOrder = r.sortingOrder;
                break;
            }
        }
    }
}

 子节点自动排布脚本:

public class AutoSetGroup : MonoBehaviour
{
    public Vector2 size = Vector2.one;
    public Vector2Int num = Vector2Int.one;

    [ContextMenu("Set")]
    public void Execute()
    {
        float hHalfSize = size.x / (2 * num.x);
        float vHalfSize = size.y / (2 * num.y);

        Vector2 topLeftPos = new Vector2(- 0.5f * size.x + hHalfSize, 0.5f * size.y - vHalfSize);

        int total = num.x * num.y;
        for(int i = 0; i < total; ++i)
        {
            if(i >= transform.childCount) return;

            var tran = transform.GetChild(i);
            int xIdx = i % num.x;
            int yIdx = i / num.x;

            var pos = tran.localPosition;
            pos.x = topLeftPos.x + xIdx * hHalfSize * 2;
            pos.y = topLeftPos.y - yIdx * vHalfSize * 2;
            tran.localPosition = pos;
        }

    }
}

 

原文地址:https://www.cnblogs.com/sifenkesi/p/3961580.html