From edc5eb693ace3c32d7fdeb7b1e4f0abc0092ca30 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期一, 26 五月 2025 15:55:34 +0800
Subject: [PATCH] 18 子 2D卡牌客户端搭建 / 2D卡牌客户端搭建 必备窗口更新&常用组件移植

---
 Assets/Editor/ScriptEditor/ScaleTweenEditor.cs             |   19 +
 Assets/Editor/ScriptEditor/PositionTweenEditor.cs          |   20 +
 Assets/Editor/ScriptEditor/TweenEditor.cs                  |   38 ++
 Assets/Editor/ScriptEditor.meta                            |    8 
 Assets/Editor/ScriptEditor/SecondFrameLoaderEditor.cs.meta |   11 
 Assets/Editor/ScriptEditor/RotationTweenEditor.cs.meta     |   11 
 Assets/Editor/ScriptEditor/TextImageEditor.cs.meta         |   11 
 Assets/Editor/ScriptEditor/TextImageEditor.cs              |   27 +
 Assets/Editor/ScriptEditor/RotationTweenEditor.cs          |   19 +
 Assets/Editor/ScriptEditor/PositionTweenEditor.cs.meta     |   11 
 Assets/Editor/InvalidScriptScanner.cs                      |  560 ++++++++++++++++++++++++++++++++++++++++
 Assets/Editor/ScriptEditor/SecondFrameLoaderEditor.cs      |   31 ++
 Assets/Editor/InvalidScriptScanner.cs.meta                 |   11 
 Assets/Editor/ScriptEditor/ScaleTweenEditor.cs.meta        |   11 
 Assets/Editor/ScriptEditor/TweenEditor.cs.meta             |   11 
 15 files changed, 799 insertions(+), 0 deletions(-)

