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来获取和设置数据。
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数据,赋值一个材质,材质需要保存起来,不然就会丢失。
[MenuItem("Item/checked", false, 1012)] public static void Checked() { bool cked = Menu.GetChecked("Item/checked"); Menu.SetChecked("Item/checked", !cked); }
//针对某个组件物体的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(); } } }
//常驻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(); } }
原有的结构被破坏了,可以通过反射获取原来的方法来执行,这样就不会破坏原有的绘制了。
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(); } }
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会在所有拥有这个脚本组件的物体上绘制辅助元素,不需要被选中。
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主菜单目录下扩展你的菜单就行了。
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中选中一个物体时,在会该物体的区域中绘制一个按钮,并且可以点击,点击后打印该物体的名字。
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。