Beispiel #1
0
        /// <summary>
        /// Active
        /// </summary>
        /// <param name="classData"></param>
        public void Active(ClassData classData)
        {
            string classType = $"{classData.classNamespace + (classData.classNamespace == "" ? "" : ".")}{classData.className}";
            IType  type      = InitJEngine.Appdomain.LoadedTypes[classType];
            Type   t         = type.ReflectionType; //获取实际属性
            //这边获取clrInstance的基类,这样可以获取不同适配器
            var clrInstance = gameObject.GetComponents <CrossBindingAdaptorType>()
                              .Last(clr => clr.ILInstance.Type == type as ILType);

            //是否激活
            if (classData.activeAfter)
            {
                if (classData.BoundData == false && classData.requireBindFields && classData.fields.Count > 0)
                {
                    Log.PrintError($"自动绑定{name}出错:{classType}没有成功绑定数据,自动激活成功,但可能会抛出空异常!");
                }

                //Mono类型能设置enabled
                if (clrInstance.GetType().IsSubclassOf(typeof(MonoBehaviour)))
                {
                    ((MonoBehaviour)clrInstance).enabled = true;
                }

                //不管是啥类型,直接invoke这个awake方法
                var awakeMethod = clrInstance.GetType().GetMethod("Awake",
                                                                  BindingFlags.Default | BindingFlags.Public
                                                                  | BindingFlags.Instance | BindingFlags.FlattenHierarchy |
                                                                  BindingFlags.NonPublic | BindingFlags.Static);
                if (awakeMethod == null)
                {
                    awakeMethod = t.GetMethod("Awake",
                                              BindingFlags.Default | BindingFlags.Public
                                              | BindingFlags.Instance | BindingFlags.FlattenHierarchy |
                                              BindingFlags.NonPublic | BindingFlags.Static);
                }
                else
                {
                    awakeMethod.Invoke(clrInstance, null);
                    classData.Activated = true;
                }

                if (awakeMethod == null)
                {
                    Log.PrintError($"{t.FullName}不包含Awake方法,无法激活,已跳过");
                }
                else if (!classData.Activated)
                {
                    awakeMethod.Invoke(t, null);
                }

                classData.Activated = true;
            }

            Remove();
        }
Beispiel #2
0
        /// <summary>
        /// Active
        /// </summary>
        /// <param name="classData"></param>
        public void Active(ClassData classData)
        {
            string classType =
                $"{classData.classNamespace + (classData.classNamespace == "" ? "" : ".")}{classData.className}";
            Type t           = classData.ClassType; //获取实际属性
            var  clrInstance = classData.ClrInstance;

            //是否激活
            if (classData.activeAfter)
            {
                if (classData.BoundData == false && classData.fields != null &&
                    classData.fields.Count > 0)
                {
                    Log.PrintError($"自动绑定{name}出错:{classType}没有成功绑定数据,自动激活成功,但可能会抛出空异常!");
                }

                //Mono类型能设置enabled
                if (clrInstance.GetType().IsSubclassOf(typeof(MonoBehaviour)))
                {
                    ((MonoBehaviour)clrInstance).enabled = true;
                }

                //不管是啥类型,直接invoke这个awake方法
                var awakeMethod = clrInstance.GetType().GetMethod("Awake",
                                                                  BindingFlags.Default | BindingFlags.Public
                                                                  | BindingFlags.Instance | BindingFlags.FlattenHierarchy |
                                                                  BindingFlags.NonPublic | BindingFlags.Static);
                if (awakeMethod == null)
                {
                    awakeMethod = t.GetMethod("Awake",
                                              BindingFlags.Default | BindingFlags.Public
                                              | BindingFlags.Instance | BindingFlags.FlattenHierarchy |
                                              BindingFlags.NonPublic | BindingFlags.Static);
                }
                else
                {
                    awakeMethod.Invoke(clrInstance, null);
                    classData.Activated = true;
                }

                if (awakeMethod == null)
                {
                    Log.PrintError($"{t.FullName}不包含Awake方法,无法激活,已跳过");
                }
                else if (!classData.Activated)
                {
                    awakeMethod.Invoke(t, null);
                }

                classData.Activated = true;
            }

            Remove();
        }