diff --git a/Assets/Editor/InvalidScriptScanner.cs b/Assets/Editor/InvalidScriptScanner.cs
new file mode 100644
index 0000000..f2a324b
--- /dev/null
+++ b/Assets/Editor/InvalidScriptScanner.cs
@@ -0,0 +1,560 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System;
+
+/// <summary>
+/// 鎵弿 GameObject 涓殑鏃犳晥鑴氭湰鐨勭紪杈戝櫒宸ュ叿
+/// </summary>
+public class InvalidScriptScanner : EditorWindow
+{
+    // 鎵弿妯″紡鏋氫妇
+    private enum ScanMode
+    {
+        Basic,      // 鍩烘湰鎵弿
+        Advanced,   // 楂樼骇鎵弿
+        Deep        // 娣卞害鎵弿
+    }
+    
+    // 褰撳墠鎵弿妯″紡
+    private static ScanMode currentScanMode = ScanMode.Advanced;
+    
+    /// <summary>
+    /// 娣诲姞鍙抽敭鑿滃崟椤�
+    /// </summary>
+    [MenuItem("GameObject/鎵弿鏃犳晥鑴氭湰", false, 20)]
+    private static void ScanInvalidScripts()
+    {
+        GameObject selectedObject = Selection.activeGameObject;
+        if (selectedObject == null)
+        {
+            EditorUtility.DisplayDialog("閿欒", "璇峰厛閫夋嫨涓�涓父鎴忓璞�", "纭畾");
+            return;
+        }
+
+        // 浣跨敤鏀硅繘鐨勬柟娉曟娴嬫棤鏁堣剼鏈�
+        List<int> invalidScriptIndices = FindInvalidScripts(selectedObject);
+
+        if (invalidScriptIndices.Count > 0)
+        {
+            // 鎵惧埌浜嗘棤鏁堣剼鏈�
+            int invalidScriptIndex = invalidScriptIndices[0]; // 鑾峰彇绗竴涓棤鏁堣剼鏈�
+            Debug.LogWarning($"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 涓婂彂鐜版棤鏁堣剼鏈紝浣嶄簬缁勪欢绱㈠紩 {invalidScriptIndex}");
+            
+            // 楂樹寒鏄剧ず璇ュ璞�
+            Selection.activeGameObject = selectedObject;
+            
+            // 鎵撳紑妫�鏌ュ櫒骞舵粴鍔ㄥ埌璇ョ粍浠�
+            EditorGUIUtility.PingObject(selectedObject);
+            
+            // 鏄剧ず瀵硅瘽妗�
+            if (EditorUtility.DisplayDialog("鍙戠幇鏃犳晥鑴氭湰", 
+                $"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 涓婂彂鐜版棤鏁堣剼鏈紝浣嶄簬缁勪欢绱㈠紩 {invalidScriptIndex}銆俓n\n鏄惁瑕佺Щ闄よ鏃犳晥鑴氭湰锛�", 
+                "绉婚櫎", "鍙栨秷"))
+            {
+                // 绉婚櫎鏃犳晥鑴氭湰
+                RemoveInvalidScript(selectedObject, invalidScriptIndex);
+            }
+        }
+        else
+        {
+            // 鏈壘鍒版棤鏁堣剼鏈紝灏濊瘯鏇存繁灞傛鐨勬壂鎻�
+            if (currentScanMode != ScanMode.Deep)
+            {
+                if (EditorUtility.DisplayDialog("鏈壘鍒版棤鏁堣剼鏈�", 
+                    $"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 涓婃湭鍙戠幇鏃犳晥鑴氭湰銆俓n\n鏄惁瑕佸皾璇曟繁搴︽壂鎻忥紵杩欏彲鑳介渶瑕佹洿闀挎椂闂淬��", 
+                    "娣卞害鎵弿", "鍙栨秷"))
+                {
+                    // 涓存椂鍒囨崲鍒版繁搴︽壂鎻忔ā寮�
+                    ScanMode previousMode = currentScanMode;
+                    currentScanMode = ScanMode.Deep;
+                    
+                    // 閲嶆柊鎵弿
+                    invalidScriptIndices = FindInvalidScripts(selectedObject);
+                    
+                    // 鎭㈠涔嬪墠鐨勬壂鎻忔ā寮�
+                    currentScanMode = previousMode;
+                    
+                    if (invalidScriptIndices.Count > 0)
+                    {
+                        // 鎵惧埌浜嗘棤鏁堣剼鏈�
+                        int invalidScriptIndex = invalidScriptIndices[0];
+                        Debug.LogWarning($"娣卞害鎵弿锛氬湪娓告垙瀵硅薄 '{selectedObject.name}' 涓婂彂鐜版棤鏁堣剼鏈紝浣嶄簬缁勪欢绱㈠紩 {invalidScriptIndex}");
+                        
+                        // 鏄剧ず瀵硅瘽妗�
+                        if (EditorUtility.DisplayDialog("娣卞害鎵弿鍙戠幇鏃犳晥鑴氭湰", 
+                            $"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 涓婂彂鐜版棤鏁堣剼鏈紝浣嶄簬缁勪欢绱㈠紩 {invalidScriptIndex}銆俓n\n鏄惁瑕佺Щ闄よ鏃犳晥鑴氭湰锛�", 
+                            "绉婚櫎", "鍙栨秷"))
+                        {
+                            // 绉婚櫎鏃犳晥鑴氭湰
+                            RemoveInvalidScript(selectedObject, invalidScriptIndex);
+                        }
+                    }
+                    else
+                    {
+                        // 娣卞害鎵弿涔熸湭鎵惧埌鏃犳晥鑴氭湰
+                        EditorUtility.DisplayDialog("娣卞害鎵弿瀹屾垚", $"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 涓婃湭鍙戠幇鏃犳晥鑴氭湰銆�", "纭畾");
+                    }
+                }
+                else
+                {
+                    // 鐢ㄦ埛鍙栨秷娣卞害鎵弿
+                    EditorUtility.DisplayDialog("鎵弿瀹屾垚", $"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 涓婃湭鍙戠幇鏃犳晥鑴氭湰銆�", "纭畾");
+                }
+            }
+            else
+            {
+                // 宸茬粡鏄繁搴︽壂鎻忔ā寮�
+                EditorUtility.DisplayDialog("鎵弿瀹屾垚", $"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 涓婃湭鍙戠幇鏃犳晥鑴氭湰銆�", "纭畾");
+            }
+        }
+    }
+
+    /// <summary>
+    /// 鏌ユ壘鏃犳晥鑴氭湰
+    /// </summary>
+    /// <param name="gameObject">瑕佹鏌ョ殑娓告垙瀵硅薄</param>
+    /// <returns>鏃犳晥鑴氭湰鐨勭储寮曞垪琛�</returns>
+    private static List<int> FindInvalidScripts(GameObject gameObject)
+    {
+        List<int> invalidIndices = new List<int>();
+        
+        // 妫�鏌ユ父鎴忓璞℃槸鍚︽湁鏁�
+        if (gameObject == null)
+            return invalidIndices;
+            
+        // 鏂规硶1锛氫娇鐢� SerializedObject 妫�鏌ョ粍浠�
+        SerializedObject serializedObject = new SerializedObject(gameObject);
+        SerializedProperty componentsProperty = serializedObject.FindProperty("m_Component");
+        
+        for (int i = 0; i < componentsProperty.arraySize; i++)
+        {
+            SerializedProperty componentProperty = componentsProperty.GetArrayElementAtIndex(i);
+            SerializedProperty scriptProperty = componentProperty.FindPropertyRelative("component");
+            
+            // 妫�鏌ヨ剼鏈紩鐢ㄦ槸鍚︽湁鏁�
+            if (scriptProperty.objectReferenceValue == null || scriptProperty.objectReferenceInstanceIDValue == 0)
+            {
+                invalidIndices.Add(i);
+                continue;
+            }
+            
+            // 棰濆妫�鏌ワ細灏濊瘯鑾峰彇瀹為檯缁勪欢骞舵鏌ュ叾绫诲瀷
+            UnityEngine.Object scriptObject = scriptProperty.objectReferenceValue;
+            if (scriptObject != null)
+            {
+                // 妫�鏌ヨ剼鏈槸鍚︿负缂哄け鎴栨崯鍧忕殑 MonoScript
+                MonoScript monoScript = scriptObject as MonoScript;
+                if (monoScript != null && monoScript.GetClass() == null)
+                {
+                    invalidIndices.Add(i);
+                    continue;
+                }
+                
+                // 楂樼骇鎵弿锛氭鏌ョ粍浠舵槸鍚﹀彲浠ユ纭簭鍒楀寲
+                if (currentScanMode >= ScanMode.Advanced)
+                {
+                    try
+                    {
+                        // 灏濊瘯鑾峰彇缁勪欢鐨勭被鍨�
+                        Type componentType = scriptObject.GetType();
+                        if (componentType == null || componentType.ToString().Contains("Missing") || componentType.ToString().Contains("missing"))
+                        {
+                            invalidIndices.Add(i);
+                            continue;
+                        }
+                    }
+                    catch (Exception)
+                    {
+                        // 濡傛灉鑾峰彇绫诲瀷鏃跺嚭鐜板紓甯革紝鍙兘鏄棤鏁堣剼鏈�
+                        invalidIndices.Add(i);
+                        continue;
+                    }
+                }
+            }
+        }
+        
+        // 鏂规硶2锛氫娇鐢� GetComponents 妫�鏌ョ粍浠讹紙鍙兘浼氭娴嬪埌涓�浜涙柟娉�1婕忔帀鐨勬儏鍐碉級
+        Component[] components = gameObject.GetComponents<Component>();
+        for (int i = 0; i < components.Length; i++)
+        {
+            if (components[i] == null)
+            {
+                // 妫�鏌ヨ繖涓储寮曟槸鍚﹀凡缁忓湪鍒楄〃涓�
+                if (!invalidIndices.Contains(i))
+                {
+                    invalidIndices.Add(i);
+                }
+                continue;
+            }
+            
+            // 娣卞害鎵弿锛氬皾璇曡闂粍浠剁殑涓�浜涘睘鎬э紝鐪嬫槸鍚︿細鎶涘嚭寮傚父
+            if (currentScanMode == ScanMode.Deep)
+            {
+                try
+                {
+                    // 灏濊瘯鑾峰彇缁勪欢鐨勫悕绉板拰鍚敤鐘舵��
+                    string name = components[i].name;
+                    bool enabled = false;
+                    
+                    // 灏濊瘯鑾峰彇鍚敤鐘舵�侊紙鍙 Behaviour 绫诲瀷鏈夋晥锛�
+                    if (components[i] is Behaviour behaviour)
+                    {
+                        enabled = behaviour.enabled;
+                    }
+                    
+                    // 灏濊瘯搴忓垪鍖栫粍浠�
+                    SerializedObject testSerializedObject = new SerializedObject(components[i]);
+                    SerializedProperty iterator = testSerializedObject.GetIterator();
+                    bool hasProperties = iterator.NextVisible(true);
+                    
+                    // 濡傛灉鏃犳硶鑾峰彇浠讳綍灞炴�э紝鍙兘鏄棤鏁堣剼鏈�
+                    if (!hasProperties && !invalidIndices.Contains(i))
+                    {
+                        invalidIndices.Add(i);
+                    }
+                }
+                catch (Exception)
+                {
+                    // 濡傛灉璁块棶缁勪欢灞炴�ф椂鍑虹幇寮傚父锛屽彲鑳芥槸鏃犳晥鑴氭湰
+                    if (!invalidIndices.Contains(i))
+                    {
+                        invalidIndices.Add(i);
+                    }
+                }
+            }
+        }
+        
+        // 妫�鏌ラ殣钘忕殑娓告垙瀵硅薄锛堝嵆浣挎槸闅愯棌鐨勶紝涔熷彲鑳藉寘鍚棤鏁堣剼鏈級
+        if (currentScanMode >= ScanMode.Advanced)
+        {
+            // 鑾峰彇鎵�鏈夐殣钘忕殑瀛愬璞�
+            Transform[] allChildren = gameObject.GetComponentsInChildren<Transform>(true);
+            foreach (Transform child in allChildren)
+            {
+                // 璺宠繃褰撳墠瀵硅薄锛堝洜涓哄凡缁忔鏌ヨ繃浜嗭級
+                if (child.gameObject == gameObject)
+                    continue;
+                    
+                // 濡傛灉瀛愬璞℃槸闅愯棌鐨勬垨鑰呯埗瀵硅薄鏄殣钘忕殑锛屽崟鐙鏌ュ畠
+                if (!child.gameObject.activeInHierarchy)
+                {
+                    // 閫掑綊妫�鏌ラ殣钘忕殑瀛愬璞�
+                    List<int> childInvalidIndices = FindInvalidScriptsInHiddenObject(child.gameObject);
+                    if (childInvalidIndices.Count > 0)
+                    {
+                        // 濡傛灉鍦ㄩ殣钘忕殑瀛愬璞′腑鎵惧埌浜嗘棤鏁堣剼鏈紝娣诲姞鍒扮粨鏋滀腑
+                        // 娉ㄦ剰锛氳繖閲屾垜浠彧鏄褰曚簡绱㈠紩锛屽疄闄呬笂闇�瑕佸湪UI涓樉绀哄畬鏁磋矾寰�
+                        foreach (int index in childInvalidIndices)
+                        {
+                            if (!invalidIndices.Contains(index))
+                            {
+                                invalidIndices.Add(index);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        
+        return invalidIndices;
+    }
+    
+    /// <summary>
+    /// 鍦ㄩ殣钘忕殑娓告垙瀵硅薄涓煡鎵炬棤鏁堣剼鏈�
+    /// </summary>
+    private static List<int> FindInvalidScriptsInHiddenObject(GameObject gameObject)
+    {
+        List<int> invalidIndices = new List<int>();
+        
+        // 妫�鏌ユ父鎴忓璞℃槸鍚︽湁鏁�
+        if (gameObject == null)
+            return invalidIndices;
+            
+        // 浣跨敤 SerializedObject 妫�鏌ョ粍浠�
+        SerializedObject serializedObject = new SerializedObject(gameObject);
+        SerializedProperty componentsProperty = serializedObject.FindProperty("m_Component");
+        
+        for (int i = 0; i < componentsProperty.arraySize; i++)
+        {
+            SerializedProperty componentProperty = componentsProperty.GetArrayElementAtIndex(i);
+            SerializedProperty scriptProperty = componentProperty.FindPropertyRelative("component");
+            
+            // 妫�鏌ヨ剼鏈紩鐢ㄦ槸鍚︽湁鏁�
+            if (scriptProperty.objectReferenceValue == null || scriptProperty.objectReferenceInstanceIDValue == 0)
+            {
+                invalidIndices.Add(i);
+            }
+        }
+        
+        return invalidIndices;
+    }
+
+    /// <summary>
+    /// 绉婚櫎鏃犳晥鑴氭湰
+    /// </summary>
+    private static void RemoveInvalidScript(GameObject gameObject, int componentIndex)
+    {
+        SerializedObject serializedObject = new SerializedObject(gameObject);
+        SerializedProperty componentsProperty = serializedObject.FindProperty("m_Component");
+        
+        if (componentIndex >= 0 && componentIndex < componentsProperty.arraySize)
+        {
+            componentsProperty.DeleteArrayElementAtIndex(componentIndex);
+            serializedObject.ApplyModifiedProperties();
+            Debug.Log($"宸蹭粠娓告垙瀵硅薄 '{gameObject.name}' 绉婚櫎鏃犳晥鑴氭湰");
+        }
+    }
+
+    /// <summary>
+    /// 閫掑綊鎵弿鎵�鏈夊瓙瀵硅薄涓殑鏃犳晥鑴氭湰
+    /// </summary>
+    [MenuItem("GameObject/閫掑綊鎵弿鎵�鏈夋棤鏁堣剼鏈�", false, 21)]
+    private static void ScanAllInvalidScriptsRecursively()
+    {
+        GameObject selectedObject = Selection.activeGameObject;
+        if (selectedObject == null)
+        {
+            EditorUtility.DisplayDialog("閿欒", "璇峰厛閫夋嫨涓�涓父鎴忓璞�", "纭畾");
+            return;
+        }
+
+        List<KeyValuePair<GameObject, int>> invalidScripts = new List<KeyValuePair<GameObject, int>>();
+        ScanInvalidScriptsInChildren(selectedObject, invalidScripts);
+
+        if (invalidScripts.Count > 0)
+        {
+            // 鎵惧埌浜嗘棤鏁堣剼鏈�
+            Debug.LogWarning($"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 鍙婂叾瀛愬璞′腑鍙戠幇 {invalidScripts.Count} 涓棤鏁堣剼鏈�");
+            
+            // 鏄剧ず缁撴灉绐楀彛
+            InvalidScriptResultWindow.ShowWindow(invalidScripts);
+        }
+        else
+        {
+            // 鏈壘鍒版棤鏁堣剼鏈紝灏濊瘯鏇存繁灞傛鐨勬壂鎻�
+            if (currentScanMode != ScanMode.Deep)
+            {
+                if (EditorUtility.DisplayDialog("鏈壘鍒版棤鏁堣剼鏈�", 
+                    $"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 鍙婂叾瀛愬璞′腑鏈彂鐜版棤鏁堣剼鏈�俓n\n鏄惁瑕佸皾璇曟繁搴︽壂鎻忥紵杩欏彲鑳介渶瑕佹洿闀挎椂闂淬��", 
+                    "娣卞害鎵弿", "鍙栨秷"))
+                {
+                    // 涓存椂鍒囨崲鍒版繁搴︽壂鎻忔ā寮�
+                    ScanMode previousMode = currentScanMode;
+                    currentScanMode = ScanMode.Deep;
+                    
+                    // 閲嶆柊鎵弿
+                    invalidScripts.Clear();
+                    ScanInvalidScriptsInChildren(selectedObject, invalidScripts);
+                    
+                    // 鎭㈠涔嬪墠鐨勬壂鎻忔ā寮�
+                    currentScanMode = previousMode;
+                    
+                    if (invalidScripts.Count > 0)
+                    {
+                        // 鎵惧埌浜嗘棤鏁堣剼鏈�
+                        Debug.LogWarning($"娣卞害鎵弿锛氬湪娓告垙瀵硅薄 '{selectedObject.name}' 鍙婂叾瀛愬璞′腑鍙戠幇 {invalidScripts.Count} 涓棤鏁堣剼鏈�");
+                        
+                        // 鏄剧ず缁撴灉绐楀彛
+                        InvalidScriptResultWindow.ShowWindow(invalidScripts);
+                    }
+                    else
+                    {
+                        // 娣卞害鎵弿涔熸湭鎵惧埌鏃犳晥鑴氭湰
+                        EditorUtility.DisplayDialog("娣卞害鎵弿瀹屾垚", $"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 鍙婂叾瀛愬璞′腑鏈彂鐜版棤鏁堣剼鏈��", "纭畾");
+                    }
+                }
+                else
+                {
+                    // 鐢ㄦ埛鍙栨秷娣卞害鎵弿
+                    EditorUtility.DisplayDialog("鎵弿瀹屾垚", $"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 鍙婂叾瀛愬璞′腑鏈彂鐜版棤鏁堣剼鏈��", "纭畾");
+                }
+            }
+            else
+            {
+                // 宸茬粡鏄繁搴︽壂鎻忔ā寮�
+                EditorUtility.DisplayDialog("鎵弿瀹屾垚", $"鍦ㄦ父鎴忓璞� '{selectedObject.name}' 鍙婂叾瀛愬璞′腑鏈彂鐜版棤鏁堣剼鏈��", "纭畾");
+            }
+        }
+    }
+
+    /// <summary>
+    /// 閫掑綊鎵弿瀛愬璞�
+    /// </summary>
+    private static void ScanInvalidScriptsInChildren(GameObject gameObject, List<KeyValuePair<GameObject, int>> results)
+    {
+        // 浣跨敤鏀硅繘鐨勬柟娉曟娴嬫棤鏁堣剼鏈�
+        List<int> invalidIndices = FindInvalidScripts(gameObject);
+        
+        // 娣诲姞鍒扮粨鏋滃垪琛�
+        foreach (int index in invalidIndices)
+        {
+            results.Add(new KeyValuePair<GameObject, int>(gameObject, index));
+        }
+
+        // 閫掑綊妫�鏌ユ墍鏈夊瓙瀵硅薄锛堝寘鎷殣钘忕殑锛�
+        foreach (Transform child in gameObject.transform)
+        {
+            ScanInvalidScriptsInChildren(child.gameObject, results);
+        }
+    }
+    
+    /// <summary>
+    /// 娣诲姞璁剧疆鑿滃崟椤�
+    /// </summary>
+    [MenuItem("GameObject/鏃犳晥鑴氭湰鎵弿璁剧疆", false, 22)]
+    private static void ShowSettings()
+    {
+        // 鍒涘缓璁剧疆绐楀彛
+        InvalidScriptScannerSettings.ShowWindow();
+    }
+}
+
+/// <summary>
+/// 鏃犳晥鑴氭湰鎵弿璁剧疆绐楀彛
+/// </summary>
+public class InvalidScriptScannerSettings : EditorWindow
+{
+    private static string[] scanModeNames = { "鍩烘湰鎵弿", "楂樼骇鎵弿", "娣卞害鎵弿" };
+    
+    public static void ShowWindow()
+    {
+        InvalidScriptScannerSettings window = GetWindow<InvalidScriptScannerSettings>("鏃犳晥鑴氭湰鎵弿璁剧疆");
+        window.minSize = new Vector2(300, 150);
+        window.Show();
+    }
+    
+    private void OnGUI()
+    {
+        EditorGUILayout.LabelField("鎵弿璁剧疆", EditorStyles.boldLabel);
+        EditorGUILayout.Space();
+        
+        // 鑾峰彇褰撳墠鎵弿妯″紡
+        int currentMode = (int)typeof(InvalidScriptScanner).GetField("currentScanMode", 
+            BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
+        
+        // 鏄剧ず鎵弿妯″紡閫夋嫨
+        int newMode = EditorGUILayout.Popup("鎵弿妯″紡", currentMode, scanModeNames);
+        
+        // 濡傛灉妯″紡鍙戠敓鍙樺寲锛屾洿鏂拌缃�
+        if (newMode != currentMode)
+        {
+            typeof(InvalidScriptScanner).GetField("currentScanMode", 
+                BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, newMode);
+        }
+        
+        EditorGUILayout.Space();
+        EditorGUILayout.HelpBox("鎵弿妯″紡璇存槑锛歕n" +
+            "鍩烘湰鎵弿锛氬彧妫�鏌ユ槑鏄剧殑鏃犳晥鑴氭湰\n" +
+            "楂樼骇鎵弿锛氭鏌ユ洿澶氱被鍨嬬殑鏃犳晥鑴氭湰锛屽寘鎷殣钘忓璞n" +
+            "娣卞害鎵弿锛氳繘琛屾渶褰诲簳鐨勬鏌ワ紝浣嗗彲鑳借緝鎱�", MessageType.Info);
+    }
+}
+
+/// <summary>
+/// 鏃犳晥鑴氭湰缁撴灉绐楀彛
+/// </summary>
+public class InvalidScriptResultWindow : EditorWindow
+{
+    private List<KeyValuePair<GameObject, int>> invalidScripts;
+    private Vector2 scrollPosition;
+
+    public static void ShowWindow(List<KeyValuePair<GameObject, int>> scripts)
+    {
+        InvalidScriptResultWindow window = GetWindow<InvalidScriptResultWindow>("鏃犳晥鑴氭湰鎵弿缁撴灉");
+        window.invalidScripts = scripts;
+        window.minSize = new Vector2(400, 300);
+        window.Show();
+    }
+
+    private void OnGUI()
+    {
+        if (invalidScripts == null || invalidScripts.Count == 0)
+        {
+            EditorGUILayout.LabelField("娌℃湁鍙戠幇鏃犳晥鑴氭湰");
+            return;
+        }
+
+        EditorGUILayout.LabelField($"鍙戠幇 {invalidScripts.Count} 涓棤鏁堣剼鏈�", EditorStyles.boldLabel);
+        EditorGUILayout.Space();
+
+        if (GUILayout.Button("绉婚櫎鎵�鏈夋棤鏁堣剼鏈�"))
+        {
+            if (EditorUtility.DisplayDialog("纭", "纭畾瑕佺Щ闄ゆ墍鏈夋棤鏁堣剼鏈悧锛�", "纭畾", "鍙栨秷"))
+            {
+                RemoveAllInvalidScripts();
+            }
+        }
+
+        EditorGUILayout.Space();
+        scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
+
+        for (int i = 0; i < invalidScripts.Count; i++)
+        {
+            EditorGUILayout.BeginHorizontal();
+            
+            if (GUILayout.Button("閫夋嫨", GUILayout.Width(60)))
+            {
+                Selection.activeGameObject = invalidScripts[i].Key;
+                EditorGUIUtility.PingObject(invalidScripts[i].Key);
+            }
+            
+            EditorGUILayout.ObjectField(invalidScripts[i].Key, typeof(GameObject), true);
+            
+            EditorGUILayout.LabelField($"缁勪欢绱㈠紩: {invalidScripts[i].Value}", GUILayout.Width(100));
+            
+            if (GUILayout.Button("绉婚櫎", GUILayout.Width(60)))
+            {
+                RemoveInvalidScript(invalidScripts[i].Key, invalidScripts[i].Value);
+                invalidScripts.RemoveAt(i);
+                i--;
+                GUIUtility.ExitGUI();
+            }
+            
+            EditorGUILayout.EndHorizontal();
+        }
+
+        EditorGUILayout.EndScrollView();
+    }
+
+    /// <summary>
+    /// 绉婚櫎鏃犳晥鑴氭湰
+    /// </summary>
+    private void RemoveInvalidScript(GameObject gameObject, int componentIndex)
+    {
+        SerializedObject serializedObject = new SerializedObject(gameObject);
+        SerializedProperty componentsProperty = serializedObject.FindProperty("m_Component");
+        
+        if (componentIndex >= 0 && componentIndex < componentsProperty.arraySize)
+        {
+            componentsProperty.DeleteArrayElementAtIndex(componentIndex);
+            serializedObject.ApplyModifiedProperties();
+            Debug.Log($"宸蹭粠娓告垙瀵硅薄 '{gameObject.name}' 绉婚櫎鏃犳晥鑴氭湰");
+        }
+    }
+
+    /// <summary>
+    /// 绉婚櫎鎵�鏈夋棤鏁堣剼鏈�
+    /// </summary>
+    private void RemoveAllInvalidScripts()
+    {
+        // 鍒涘缓涓�涓壇鏈紝鍥犱负鎴戜滑浼氬湪寰幆涓慨鏀瑰師濮嬪垪琛�
+        var scripts = new List<KeyValuePair<GameObject, int>>(invalidScripts);
+        
+        // 鎸夌収缁勪欢绱㈠紩浠庡ぇ鍒板皬鎺掑簭锛岃繖鏍峰垹闄ゆ椂涓嶄細褰卞搷鍏朵粬缁勪欢鐨勭储寮�
+        scripts = scripts.OrderByDescending(pair => pair.Value)
+                         .GroupBy(pair => pair.Key)
+                         .SelectMany(group => group.OrderByDescending(pair => pair.Value))
+                         .ToList();
+        
+        foreach (var pair in scripts)
+        {
+            RemoveInvalidScript(pair.Key, pair.Value);
+        }
+        
+        invalidScripts.Clear();
+        Repaint();
+    }
+}
\ No newline at end of file
diff --git a/Assets/Editor/InvalidScriptScanner.cs.meta b/Assets/Editor/InvalidScriptScanner.cs.meta
new file mode 100644
index 0000000..4e2b012
--- /dev/null
+++ b/Assets/Editor/InvalidScriptScanner.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e6c90377d2aed5d4a93122a96021bcdb
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Editor/ScriptEditor.meta b/Assets/Editor/ScriptEditor.meta
new file mode 100644
index 0000000..b3ba66d
--- /dev/null
+++ b/Assets/Editor/ScriptEditor.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7755da5fc71d4014ba3d1af2c458a241
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Editor/ScriptEditor/PositionTweenEditor.cs b/Assets/Editor/ScriptEditor/PositionTweenEditor.cs
new file mode 100644
index 0000000..d9807a9
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/PositionTweenEditor.cs
@@ -0,0 +1,20 @@
+锘�//--------------------------------------------------------
+//    [Author]:           绗簩涓栫晫
+//    [  Date ]:           Wednesday, January 10, 2018
+//--------------------------------------------------------
+using UnityEditor;
+using vnxbqy.UI;
+
+[CustomEditor(typeof(PositionTween))]
+public class PositionTweenEditor : TweenEditor
+{
+    public override void OnInspectorGUI()
+    {
+        base.OnInspectorGUI();
+    }
+
+}
+
+
+
+
diff --git a/Assets/Editor/ScriptEditor/PositionTweenEditor.cs.meta b/Assets/Editor/ScriptEditor/PositionTweenEditor.cs.meta
new file mode 100644
index 0000000..c935599
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/PositionTweenEditor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3c5bc6f0323f3ec428e45e295b378069
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Editor/ScriptEditor/RotationTweenEditor.cs b/Assets/Editor/ScriptEditor/RotationTweenEditor.cs
new file mode 100644
index 0000000..06bfd02
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/RotationTweenEditor.cs
@@ -0,0 +1,19 @@
+锘�//--------------------------------------------------------
+//    [Author]:           绗簩涓栫晫
+//    [  Date ]:           Wednesday, January 10, 2018
+//--------------------------------------------------------
+using UnityEditor;
+using vnxbqy.UI;
+
+[CustomEditor(typeof(RotationTween))]
+public class RotationTweenEditor : TweenEditor
+{
+    public override void OnInspectorGUI()
+    {
+        base.OnInspectorGUI();
+    }
+
+}
+
+
+
diff --git a/Assets/Editor/ScriptEditor/RotationTweenEditor.cs.meta b/Assets/Editor/ScriptEditor/RotationTweenEditor.cs.meta
new file mode 100644
index 0000000..57930f3
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/RotationTweenEditor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 216f06bf51951b347a17be03268a3ee5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Editor/ScriptEditor/ScaleTweenEditor.cs b/Assets/Editor/ScriptEditor/ScaleTweenEditor.cs
new file mode 100644
index 0000000..0201ac5
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/ScaleTweenEditor.cs
@@ -0,0 +1,19 @@
+锘�//--------------------------------------------------------
+//    [Author]:           绗簩涓栫晫
+//    [  Date ]:           Wednesday, January 10, 2018
+//--------------------------------------------------------
+using UnityEditor;
+using vnxbqy.UI;
+
+[CustomEditor(typeof(ScaleTween))]
+public class ScaleTweenEditor : TweenEditor
+{
+    public override void OnInspectorGUI()
+    {
+        base.OnInspectorGUI();
+    }
+
+}
+
+
+
diff --git a/Assets/Editor/ScriptEditor/ScaleTweenEditor.cs.meta b/Assets/Editor/ScriptEditor/ScaleTweenEditor.cs.meta
new file mode 100644
index 0000000..26eca33
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/ScaleTweenEditor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5f70a43de122a8d4c9893e5c40abdf4d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Editor/ScriptEditor/SecondFrameLoaderEditor.cs b/Assets/Editor/ScriptEditor/SecondFrameLoaderEditor.cs
new file mode 100644
index 0000000..ddb396f
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/SecondFrameLoaderEditor.cs
@@ -0,0 +1,31 @@
+
+using vnxbqy.UI;
+using UnityEditor;
+using UnityEngine;
+
+[CustomEditor(typeof(SecondFrameLoader2))]
+public class SecondFrameLoaderEditor : Editor
+{
+
+    SecondFrameLoader2 loader;
+
+    private void OnEnable()
+    {
+        loader = target as SecondFrameLoader2;
+    }
+
+    public override void OnInspectorGUI()
+    {
+        EditorGUILayout.Space(10);
+        loader.m_TitleKey = EditorGUILayout.TextField("Title Key", loader.m_TitleKey);
+        loader.frameSize = (FrameSize)EditorGUILayout.EnumPopup("Size", loader.frameSize);
+        if (loader.frameSize == FrameSize.Free)
+            loader.size = EditorGUILayout.Vector2Field("WH", loader.size);
+        EditorGUILayout.Space(10);
+        if (GUILayout.Button("鍒锋柊"))
+        {
+            loader.Reload();
+        }
+    }
+
+}
diff --git a/Assets/Editor/ScriptEditor/SecondFrameLoaderEditor.cs.meta b/Assets/Editor/ScriptEditor/SecondFrameLoaderEditor.cs.meta
new file mode 100644
index 0000000..76a5e54
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/SecondFrameLoaderEditor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 66b3b7fa32d7f924f9746bf6671cb74e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Editor/ScriptEditor/TextImageEditor.cs b/Assets/Editor/ScriptEditor/TextImageEditor.cs
new file mode 100644
index 0000000..b1c15c2
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/TextImageEditor.cs
@@ -0,0 +1,27 @@
+锘縰sing System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+
+[CustomEditor(typeof(TextImage), true), CanEditMultipleObjects]
+public class TextImageEditor : TextExEditor
+{
+
+    SerializedProperty sprite;
+    protected override void OnEnable()
+    {
+        base.OnEnable();
+        sprite = serializedObject.FindProperty("m_Sprite");
+    }
+
+    public override void OnInspectorGUI()
+    {
+        base.OnInspectorGUI();
+        EditorGUILayout.Space();
+
+        EditorGUILayout.PropertyField(sprite);
+        base.serializedObject.ApplyModifiedProperties();
+    }
+
+
+}
diff --git a/Assets/Editor/ScriptEditor/TextImageEditor.cs.meta b/Assets/Editor/ScriptEditor/TextImageEditor.cs.meta
new file mode 100644
index 0000000..b233c0a
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/TextImageEditor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bcd486d4ab062ea48adeb7479aaa0b03
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Editor/ScriptEditor/TweenEditor.cs b/Assets/Editor/ScriptEditor/TweenEditor.cs
new file mode 100644
index 0000000..ffc9179
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/TweenEditor.cs
@@ -0,0 +1,38 @@
+锘�//--------------------------------------------------------
+//    [Author]:           绗簩涓栫晫
+//    [  Date ]:           Wednesday, January 10, 2018
+//--------------------------------------------------------
+using UnityEngine;
+using System.Collections;
+using UnityEditor;
+using vnxbqy.UI;
+
+[CustomEditor(typeof(Tween))]
+public class TweenEditor : Editor
+{
+
+    public override void OnInspectorGUI()
+    {
+        var tween = (Tween)target;
+
+        tween.curve = (TweenCurve)EditorGUILayout.ObjectField("鍔ㄧ敾鏇茬嚎", tween.curve, typeof(TweenCurve), true);
+        tween.from = EditorGUILayout.Vector3Field("寮�濮�", tween.from);
+        tween.to = EditorGUILayout.Vector3Field("缁撴潫", tween.to);
+        tween.delayMode = (Tween.DelayMode)EditorGUILayout.EnumPopup("寤惰繜鏂瑰紡", tween.delayMode);
+
+        if (tween.delayMode == Tween.DelayMode.Time)
+        {
+            tween.delay = EditorGUILayout.FloatField("寤惰繜鏃堕棿", tween.delay);
+        }
+        tween.duration = EditorGUILayout.FloatField("鍔ㄧ敾鏃堕棿", tween.duration);
+        tween.trigger = (Tween.Trigger)EditorGUILayout.EnumPopup("瑙﹀彂妯″紡", tween.trigger);
+        tween.wrapMode = (Tween.WrapMode)EditorGUILayout.EnumPopup("寰幆妯″紡", tween.wrapMode);
+        tween.reversal = EditorGUILayout.Toggle("鍙嶈浆", tween.reversal);
+    }
+
+
+}
+
+
+
+
diff --git a/Assets/Editor/ScriptEditor/TweenEditor.cs.meta b/Assets/Editor/ScriptEditor/TweenEditor.cs.meta
new file mode 100644
index 0000000..d4d7488
--- /dev/null
+++ b/Assets/Editor/ScriptEditor/TweenEditor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 20ec1c2948677624ca7adb020853524e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

--
Gitblit v1.8.0