using TFramework; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using UnityEditorInternal; using System.IO; using System.Text; namespace TFramework { [CustomEditor(typeof(UIBehaviour))] public class UIBehaviourInspector : TEditor { SerializedProperty m_id; SerializedProperty enableAnim; SerializedProperty m_uiAnimType; SerializedProperty isScriptUse; SerializedProperty variableInfos; SerializedProperty parnetPanel; Component[] behaviours; ReorderableList variableList; List anims = new List(); int select = 0; List parentPanles = new List(); int selectParent = -1; Dictionary scriptPathDic = new Dictionary(); string scriptText; const string INITFLGS = "base.OnInit();"; private void OnEnable() { m_id = serializedObject.FindProperty("m_id"); enableAnim = serializedObject.FindProperty("enableAnim"); m_uiAnimType = serializedObject.FindProperty("m_uiAnimType"); isScriptUse = serializedObject.FindProperty("isScriptUse"); variableInfos = serializedObject.FindProperty("variableInfos"); parnetPanel = serializedObject.FindProperty("parnetPanel"); if (string.IsNullOrEmpty(m_id.stringValue)) { (target as UIBehaviour).ResetID(); } anims.Add("None"); foreach (var item in GlobalTool.GetTypesInRunTimeAssemblies(type => (type.IsSubclassOf(typeof(UIAnimBase)) || (type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(UIAnimBase))) && type.IsClass && !type.IsAbstract && type.Name != typeof(UIAnimBase).Name)) { anims.Add(item.FullName); } behaviours = (target as UIBehaviour).GetComponents(); foreach (var item in GlobalTool.GetTypesInRunTimeAssemblies(type => (type.IsSubclassOf(typeof(BasePanel)) || (type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(BasePanel))) && type.IsClass && !type.IsAbstract && type.Name != typeof(BasePanel).Name)) { parentPanles.Add(item.FullName); string[] guids = AssetDatabase.FindAssets(item.Name + ".Designer t:Script"); if (guids.Length <= 0) guids = AssetDatabase.FindAssets(item.Name + " t:Script"); if (guids.Length > 0) { string scriptPath = AssetDatabase.GUIDToAssetPath(guids[0]); if (!scriptPathDic.ContainsKey(item.FullName)) scriptPathDic.Add(item.FullName, scriptPath); } } variableList = new ReorderableList(serializedObject, variableInfos, false, true, true, true); variableList.drawHeaderCallback = (rect) => { GUI.Label(rect, "绑定组件"); }; variableList.drawElementCallback = (rect, index, isActive, isFocused) => { SerializedProperty property = variableInfos.GetArrayElementAtIndex(index); SerializedProperty variableName = property.FindPropertyRelative("variableName"); SerializedProperty compentType = property.FindPropertyRelative("compentType"); float width = rect.width / 2; rect.width = 63; GUI.Label(rect, "变量名:"); rect.x += 63; rect.width = width - 63; string newName = EditorGUI.TextField(rect, variableName.stringValue); if (newName != variableName.stringValue) { if (!string.IsNullOrEmpty(compentType.stringValue)) { int indexPos = scriptText.IndexOf($"private {compentType.stringValue} {variableName.stringValue};"); if (indexPos == -1) { indexPos = scriptText.IndexOf("#endregion"); scriptText = scriptText.Insert(indexPos, $"private {compentType.stringValue} {newName};\n "); } else { scriptText = scriptText.Replace($"private {compentType.stringValue} {variableName.stringValue};", $"private {compentType.stringValue} {newName};"); } int initPos = scriptText.IndexOf($" {variableName.stringValue} = GetComponentInUIID<{compentType.stringValue}>(\"{m_id.stringValue}\");"); if (initPos == -1) { initPos = scriptText.IndexOf(INITFLGS) + INITFLGS.Length; scriptText = scriptText.Insert(initPos, $"\n {newName} = GetComponentInUIID<{compentType.stringValue}>(\"{m_id.stringValue}\");"); } else { scriptText = scriptText.Replace($" {variableName.stringValue} = GetComponentInUIID<{compentType.stringValue}>(\"{m_id.stringValue}\");", $" {newName} = GetComponentInUIID<{compentType.stringValue}>(\"{m_id.stringValue}\");"); } string path = Application.dataPath.Remove(Application.dataPath.LastIndexOf("Assets")); path += scriptPathDic[parnetPanel.stringValue]; StreamWriter baseWriter = new StreamWriter(path, false, UTF8Encoding.UTF8); baseWriter.Write(scriptText); baseWriter.Close(); AssetDatabase.Refresh(); } variableName.stringValue = newName; } rect.x += rect.width + 3; rect.width = 80; GUI.Label(rect, "组件类型:"); GenericMenu menu = new GenericMenu(); foreach (var item in behaviours) { menu.AddItem(new GUIContent(item.GetType().Name), compentType.stringValue == item.GetType().Name, () => { serializedObject.Update(); string oldType = compentType.stringValue; compentType.stringValue = item.GetType().Name; if (!variableName.stringValue.Contains(compentType.stringValue)) { variableName.stringValue += compentType.stringValue; } int index = scriptText.IndexOf($"private {oldType} {variableName.stringValue};"); if (index == -1) { index = scriptText.IndexOf("#endregion"); scriptText = scriptText.Insert(index, $"private {compentType.stringValue} {variableName.stringValue};\n "); } else { scriptText = scriptText.Replace($"private {oldType} {variableName.stringValue};", $"private {compentType.stringValue} {variableName.stringValue};"); } int initPos = scriptText.IndexOf($" {variableName.stringValue} = GetComponentInUIID<{oldType}>(\"{m_id.stringValue}\");"); if (initPos == -1) { initPos = scriptText.IndexOf(INITFLGS) + INITFLGS.Length; scriptText = scriptText.Insert(initPos, $"\n {variableName.stringValue} = GetComponentInUIID<{compentType.stringValue}>(\"{m_id.stringValue}\");"); } else { scriptText = scriptText.Replace($" {variableName.stringValue} = GetComponentInUIID<{oldType}>(\"{m_id.stringValue}\");", $" {variableName.stringValue} = GetComponentInUIID<{compentType.stringValue}>(\"{m_id.stringValue}\");"); } if (!scriptText.Contains($"using {item.GetType().Namespace};")) { scriptText = scriptText.Insert(0, $"using {item.GetType().Namespace};\n"); } string path = Application.dataPath.Remove(Application.dataPath.LastIndexOf("Assets")); path += scriptPathDic[parnetPanel.stringValue]; StreamWriter baseWriter = new StreamWriter(path, false, UTF8Encoding.UTF8); baseWriter.Write(scriptText); baseWriter.Close(); AssetDatabase.Refresh(); serializedObject.ApplyModifiedProperties(); }); } rect.x += 63; rect.width = width - 80; if (GUI.Button(rect, compentType.stringValue)) { menu.ShowAsContext(); } }; variableList.multiSelect = false; variableList.onAddCallback = (list) => { serializedObject.Update(); int newIndex = list.serializedProperty.arraySize; list.serializedProperty.InsertArrayElementAtIndex(newIndex); list.index = newIndex; SerializedProperty newItem = list.serializedProperty.GetArrayElementAtIndex(newIndex); newItem.FindPropertyRelative("variableName").stringValue = (target as UIBehaviour).gameObject.name + "_"; newItem.FindPropertyRelative("compentType").stringValue = "UIBehaviour"; serializedObject.ApplyModifiedProperties(); }; variableList.onRemoveCallback = (list) => { SerializedProperty property = variableInfos.GetArrayElementAtIndex(list.index); SerializedProperty variableName = property.FindPropertyRelative("variableName"); SerializedProperty compentType = property.FindPropertyRelative("compentType"); int index = scriptText.IndexOf($"private {compentType.stringValue} {variableName.stringValue};"); if (index != -1) scriptText = scriptText.Replace($"private {compentType.stringValue} {variableName.stringValue};\n ", ""); int initPos = scriptText.IndexOf($" {variableName.stringValue} = GetComponentInUIID<{compentType.stringValue}>(\"{m_id.stringValue}\");"); if (initPos != -1) { scriptText = scriptText.Replace($"\n {variableName.stringValue} = GetComponentInUIID<{compentType.stringValue}>(\"{m_id.stringValue}\");", ""); } string path = Application.dataPath.Remove(Application.dataPath.LastIndexOf("Assets")); path += scriptPathDic[parnetPanel.stringValue]; StreamWriter baseWriter = new StreamWriter(path, false, UTF8Encoding.UTF8); baseWriter.Write(scriptText); baseWriter.Close(); AssetDatabase.Refresh(); ReorderableList.defaultBehaviours.DoRemoveButton(list); }; if (!string.IsNullOrEmpty(parnetPanel.stringValue)) scriptText = AssetDatabase.LoadAssetAtPath(scriptPathDic[parnetPanel.stringValue]).text; } public override void OnInspectorGUI() { serializedObject.Update(); using (new EditorGUILayout.HorizontalScope()) { GUI.enabled = false; EditorGUILayout.PropertyField(m_id, new GUIContent("ID")); GUI.enabled = true; if(GUILayout.Button("重置",GUILayout.ExpandWidth(false))) { (target as UIBehaviour).ResetID(); } DrawGUILayoutCopyButton(m_id.stringValue); } EditorGUILayout.PropertyField(enableAnim, new GUIContent("启用动画")); if(enableAnim.boolValue) { select = anims.IndexOf(m_uiAnimType.stringValue); select = select == -1 ? 0 : select; int newSelect = EditorGUILayout.Popup("动画类型", select, anims.ToArray()); if(newSelect!=select) { m_uiAnimType.stringValue = anims[newSelect]; select = newSelect; } } EditorGUILayout.PropertyField(isScriptUse, new GUIContent("绑定脚本")); if(isScriptUse.boolValue) { using(new EditorGUILayout.VerticalScope("Box")) { selectParent = parentPanles.IndexOf(parnetPanel.stringValue); //selectParent = selectParent == -1 ? 0 : selectParent; int newParent = EditorGUILayout.Popup("绑定到面板", selectParent, parentPanles.ToArray()); if (newParent != selectParent) { parnetPanel.stringValue = parentPanles[newParent]; selectParent = newParent; scriptText = string.Empty; scriptText = AssetDatabase.LoadAssetAtPath(scriptPathDic[parnetPanel.stringValue]).text; } variableList.DoLayoutList(); } } serializedObject.ApplyModifiedProperties(); } } }