Beispiel #3
0
        /// <summary>
        /// Add a classbind to gameobject to visualize
        /// 加ClassBind至GameObject以可视化
        /// </summary>
        /// <param name="gameObject"></param>
        /// <param name="activeAfter"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private static string AddClassBind(GameObject gameObject, bool activeAfter, Type type)
        {
            var jBehaviour = type;
            var cb         = gameObject.AddComponent <ClassBind>();
            var _cb        = new ClassData()
            {
                classNamespace = "",
                className      = jBehaviour.FullName,
                activeAfter    = activeAfter,
            };
            var id = (cb.AddClass(_cb) as JBehaviour)._instanceID;

            cb.Active(_cb);
            UnityEngine.Object.Destroy(cb);
            return(id);
        }
Beispiel #4
0
        /// <summary>
        /// Add a classbind to gameobject to visualize
        /// 加ClassBind至GameObject以可视化
        /// </summary>
        /// <param name="gameObject"></param>
        /// <param name="activeAfter"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private static string AddClassBind(GameObject gameObject, bool activeAfter, Type type)
        {
            var jBehaviour = type;
            var cb         = gameObject.AddComponent <ClassBind>();
            var _cb        = new ClassData()
            {
                classNamespace = jBehaviour.Namespace,
                className      = jBehaviour.Name,
                activeAfter    = activeAfter,
                useConstructor = true
            };
            var id = cb.AddClass(_cb);

            cb.Active(_cb);
            UnityEngine.Object.Destroy(cb);
            return(id);
        }
