读一读

public class Script_04_01 : MonoBehaviour{

    [SerializeField]
    private int id;
    [SerializeField]
    private string name;
    [SerializeField]
    private GameObject prefab;

    public GameObject[] objs;
    public string datas;
}

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(Script_04_01))]
public class Script_04_01_Insprctor : Editor {

    public override void OnInspectorGUI()
    {
        serializedObject.Update();//更新最新数据
        //获取数据信息
        SerializedProperty property = serializedObject.FindProperty("id");
        //赋值数据
        property.intValue = EditorGUILayout.IntField("主键", property.intValue); 

        property = serializedObject.FindProperty("name");
        property.stringValue = EditorGUILayout.TextField("姓名", property.stringValue);

        property = serializedObject.FindProperty("prefab");
        property.objectReferenceValue = EditorGUILayout.ObjectField("游戏对象", property.objectReferenceValue, typeof(GameObject), true);

        EditorGUILayout.PropertyField(serializedObject.FindProperty("objs"), true);//原生方法绘制
        EditorGUILayout.PropertyField(serializedObject.FindProperty("datas"), true);

        serializedObject.ApplyModifiedProperties();//保存全部数据
    }

}


可以通过SerializedObject和SerializedProperty来获取和设置数据。

图片.png


using UnityEngine;
using UnityEditor.Experimental.AssetImporters;
using System.IO;

[ScriptedImporter(1, "jjj")]
public class Script_03_11 : ScriptedImporter
{
    public override void OnImportAsset(AssetImportContext ctx)
    {
        GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        Vector3 position = JsonUtility.FromJson<Vector3>(File.ReadAllText(ctx.assetPath));

        cube.transform.position = position;
        cube.transform.localScale = Vector3.one;
        Material mat = new Material(Shader.Find("Standard"));
        mat.color = Color.green;
        ctx.AddObjectToAsset("material", mat);
        cube.GetComponent<MeshRenderer>().material = mat;
        ctx.AddObjectToAsset("obj",cube);
        ctx.SetMainObject(cube);
    }
}


[ScriptedImporter(1, "jjj")] 表示自定义的资源后缀为jjj,导入该类型的文件时,就会执行OnInportAsset方法,创建一个Cube,位置信息使用自定义资源的json数据,赋值一个材质,材质需要保存起来,不然就会丢失。

图片.png


[MenuItem("Item/checked", false, 1012)]
public static void Checked()
{
    bool cked = Menu.GetChecked("Item/checked");
    Menu.SetChecked("Item/checked", !cked);
}


图片.png


//针对某个组件物体的ui
using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(Camera))]
public class Script_03_09 : Editor {

    private void OnSceneGUI()
    {
        Camera camera = target as Camera;
        if (camera != null)
        {
            Handles.color = Color.green;
            Handles.Label(camera.transform.position, camera.transform.position.ToString());
            Handles.BeginGUI();
            GUI.backgroundColor = Color.red;
            if (GUILayout.Button("click", GUILayout.Width(50)))
            {
                Debug.LogError("click:" + camera.name);
            }
            Handles.EndGUI();
        }
    }
}


图片.png


//常驻Scene视图的辅助ui
[InitializeOnLoadMethod]
static void InitializeOnLoadMethoda()
{
    SceneView.onSceneGUIDelegate = delegate (SceneView sceneView)
    {
        Handles.BeginGUI();
        GUILayout.Label("标题");
        GUILayout.Button("按钮");
        Handles.EndGUI();
    };
}

//放置在Editor文件夹内
using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(Transform))]
public class Script_03_08 :Editor {

    public override void OnInspectorGUI()
    {
        if (GUILayout.Button("按钮一个"))
        {
        }
        base.OnInspectorGUI();
    }
}


图片.png

原有的结构被破坏了,可以通过反射获取原来的方法来执行,这样就不会破坏原有的绘制了。


using UnityEngine;
using UnityEditor;
using System.Reflection;

[CustomEditor(typeof(Transform))]
public class Script_03_08 :Editor {

    private Editor m_Editor;

    private void OnEnable()
    {
        m_Editor = Editor.CreateEditor(target,Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.TransformInspector",true));
    }

    public override void OnInspectorGUI()
    {
        if (GUILayout.Button("按钮一个"))
        {
        }
        m_Editor.OnInspectorGUI();
    }
}


图片.png


public class Rssting : MonoBehaviour {

    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawLine(transform.position, transform.TransformPoint(transform.up * 5));
        Gizmos.DrawCube(transform.position, Vector3.one * 2);
    }

    private void OnDrawGizmos()
    {
        Gizmos.DrawSphere(transform.position, 1);
    }
}


