关注

如何使用脚本修改编辑器的窗口布局

问题

  • 编辑器没有提供公共的API来修改窗口布局。

原因

公共的API没有提供任何修改编辑器窗口布局的方法。但可以用System.ReflectionUnityEditor两个命名空间来保存并读取编辑器布局。

解决方案

UnityEditor.WindowLayout 有两个函数,可以用来保存和读取窗口布局: SaveWindowLayoutLoadWindowLayout

using UnityEditor;
using System.IO;
using System.Reflection;
using Type = System.Type;

public static class LayoutUtility {

	private static MethodInfo _miLoadWindowLayout;
	private static MethodInfo _miSaveWindowLayout;
	private static MethodInfo _miReloadWindowLayoutMenu;
	private static bool _available;
	private static string _layoutsPath;

	static LayoutUtility() {
		Type tyWindowLayout = Type.GetType("UnityEditor.WindowLayout,UnityEditor");
		Type tyEditorUtility = Type.GetType("UnityEditor.EditorUtility,UnityEditor");
		Type tyInternalEditorUtility = Type.GetType("UnityEditorInternal.InternalEditorUtility,UnityEditor");
		if (tyWindowLayout != null && tyEditorUtility != null && tyInternalEditorUtility != null) {
			MethodInfo miGetLayoutsPath = tyWindowLayout.GetMethod("GetLayoutsPath", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
			_miLoadWindowLayout = tyWindowLayout.GetMethod("LoadWindowLayout", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string), typeof(bool) }, null);
			_miSaveWindowLayout = tyWindowLayout.GetMethod("SaveWindowLayout", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string) }, null);
			_miReloadWindowLayoutMenu = tyInternalEditorUtility.GetMethod("ReloadWindowLayoutMenu", BindingFlags.Public | BindingFlags.Static);

			if (miGetLayoutsPath == null || _miLoadWindowLayout == null || _miSaveWindowLayout == null || _miReloadWindowLayoutMenu == null)
				return;

			_layoutsPath = (string)miGetLayoutsPath.Invoke(null, null);
			if (string.IsNullOrEmpty(_layoutsPath))
				return;

			_available = true;
		}
	}

	// Gets a value indicating whether all required Unity API functionality is available for usage.
	public static bool IsAvailable {
		get { return _available; }
	}

	// Gets absolute path of layouts directory. Returns `null` when not available.
	public static string LayoutsPath {
		get { return _layoutsPath; }
	}

	// Save current window layout to asset file. `assetPath` must be relative to project directory.
	public static void SaveLayoutToAsset(string assetPath) {
		SaveLayout(Path.Combine(Directory.GetCurrentDirectory(), assetPath));
	}

	// Load window layout from asset file. `assetPath` must be relative to project directory.
	public static void LoadLayoutFromAsset(string assetPath) {
		if (_miLoadWindowLayout != null) {
			string path = Path.Combine(Directory.GetCurrentDirectory(), assetPath);
			_miLoadWindowLayout.Invoke(null, new object[] { path , true });
		}
	}

	// Save current window layout to file. `path` must be absolute.
	public static void SaveLayout(string path) {
		if (_miSaveWindowLayout != null)
			_miSaveWindowLayout.Invoke(null, new object[] { path });
	}
}

更多信息

http://answers.unity3d.com/questions/382973/programmatically-change-editor-layout.html

https://github.com/MattRix/UnityDecompiled/blob/master/UnityEditor/UnityEditor/WindowLayout.cs

本文适用于Unity 5.3版本

这篇文章有帮助吗?
0 人中有 0 人觉得有帮助
还有其它问题?提交请求

0 评论

登录写评论。