Beispiel #5
0
        /// <summary>
        /// Set value
        /// </summary>
        /// <param name="classData"></param>
        public void SetVal(ClassData classData)
        {
            string classType = $"{classData.classNamespace + (classData.classNamespace == "" ? "" : ".")}{classData.className}";

            InitJEngine.Appdomain.LoadedTypes.TryGetValue(classType, out var type);
            Type t = type?.ReflectionType;//获取实际属性
            //这里获取适配器类型接口,不直接获取Mono适配器了,因为不同的类型适配器不一样
            var clrInstance = gameObject.GetComponents <CrossBindingAdaptorType>()
                              .Last(clr => clr.ILInstance.Type == type as ILType);

            //绑定数据
            if (classData.requireBindFields)
            {
                classData.BoundData = false;
                var fields = classData.fields.ToArray();

                foreach (ClassField field in fields)
                {
                    if (field.fieldType == ClassField.FieldType.NotSupported)
                    {
                        continue;
                    }

                    object obj = null;
                    try
                    {
                        if (field.fieldType == ClassField.FieldType.Number)
                        {
                            var fieldType = t.GetField(field.fieldName,
                                                       BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance |
                                                       BindingFlags.Static).FieldType ?? t.GetProperty(field.fieldName,
                                                                                                       BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance |
                                                                                                       BindingFlags.Static).PropertyType;

                            if (fieldType.FullName == typeof(SByte).FullName)
                            {
                                obj = SByte.Parse(field.value);
                                classData.BoundData = true;
                            }
                            else if (fieldType.FullName == typeof(Byte).FullName)
                            {
                                obj = Byte.Parse(field.value);
                                classData.BoundData = true;
                            }
                            else if (fieldType.FullName == typeof(Int16).FullName)
                            {
                                obj = Int16.Parse(field.value);
                                classData.BoundData = true;
                            }
                            else if (fieldType.FullName == typeof(UInt16).FullName)
                            {
                                obj = UInt16.Parse(field.value);
                                classData.BoundData = true;
                            }
                            else if (fieldType.FullName == typeof(Int32).FullName)
                            {
                                obj = Int32.Parse(field.value);
                                classData.BoundData = true;
                            }
                            else if (fieldType.FullName == typeof(UInt32).FullName)
                            {
                                obj = UInt32.Parse(field.value);
                                classData.BoundData = true;
                            }
                            else if (fieldType.FullName == typeof(Int64).FullName)
                            {
                                obj = Int64.Parse(field.value);
                                classData.BoundData = true;
                            }
                            else if (fieldType.FullName == typeof(UInt64).FullName)
                            {
                                obj = UInt64.Parse(field.value);
                                classData.BoundData = true;
                            }
                            else if (fieldType.FullName == typeof(Single).FullName)
                            {
                                obj = Single.Parse(field.value);
                                classData.BoundData = true;
                            }
                            else if (fieldType.FullName == typeof(Decimal).FullName)
                            {
                                obj = Decimal.Parse(field.value);
                                classData.BoundData = true;
                            }
                            else if (fieldType.FullName == typeof(Double).FullName)
                            {
                                obj = Double.Parse(field.value);
                                classData.BoundData = true;
                            }
                        }

                        else if (field.fieldType == ClassField.FieldType.String)
                        {
                            obj = field.value;
                            classData.BoundData = true;
                        }
                        else if (field.fieldType == ClassField.FieldType.Bool)
                        {
                            field.value         = field.value.ToLower();
                            obj                 = field.value == "true";
                            classData.BoundData = true;
                        }

                        if (field.fieldType == ClassField.FieldType.GameObject)
                        {
                            GameObject go = field.gameObject;
                            if (go == null)
                            {
                                try
                                {
                                    go = field.value == "${this}"
                                        ? gameObject
                                        : GameObject.Find(field.value);
                                    if (go == null) //找父物体
                                    {
                                        go = FindSubGameObject(field);
                                        if (go == null) //如果父物体还不存在
                                        {
                                            continue;
                                        }
                                    }
                                }
                                catch (Exception) //找父物体(如果抛出空异常)
                                {
                                    go = FindSubGameObject(field);
                                    if (go == null) //如果父物体还不存在
                                    {
                                        continue;
                                    }
                                }
                            }

                            obj = go;
                            classData.BoundData = true;
                        }
                        else if (field.fieldType == ClassField.FieldType.UnityComponent)
                        {
                            GameObject go = field.gameObject;
                            if (go == null)
                            {
                                try
                                {
                                    if (field.value.Contains("."))
                                    {
                                        field.value =
                                            field.value.Remove(field.value.IndexOf(".", StringComparison.Ordinal));
                                    }

                                    go = field.value == "${this}"
                                        ? gameObject
                                        : GameObject.Find(field.value);
                                    if (go == null) //找父物体
                                    {
                                        go = FindSubGameObject(field);
                                        if (go == null) //如果父物体还不存在
                                        {
                                            continue;
                                        }
                                    }
                                }
                                catch (Exception) //找父物体(如果抛出空异常)
                                {
                                    go = FindSubGameObject(field);
                                    if (go == null) //如果父物体还不存在
                                    {
                                        continue;
                                    }
                                }
                            }

                            var tp = t.GetField(field.fieldName,
                                                BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance |
                                                BindingFlags.Static);
                            if (tp != null)
                            {
                                string tName = tp.FieldType.Name;
                                if (tp.FieldType is ILRuntime.Reflection.ILRuntimeType) //如果在热更中
                                {
                                    var components = go.GetComponents <CrossBindingAdaptorType>();
                                    foreach (var c in components)
                                    {
                                        if (c.ILInstance.Type.Name == tName)
                                        {
                                            obj = c.ILInstance;
                                            classData.BoundData = true;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    var component = go.GetComponents <Component>().ToList()
                                                    .Find(c => c.GetType().ToString().Contains(tName));
                                    if (component != null)
                                    {
                                        obj = component;
                                        classData.BoundData = true;
                                    }
                                }
                            }
                            else
                            {
                                var pi = t.GetProperty(field.fieldName,
                                                       BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance |
                                                       BindingFlags.Static);
                                if (pi != null)
                                {
                                    string tName = pi.PropertyType.Name;
                                    if (pi.PropertyType is ILRuntime.Reflection.ILRuntimeType) //如果在热更中
                                    {
                                        var components = go.GetComponents <CrossBindingAdaptorType>();
                                        foreach (var c in components)
                                        {
                                            if (c.ILInstance.Type.Name == tName)
                                            {
                                                obj = c.ILInstance;
                                                classData.BoundData = true;
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        var component = go.GetComponents <Component>().ToList()
                                                        .Find(c => c.GetType().ToString().Contains(tName));
                                        if (component != null)
                                        {
                                            obj = component;
                                            classData.BoundData = true;
                                        }
                                    }
                                }
                                else
                                {
                                    Log.PrintError(
                                        $"自动绑定{name}出错:{classType}.{field.fieldName}赋值出错:{field.fieldName}不存在");
                                }
                            }
                        }
                        else if (field.fieldType == ClassField.FieldType.HotUpdateResource)
                        {
                            obj = Assets.LoadAsset(field.value, typeof(Object)).asset;
                            classData.BoundData = true;
                        }
                    }
                    catch (Exception except)
                    {
                        Log.PrintError(
                            $"自动绑定{name}出错:{classType}.{field.fieldName}获取值{field.value}出错:{except.Message},已跳过");
                    }

                    //如果有数据再绑定
                    if (classData.BoundData)
                    {
                        var fi = t.GetField(field.fieldName,
                                            BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance |
                                            BindingFlags.Static);
                        if (fi != null)
                        {
                            try
                            {
                                fi.SetValue(clrInstance.ILInstance, obj);
                            }
                            catch (Exception e)
                            {
                                Log.PrintError(
                                    $"自动绑定{name}出错:{classType}.{field.fieldName}赋值出错:{e.Message},已跳过");
                            }
                        }
                        else
                        {
                            //没FieldInfo尝试PropertyInfo
                            var pi = t.GetProperty(field.fieldName,
                                                   BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance |
                                                   BindingFlags.Static);
                            if (pi != null)
                            {
                                pi.SetValue(clrInstance.ILInstance, obj);
                            }
                            else
                            {
                                Log.PrintError($"自动绑定{name}出错:{classType}不存在{field.fieldName},已跳过");
                            }
                        }
                    }
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Add class
        /// </summary>
        /// <param name="classData"></param>
        /// <returns></returns>
        public string AddClass(ClassData classData)
        {
            //添加脚本
            string classType =
                $"{classData.classNamespace + (string.IsNullOrEmpty(classData.classNamespace) ? "" : ".")}{classData.className}";

            if (!InitJEngine.Appdomain.LoadedTypes.TryGetValue(classType, out var type))
            {
                Log.PrintError($"自动绑定{name}出错:{classType}不存在,已跳过");
                return(null);
            }

            Type t = type.ReflectionType; //获取实际属性

            //JBehaviour需自动赋值一个值
            bool isMono       = t.IsSubclassOf(typeof(MonoBehaviour));
            bool isJBehaviour = false;

            if (!isMono)//不是mono才有可能继承JBehaviour
            {
                isJBehaviour = t.IsSubclassOf(jBehaviourType.ReflectionType);
            }

            bool needAdapter = t.BaseType != null &&
                               t.BaseType.GetInterfaces().Contains(typeof(CrossBindingAdaptorType));

            ILTypeInstance instance;

            if (classData.useConstructor)
            {
                instance = isMono ? new ILTypeInstance(type as ILType, false) : InitJEngine.Appdomain.Instantiate(classType);
            }
            else
            {
                instance = new ILTypeInstance(type as ILType, !isMono);
            }

            instance.CLRInstance = instance;

            //这里是ClassBind的灵魂,我都佩服我自己这么写,所以别乱改这块
            //非mono的跨域继承用特殊的,就是用JEngine提供的一个mono脚本,来显示字段,里面存ILTypeInstance
            //总之JEngine牛逼
            //是继承Mono封装的基类,用自动生成的
            if (needAdapter && isMono && t.BaseType?.FullName != typeof(MonoBehaviourAdapter.Adaptor).FullName && Type.GetType(t.BaseType?.FullName ?? string.Empty) != null)
            {
                Type adapterType = Type.GetType(t.BaseType?.FullName ?? string.Empty);
                if (adapterType == null)
                {
                    Log.PrintError($"{t.FullName}, need to generate adapter");
                    return(null);
                }

                //直接反射赋值一波了
                var clrInstance = gameObject.AddComponent(adapterType) as MonoBehaviour;

                var clrILInstance = t.GetField("instance",
                                               BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
                var clrAppDomain = t.GetField("appdomain",
                                              BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
                if (!(clrInstance is null))
                {
                    clrInstance.enabled = false;
                    clrILInstance?.SetValue(clrInstance, instance);
                    clrAppDomain?.SetValue(clrInstance, InitJEngine.Appdomain);
                    instance.CLRInstance = clrInstance;
                }
            }
            //直接继承Mono的,非继承mono的,或不需要继承的,用这个
            else
            {
                //挂个适配器到编辑器(直接继承mono,非继承mono,无需继承,都可以用这个)
                var clrInstance = gameObject.AddComponent <MonoBehaviourAdapter.Adaptor>();
                clrInstance.enabled    = false;
                clrInstance.ILInstance = instance;
                clrInstance.AppDomain  = InitJEngine.Appdomain;

                //是MonoBehaviour继承,需要指定CLRInstance
                if (isMono && needAdapter)
                {
                    instance.CLRInstance = clrInstance;
                }

                //判断类型
                clrInstance.isMonoBehaviour = isMono;

                classData.Added = true;

                //JBehaviour额外处理
                if (isJBehaviour)
                {
                    clrInstance.isJBehaviour = true;
                    var go = t.GetField("_gameObject", BindingFlags.Public);
                    if (!(go is null))
                    {
                        go.SetValue(clrInstance.ILInstance, gameObject);
                    }
                }

                //JBehaviour返回实例ID
                if (isJBehaviour)
                {
                    var f = t.GetField("_instanceID", BindingFlags.NonPublic);
                    if (!(f is null))
                    {
                        var id = f.GetValue(clrInstance.ILInstance).ToString();
                        return(id);
                    }
                }
            }

            if (classData.useConstructor && isMono)
            {
                var m = type.GetConstructor(Extensions.EmptyParamList);
                if (m != null)
                {
                    InitJEngine.Appdomain.Invoke(m, instance, null);
                }
            }

            return(null);
        }
Beispiel #7
0
        /// <summary>
        /// Add class
        /// </summary>
        /// <param name="classData"></param>
        /// <returns></returns>
        public object AddClass(ClassData classData)
        {
            //添加脚本
            string classType =
                $"{classData.classNamespace + (string.IsNullOrEmpty(classData.classNamespace) ? "" : ".")}{classData.className}";

            if (!InitJEngine.Appdomain.LoadedTypes.TryGetValue(classType, out var type))
            {
                Log.PrintError($"自动绑定{name}出错:{classType}不存在,已跳过");
                return(null);
            }

            Type t = type.ReflectionType; //获取实际属性

            classData.ClassType = t;
            Type baseType =
                t.BaseType is ILRuntimeWrapperType wrapperType
                    ? wrapperType.RealType
                    : t.BaseType; //这个地方太坑了 你一旦热更工程代码写的骚 就会导致ILWrapperType这个问题出现 一般人还真不容易发现这个坑
            Type monoType = typeof(MonoBehaviour);

            //JBehaviour需自动赋值一个值
            bool isMono      = t.IsSubclassOf(monoType) || (baseType != null && baseType.IsSubclassOf(monoType));
            bool needAdapter = baseType != null &&
                               baseType.GetInterfaces().Contains(typeof(CrossBindingAdaptorType));

            ILTypeInstance instance = isMono
                ? new ILTypeInstance(type as ILType, false)
                : InitJEngine.Appdomain.Instantiate(classType);

            instance.CLRInstance = instance;

            /*
             * 这里是ClassBind的灵魂,我都佩服我自己这么写,所以别乱改这块
             * 非mono的跨域继承用特殊的,就是用JEngine提供的一个mono脚本,来显示字段,里面存ILTypeInstance
             * 总之JEngine牛逼
             * ClassBind只支持挂以下2种热更类型:纯热更类型,继承了Mono的类型(无论是主工程多重继承后跨域还是跨域后热更工程多重继承都可以)
             * 主工程多重继承后再跨域多重继承的应该还不支持
             */
            //主工程多重继承后跨域继承的生成适配器后用这个
            if (needAdapter && isMono && baseType != typeof(MonoBehaviourAdapter.Adaptor))
            {
                Type adapterType = Type.GetType(baseType.FullName ?? string.Empty);
                if (adapterType == null)
                {
                    Log.PrintError($"{t.FullName}, need to generate adapter");
                    return(null);
                }

                //直接反射赋值一波了
                var clrInstance = gameObject.AddComponent(adapterType) as MonoBehaviour;

                var clrILInstance = t.GetFields(
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
                                    .First(f => f.Name == "instance" && f.FieldType == typeof(ILTypeInstance));
                var clrAppDomain = t.GetFields(
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
                                   .First(f => f.Name == "appdomain" && f.FieldType == typeof(AppDomain));
                if (!(clrInstance is null))
                {
                    clrInstance.enabled = false;
                    clrILInstance.SetValue(clrInstance, instance);
                    clrAppDomain.SetValue(clrInstance, InitJEngine.Appdomain);
                    instance.CLRInstance  = clrInstance;
                    classData.ClrInstance = (CrossBindingAdaptorType)clrInstance;
                }
            }
            //直接继承Mono的,热更工程多层继承mono的,非继承mono的,或不需要继承的,用这个
            else
            {
                //挂个适配器到编辑器(直接继承mono,非继承mono,无需继承,都可以用这个)
                var clrInstance = gameObject.AddComponent <MonoBehaviourAdapter.Adaptor>();
                clrInstance.enabled    = false;
                clrInstance.ILInstance = instance;
                clrInstance.AppDomain  = InitJEngine.Appdomain;
                classData.ClrInstance  = clrInstance;


                //是MonoBehaviour继承,需要指定CLRInstance
                if (isMono)
                {
                    instance.CLRInstance = clrInstance;
                }

                //判断类型
                clrInstance.isMonoBehaviour = isMono;

                classData.Added = true;

                //JBehaviour额外处理
                var go = t.GetField("_gameObject", BindingFlags.Public);
                go?.SetValue(clrInstance.ILInstance, gameObject);
            }

            if (isMono)
            {
                if (type.BaseType.ReflectionType is ILRuntimeType)
                {
                    Log.PrintWarning(
                        "因为有跨域多层继承MonoBehaviour,会有一个可以忽略的警告:You are trying to create a MonoBehaviour using the 'new' keyword.  This is not allowed.  MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all");
                    type.ReflectionType.GetConstructor(new Type[] { })?.Invoke(instance, new object[] { });
                }
                else
                {
                    var m = type.GetConstructor(Extensions.EmptyParamList);
                    if (m != null)
                    {
                        InitJEngine.Appdomain.Invoke(m, instance, null);
                    }
                }
            }

            return(instance);
        }
Beispiel #8
0
        /// <summary>
        /// Set value
        /// </summary>
        /// <param name="classData"></param>
        public void SetVal(ClassData classData)
        {
            string classType =
                $"{classData.classNamespace + (classData.classNamespace == "" ? "" : ".")}{classData.className}";
            Type t           = classData.ClassType; //获取实际属性
            var  clrInstance = classData.ClrInstance;

            //绑定数据
            classData.BoundData = false;
            var fields      = classData.fields.ToArray();
            var bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance |
                              BindingFlags.Static;

            foreach (ClassField field in fields)
            {
                if (field.fieldType == ClassField.FieldType.NotSupported)
                {
                    continue;
                }

                object obj = null;
                try
                {
                    if (field.fieldType == ClassField.FieldType.Number)
                    {
                        var fieldType = t.GetField(field.fieldName, bindingAttr).FieldType ??
                                        (t.BaseType.GetField(field.fieldName, bindingAttr).FieldType ??
                                         (t.GetProperty(field.fieldName, bindingAttr).PropertyType ??
                                          t.BaseType.GetProperty(field.fieldName, bindingAttr).PropertyType));
                        fieldType = fieldType is ILRuntimeWrapperType wrapperType ? wrapperType.RealType : fieldType;

                        if (fieldType == typeof(SByte))
                        {
                            obj = SByte.Parse(field.value);
                            classData.BoundData = true;
                        }
                        else if (fieldType == typeof(Byte))
                        {
                            obj = Byte.Parse(field.value);
                            classData.BoundData = true;
                        }
                        else if (fieldType == typeof(Int16))
                        {
                            obj = Int16.Parse(field.value);
                            classData.BoundData = true;
                        }
                        else if (fieldType == typeof(UInt16))
                        {
                            obj = UInt16.Parse(field.value);
                            classData.BoundData = true;
                        }
                        else if (fieldType == typeof(Int32))
                        {
                            obj = Int32.Parse(field.value);
                            classData.BoundData = true;
                        }
                        else if (fieldType == typeof(UInt32))
                        {
                            obj = UInt32.Parse(field.value);
                            classData.BoundData = true;
                        }
                        else if (fieldType == typeof(Int64))
                        {
                            obj = Int64.Parse(field.value);
                            classData.BoundData = true;
                        }
                        else if (fieldType == typeof(UInt64))
                        {
                            obj = UInt64.Parse(field.value);
                            classData.BoundData = true;
                        }
                        else if (fieldType == typeof(Single))
                        {
                            obj = Single.Parse(field.value);
                            classData.BoundData = true;
                        }
                        else if (fieldType == typeof(Decimal))
                        {
                            obj = Decimal.Parse(field.value);
                            classData.BoundData = true;
                        }
                        else if (fieldType == typeof(Double))
                        {
                            obj = Double.Parse(field.value);
                            classData.BoundData = true;
                        }
                    }

                    else if (field.fieldType == ClassField.FieldType.String)
                    {
                        obj = field.value;
                        classData.BoundData = true;
                    }
                    else if (field.fieldType == ClassField.FieldType.Bool)
                    {
                        field.value         = field.value.ToLower();
                        obj                 = field.value == "true";
                        classData.BoundData = true;
                    }

                    if (field.fieldType == ClassField.FieldType.GameObject)
                    {
                        GameObject go = field.gameObject;
                        if (go == null)
                        {
                            try
                            {
                                go = field.value == "${this}"
                                    ? gameObject
                                    : GameObject.Find(field.value);
                                if (go == null) //找父物体
                                {
                                    go = FindSubGameObject(field);
                                    if (go == null) //如果父物体还不存在
                                    {
                                        continue;
                                    }
                                }
                            }
                            catch (Exception) //找父物体(如果抛出空异常)
                            {
                                go = FindSubGameObject(field);
                                if (go == null) //如果父物体还不存在
                                {
                                    continue;
                                }
                            }
                        }

                        obj = go;
                        classData.BoundData = true;
                    }
                    else if (field.fieldType == ClassField.FieldType.UnityComponent)
                    {
                        GameObject go = field.gameObject;
                        if (go == null)
                        {
                            try
                            {
                                if (field.value.Contains("."))
                                {
                                    field.value =
                                        field.value.Remove(field.value.IndexOf(".", StringComparison.Ordinal));
                                }

                                go = field.value == "${this}"
                                    ? gameObject
                                    : GameObject.Find(field.value);
                                if (go == null) //找父物体
                                {
                                    go = FindSubGameObject(field);
                                    if (go == null) //如果父物体还不存在
                                    {
                                        continue;
                                    }
                                }
                            }
                            catch (Exception) //找父物体(如果抛出空异常)
                            {
                                go = FindSubGameObject(field);
                                if (go == null) //如果父物体还不存在
                                {
                                    continue;
                                }
                            }
                        }

                        var tp = t.GetField(field.fieldName, bindingAttr);
                        if (tp == null)
                        {
                            tp = t.BaseType?.GetField(field.fieldName, bindingAttr);
                        }
                        if (tp != null)
                        {
                            var fieldType = tp.FieldType;
                            fieldType = fieldType is ILRuntimeWrapperType wrapperType ? wrapperType.RealType : fieldType;

                            if (fieldType is ILRuntimeType) //如果在热更中
                            {
                                var components = go.GetComponents <CrossBindingAdaptorType>();
                                foreach (var c in components)
                                {
                                    if (c.ILInstance.Type.ReflectionType == fieldType)
                                    {
                                        obj = c.ILInstance;
                                        classData.BoundData = true;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                var component = go.GetComponent(fieldType);
                                if (component != null)
                                {
                                    obj = component;
                                    classData.BoundData = true;
                                }
                            }
                        }
                        else
                        {
                            var pi = t.GetProperty(field.fieldName, bindingAttr);
                            if (pi == null)
                            {
                                pi = t.BaseType?.GetProperty(field.fieldName, bindingAttr);
                            }
                            if (pi != null)
                            {
                                var fieldType = pi.PropertyType;
                                fieldType = fieldType is ILRuntimeWrapperType wrapperType ? wrapperType.RealType : fieldType;

                                if (fieldType is ILRuntimeType) //如果在热更中
                                {
                                    var components = go.GetComponents <CrossBindingAdaptorType>();
                                    foreach (var c in components)
                                    {
                                        if (c.ILInstance.Type.ReflectionType == fieldType)
                                        {
                                            obj = c.ILInstance;
                                            classData.BoundData = true;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    var component = go.GetComponent(fieldType);
                                    if (component != null)
                                    {
                                        obj = component;
                                        classData.BoundData = true;
                                    }
                                }
                            }
                            else
                            {
                                Log.PrintError(
                                    $"自动绑定{name}出错:{classType}.{field.fieldName}赋值出错:{field.fieldName}不存在");
                            }
                        }
                    }
                    else if (field.fieldType == ClassField.FieldType.HotUpdateResource)
                    {
                        obj = AssetMgr.Load(field.value);
                        classData.BoundData = true;
                    }
                }
                catch (Exception except)
                {
                    Log.PrintError(
                        $"自动绑定{name}出错:{classType}.{field.fieldName}获取值{field.value}出错:{except.Message},已跳过");
                }

                //如果有数据再绑定
                if (classData.BoundData)
                {
                    void _setVal(MemberInfo mi)
                    {
                        try
                        {
                            switch (mi)
                            {
                            case null:
                                throw new NullReferenceException();

                            case FieldInfo info:
                                info.SetValue(clrInstance.ILInstance, obj);
                                break;

                            case PropertyInfo inf:
                                inf.SetValue(clrInstance.ILInstance, obj);
                                break;
                            }
                        }
                        catch (Exception e)
                        {
                            Log.PrintError(
                                $"自动绑定{name}出错:{classType}.{field.fieldName}赋值出错:{e.Message},已跳过");
                        }
                    }

                    var fi = t.GetField(field.fieldName, bindingAttr);
                    if (fi == null)
                    {
                        fi = t.BaseType?.GetField(field.fieldName, bindingAttr);
                    }
                    if (fi != null)
                    {
                        _setVal(fi);
                    }
                    else
                    {
                        var pi = t.GetProperty(field.fieldName, bindingAttr);
                        if (pi == null)
                        {
                            pi = t.BaseType?.GetProperty(field.fieldName, bindingAttr);
                        }
                        _setVal(pi);
                    }
                }
            }
        }