OnDrawGizmosSelected会在物体选中时执行,绘制辅助元素。OnDrawGizmos会在所有拥有这个脚本组件的物体上绘制辅助元素,不需要被选中。

图片.png

图片.png


using UnityEngine;
using UnityEditor;

public class Script_03_07 {

    [MenuItem("Window/Test/abc")]
    static void abc() { }

    [MenuItem("Window/Test/def")]
    static void def() { }

    [MenuItem("Window/Test/haha/jjj")]
    static void jjj() { }

    [InitializeOnLoadMethod]
    static void InitializeOnLoadMethod()
    {
        EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
    }

    static void OnHierarchyGUI(int instanceID, Rect rect)
    {
        if (Event.current != null && rect.Contains(Event.current.mousePosition) && Event.current.button == 1 && Event.current.type <= EventType.MouseUp)
        {
            GameObject selectedGameobject = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
            if (selectedGameobject)
            {
                Vector2 mousePosition = Event.current.mousePosition;
                EditorUtility.DisplayPopupMenu(new Rect(mousePosition.x, mousePosition.y, 0, 0), "Window/Test", null);
                Event.current.Use();
            }
        }
    }
}


通过Event.current获取当前的事件,判断事件发生的类型和事件发生的位置是在Hierarchy的物体上,就显示Window/Test下的菜单内容。Event.current.Use()表示不执行原有操作了。如果需要单单的扩展原右键菜单,只需要在GameObject主菜单目录下扩展你的菜单就行了。

图片.png


using UnityEngine;
using UnityEditor;

public class Script_03_06 {

    [InitializeOnLoadMethod] //Unity编译完后执行这个方法,添加监听
    static void InitializeLoadMethod()
    {
        EditorApplication.hierarchyWindowItemOnGUI = delegate (int instanceID,Rect rect)
        {
            if (Selection.activeObject && instanceID == Selection.activeObject.GetInstanceID())
            {
                float width = 50f;
                float height = 20f;
                rect.x += rect.width - width;
                rect.height = height;
                rect.width = width;
                if (GUI.Button(rect, AssetDatabase.LoadAssetAtPath<Texture>("Assets/1.png")))
                {
                    Undo.DestroyObjectImmediate(Selection.activeObject);
                }
            }
        };
    }
}


当选择hierarchy的物体时,右边会出现一个按钮,点击按钮后就会把选择的这个物体删除掉!


//脚本放在Editor文件夹中
using UnityEngine;
using UnityEditor;

public class Script_03_03  {

    [InitializeOnLoadMethod] //Unity编译后立刻执行这个方法,监听事件
    static void InitializeOnloadMethod()
    {
        Debug.LogError("编译后立刻执行");
        EditorApplication.projectWindowItemOnGUI = delegate (string guid, Rect selectionRect)
        {
            if (Selection.activeObject && guid == AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(Selection.activeObject)))
            {
                float width = 50f;
                selectionRect.x += (selectionRect.width - width) / 2;
                selectionRect.y = selectionRect.height / 4;
                selectionRect.width = width;
                selectionRect.height /= 2;
                GUI.color = Color.green;
                if (GUI.Button(selectionRect, "click")) {
                    Debug.LogError("click:" + Selection.activeObject.name);
                }
                GUI.color = Color.white;
            }
        };
    }
}


当你在Project中选中一个物体时,在会该物体的区域中绘制一个按钮,并且可以点击,点击后打印该物体的名字。

图片.png


using UnityEngine;
using UnityEditor;
using System.Collections;

public class RenderCubemapWizard : ScriptableWizard {
	
	public Transform renderFromPosition;
	public Cubemap cubemap;
	
	void OnWizardUpdate () {
		helpString = "Select transform to render from and cubemap to render into";
		isValid = (renderFromPosition != null) && (cubemap != null);
	}
	
	void OnWizardCreate () {
		// create temporary camera for rendering
		GameObject go = new GameObject( "CubemapCamera");
		go.AddComponent<Camera>();
		// place it on the object
		go.transform.position = renderFromPosition.position;
		// render into cubemap		
		go.GetComponent<Camera>().RenderToCubemap(cubemap);
		
		// destroy temporary camera
		DestroyImmediate( go );
	}
	
	[MenuItem("GameObject/Render into Cubemap")]
	static void RenderCubemap () {
		ScriptableWizard.DisplayWizard<RenderCubemapWizard>(
			"Render cubemap", "Render!");
	}
}


在指定位置上,创建一个摄像机,然后将它渲染的内容写入到cubemap中去,记得要开启cubemap的Readable。