一. 编辑器下复制Component的快捷方式: UnityEditorInternal.ComponentUtility.CopyComponent(from); UnityEditorInternal.ComponentUtility.PasteComponentValues(to); UnityEditorInternal.ComponentUtility.PasteComponentAsNew(gameObject);
二. 创建UI节点的方式: new GameObject("Name", typeof(RectTransform)); // 这样才会给你创建RectTransform
三. 获取BuildSettings里面场景的信息方式: var scenes = UnityEditor.EditorBuildSettings.scenes; var activeScenes = UnityEditor.EditorBuildSettingsScene.GetActiveSceneList(scenes );
四. 任意位置的选择菜单: UnityEditor.EditorUtility.DisplayCustomMenu -- 指定位置出现菜单 UnityEditor.GenericMenu -- 在当前鼠标位置出现
五. 初始化顺序: 场景读取以及场景中的脚本的初始化顺序如下 1. Awake 2. UnityEngine.SceneManagement.SceneManager.sceneLoaded 3. Start
六. 关于CustomPropertyDrawer的使用, 下面有个例子: using System; using UnityEditor; using UnityEngine; public class EnumFlagAttribute : UnityEngine.PropertyAttribute { public EnumFlagAttribute() {} } [CustomPropertyDrawer(typeof(EnumFlagAttribute))] public class EnumFlagsAttributeDrawer : PropertyDrawer { public override void OnGUI(Rect _position, SerializedProperty _property, GUIContent _label) { int buttonsIntValue = 0; int enumLength = _property.enumNames.Length; bool[] buttonPressed = new bool[enumLength]; float buttonWidth = (_position.width - EditorGUIUtility.labelWidth) / enumLength; EditorGUI.LabelField(new Rect(_position.x, _position.y, EditorGUIUtility.labelWidth, _position.height), _label); EditorGUI.BeginChangeCheck (); for (int i = 0; i < enumLength; i++) { // Check if the button is/was pressed if ( ( _property.intValue & (1 << i) ) == 1 << i ) { buttonPressed[i] = true; } Rect buttonPos = new Rect (_position.x + EditorGUIUtility.labelWidth + buttonWidth * i, _position.y, buttonWidth, _position.height); buttonPressed[i] = GUI.Toggle(buttonPos, buttonPressed[i], _property.enumNames[i], "Button"); if (buttonPressed[i]) buttonsIntValue += 1 << i; } if (EditorGUI.EndChangeCheck()) { _property.intValue = buttonsIntValue; } } } 给Enum变量添加这个属性之后, 就会被按照代码的方式进行绘制(Inspector) 七. 入口函数是可以做的, 使用属性 [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] 被标记的静态函数会在程序启动后第一个调用, 如果打包之后没有打包场景的情况下, Unity会自动生成一个默认场景, 这样在这个函数里读取场景的话, 应该就能把自动生成的 场景给顶掉. 八. 菜单的Toggle方式 const string T1Name = "Tools/Test/TT/T1"; private static bool selected = false;
[MenuItem(T1Name, true, 105)] public static bool T1_Init() { Menu.SetChecked(T1Name, selected); return true; }
[MenuItem(T1Name, false, 105)] public static void T1_Func() { selected = false == selected; Menu.SetChecked(T1Name, selected); } 想要给一个菜单提供Toggle的可视化, 需要使用两个函数, 一个是Init就是在每次菜单展开 之前都会调用一次, 然后Menu.SetChecked标记这个菜单的Toggle UI, 每次点击则进入 T1_Func函数, 九. 在有自动布局组件的时候(UnityEngine.UI.LayoutGroup) 可能是 HorizontalLayoutGroup, VerticalLayoutGroup, Grid 等, 在重新设置了里面的元素之后, 它不会自动刷新, 需要手动调用 LayoutRebuilder.ForceRebuildLayoutImmediate(rect); PS : 在很多情况下, 这个函数也不是那么好用的, 实际情况还是需要 关闭-打开 组件的 方式才能正确让它重排, 我要吐血了, 测试了很多方法, 只有下面这类的才能正确排列 // Do Sth Core.CoroutineRoot.Instance.RunWaitFrames(2, () => { this.transform.LoopComponentsInChildren<LayoutGroup>((_group) => { _group.enabled = false; _group.enabled = true; }); LayoutRebuilder.ForceRebuildLayoutImmediate(this.rect); });
|