public override void OnPropertyDrawer(UnityEditor.SerializedProperty prop)
        {
            if (editorContent == null || string.IsNullOrEmpty(editorContent.text))
            {
                var name = UnityEditor.ObjectNames.NicifyVariableName(FieldName);
                editorContent = new GUIContent(name);
            }

            Type type;

            if (FieldType.StartsWith("CS."))
            {
                var typeName = FieldType.Substring(3);
                type = String2TypeCache.GetType(typeName);
            }
            else
            {
                type = typeof(LuaBinding);
            }
            UnityEditor.EditorGUI.BeginChangeCheck();
            UnityEditor.EditorGUILayout.ObjectField(prop, type, editorContent);
            if (UnityEditor.EditorGUI.EndChangeCheck())
            {
                var path = UnityEditor.AssetDatabase.GetAssetPath(prop.objectReferenceValue);
                if (string.IsNullOrEmpty(path))
                {
                    return;
                }

                UnityEditor.EditorUtility.DisplayDialog("ERROR", $"{FieldName} should use AssetReference to a non scene object!", "OK");
                prop.objectReferenceValue = null;
            }
        }
        public override void OnPropertyDrawer(UnityEditor.SerializedProperty prop)
        {
            if (editorContent == null || string.IsNullOrEmpty(editorContent.text))
            {
                var name = UnityEditor.ObjectNames.NicifyVariableName(FieldName);
                editorContent = new UnityEngine.GUIContent(name);
            }

            if (reList == null)
            {
                Type type;
                if (FieldType.StartsWith("CS."))
                {
                    var typeName = FieldType.Substring(3);
                    type = String2TypeCache.GetType(typeName);
                }
                else
                {
                    type = typeof(LuaBinding);
                }

                reList = new UnityEditorInternal.ReorderableList(prop.serializedObject, prop)
                {
                    elementHeight = UnityEditor.EditorGUIUtility.singleLineHeight
                };
                reList.drawHeaderCallback += rect => {
                    UnityEditor.EditorGUI.LabelField(rect, FieldName);
                };
                reList.drawElementCallback += (rect, index, active, focused) => {
                    var elemProp = reList.serializedProperty.GetArrayElementAtIndex(index);
                    UnityEditor.EditorGUI.BeginChangeCheck();
                    UnityEditor.EditorGUI.ObjectField(rect, elemProp, type, editorContent);
                    if (UnityEditor.EditorGUI.EndChangeCheck())
                    {
                        var path = UnityEditor.AssetDatabase.GetAssetPath(elemProp.objectReferenceValue);
                        if (string.IsNullOrEmpty(path))
                        {
                            return;
                        }

                        UnityEditor.EditorUtility.DisplayDialog("ERROR", $"{FieldName} should use AssetReference to a non scene object!", "OK");
                        elemProp.objectReferenceValue = null;
                    }
                };
            }

            reList.serializedProperty = prop;
            reList.DoLayoutList();
        }
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            if (!string.IsNullOrEmpty(label.text))
            {
                if (!label.text.Contains("(Asset)"))
                {
                    label.text += " (Asset)";
                }
            }

            var guidProp   = property.FindPropertyRelative("m_assetGUID");
            var attributes = fieldInfo.GetCustomAttributes(typeof(AssetReferenceAssetTypeAttribute), false);
            var type       = typeof(Object);

            if (!string.IsNullOrEmpty(label.tooltip))
            {
                type = String2TypeCache.GetType(label.tooltip);
            }
            else
            {
                if (attributes.Length > 0)
                {
                    var attr = attributes[0] as AssetReferenceAssetTypeAttribute;
                    type = attr.AssetType;
                }
            }

            var assetPath = AssetDatabase.GUIDToAssetPath(guidProp.stringValue);
            var resObj    = AssetDatabase.LoadAssetAtPath(assetPath, type);

            m_object = resObj;
            OnQuickInspectorGUI(ref position);
            var newResObj = EditorGUI.ObjectField(position, label, resObj, type, false);

            if (!string.IsNullOrEmpty(guidProp.stringValue) && string.IsNullOrEmpty(assetPath))
            {
                position.xMax -= EditorGUIUtility.singleLineHeight;
                EditorGUI.DrawRect(position, Color.red);
            }
            if (newResObj != resObj)
            {
                if (newResObj == null)
                {
                    guidProp.stringValue = null;
                }
                else
                {
                    assetPath = AssetDatabase.GetAssetPath(newResObj);
                    var path = assetPath.ToLower();
                    if (path.StartsWith("assets/resources"))
                    {
                        guidProp.stringValue = AssetDatabase.AssetPathToGUID(assetPath);
                    }
                    else
                    {
                        var settings = AssetDatabase.LoadAssetAtPath <StaticABSettings>(StaticAssetBundleWindow.SETTING_FILE_PATH);
                        if (settings.ContainExtraObject(newResObj))
                        {
                            guidProp.stringValue = AssetDatabase.AssetPathToGUID(assetPath);
                            return;
                        }

                        EditorUtility.DisplayDialog("ERROR", $"无法在配置中找到资源:{newResObj}", "OK");
                    }
                }
            }
        }
        public override void OnInspectorGUI()
        {
            if (binding.LuaData == null)
            {
                binding.LuaData = new LuaBindingDataBase[0];
            }

            var luaPathProp = serializedObject.FindProperty("LuaFile");

            if (string.IsNullOrEmpty(luaPathProp.stringValue))
            {
                EditorGUILayout.PropertyField(luaPathProp);
                EditorGUILayout.HelpBox("需要设置Lua文件!", MessageType.Error);
                serializedObject.ApplyModifiedProperties();
                return;
            }

            if (descriptor == null)
            {
                EditorGUILayout.PropertyField(luaPathProp);
                EditorGUILayout.HelpBox("需要设置Lua文件!", MessageType.Error);
                descriptor = LuaClassEditorFactory.GetDescriptorWithFilePath(luaPathProp.stringValue);
                serializedObject.ApplyModifiedProperties();
                return;
            }

            isUsedBinding.Clear();
            foreach (var field in descriptor.Fields.Where(field => !field.FieldName.StartsWith("_")))
            {
                if (field.FieldType.Contains("[]"))
                {
                    CheckBinding <LuaBindingUOArrayData>(field);
                }
                else if (field.FieldType.StartsWith("CS."))
                {
                    var typeName = field.FieldType.Substring(3);
                    var type     = String2TypeCache.GetType(typeName);
                    if (type == null)
                    {
                        EditorGUILayout.HelpBox($"Can not find type : {typeName}", MessageType.Error);
                    }
                    else
                    {
                        if (field.FieldType == "CS.Extend.Asset.AssetReference")
                        {
                            var match = CheckBinding <LuaBindingAssetReferenceData>(field);
                            if (!string.IsNullOrEmpty(field.Comment) && field.Comment.StartsWith("CS."))
                            {
                                match.AssetType = String2TypeCache.GetType(field.Comment.Substring(3));
                            }
                        }
                        else
                        {
                            CheckBinding <LuaBindingUOData>(field);
                        }
                    }
                }
                else
                {
                    var index = Array.IndexOf(basicTypes, field.FieldType);
                    if (index >= 0)
                    {
                        var typ = basicBindingTypes[index];
                        CheckBinding(field, typ);
                    }
                    else
                    {
                        CheckBinding <LuaBindingUOData>(field);
                    }
                }
            }

            for (var i = 0; i < binding.LuaData.Length;)
            {
                var bindingData = binding.LuaData[i];
                if (isUsedBinding.Contains(bindingData))
                {
                    i++;
                }
                else
                {
                    ArrayUtility.RemoveAt(ref binding.LuaData, i);
                }
            }

            serializedObject.UpdateIfRequiredOrScript();
            var luaDataProp = serializedObject.FindProperty("LuaData");

            for (var i = 0; i < binding.LuaData.Length; i++)
            {
                var arrElem     = binding.LuaData[i];
                var elementProp = luaDataProp.GetArrayElementAtIndex(i);
                var dataProp    = elementProp.FindPropertyRelative("Data");
                arrElem.OnPropertyDrawer(dataProp);
            }

            if (Application.isPlaying)
            {
                foreach (var methodName in descriptor.DebugMethods)
                {
                    if (GUILayout.Button(methodName) && binding.LuaInstance != null)
                    {
                        var func = binding.LuaInstance.Get <Action <LuaTable> >(methodName);
                        func(binding.LuaInstance);
                    }
                }
            }

            serializedObject.ApplyModifiedProperties();
            base.OnInspectorGUI();
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("重新加载Lua文件"))
            {
                if (descriptor == null)
                {
                    return;
                }
                descriptor = LuaClassEditorFactory.ReloadDescriptor(descriptor.ClassName.Replace('.', '/'));
            }

            if (GUILayout.Button("在编辑器中打开"))
            {
                string idePath = EditorPrefs.GetString("kScriptsDefaultApp_h2657262712");
                var    luaPath = $"{Application.dataPath}/../Lua/{luaPathProp.stringValue.Replace('.', '/')}.lua";
                if (idePath.Contains("Rider"))
                {
                    Process.Start($"\"{idePath}\"", $"--line 0 {luaPath}");
                }
                else if (idePath.Contains("Code"))
                {
                    string binPath = idePath.Replace("Code.exe", "bin/code");
                    Process.Start($"\"{binPath}\"", $"-r -g \"{luaPath}:0\"");
                }
            }

            GUILayout.EndHorizontal();
        }