/// <summary> /// Loads the UClass address for the given path (e.g. "/Script/Engine.Actor") /// </summary> /// <param name="path">The path of the object/class</param> /// <returns>The UClass address</returns> public static IntPtr LoadClassAddress(string path) { return(NativeReflection.LoadObject(Classes.UClass, IntPtr.Zero, path)); }
/// <summary> /// Gets the UClass for the given type /// </summary> /// <param name="type">The type</param> /// <returns>The UClass for the given type</returns> public static UClass GetClass(Type type) { UClass result = null; if (classes.TryGetValue(type, out result)) { return(result); } if (type.IsEnum || type.IsValueType || typeof(IDelegateBase).IsAssignableFrom(type)) { // Find the top-most UClass (UUserDefinedEnum, UEnum, UUserDefinedStruct, UUserStruct, etc) // NOTE: This wont contain any useful information about the actual type itself IntPtr address = IntPtr.Zero; if (type.IsEnum) { address = UEnum.GetEnumAddress(type); } else if (type.IsValueType) { address = UScriptStruct.GetStructAddress(type); } else { address = UFunction.GetDelegateSignatureAddress(type); } if (address != IntPtr.Zero) { return(GetClass(address)); } return(null); } if (!type.IsSameOrSubclassOf(typeof(UObject)) && (!type.IsInterface || !typeof(IInterface).IsAssignableFrom(type)) || type == typeof(IInterface)) { return(null); } if (seenClasses.Contains(type)) { // Note: GetModuleCount uses a lock // TODO: Find some multicast delegate which is called when a module is loaded or a new class type is created. // - FModuleManager::Get().OnProcessLoadedObjectsCallback if (FModuleManager.Get().GetModuleCount() != lastModuleCount) { seenClasses.Clear(); } else { return(null); } } if (!seenClasses.Contains(type)) { seenClasses.Add(type); UMetaPathAttribute pathAttribute; if (UnrealTypes.Native.TryGetValue(type, out pathAttribute)) { IntPtr classAddress = GetClassAddress(pathAttribute.Path); if (classAddress == IntPtr.Zero) { // Fallback if this class isn't loaded yet. TODO: Check if this is the correct method to call. classAddress = NativeReflection.LoadObject(Classes.UClass, IntPtr.Zero, pathAttribute.Path); } if (classAddress != IntPtr.Zero) { UClass unrealClass = GCHelper.Find <UClass>(classAddress); if (unrealClass != null) { classesByAddress[classAddress] = type; classes[type] = unrealClass; return(unrealClass); } } } } return(null); }
/// <summary> /// Loads the UScriptStruct address for the given path (e.g. "/Script/CoreUObject.Guid") /// </summary> /// <param name="path">The path of the UScriptStruct</param> /// <returns>The address of the UScriptStruct for the given path</returns> public static IntPtr LoadStructAddress(string path) { return(NativeReflection.LoadObject(Classes.UScriptStruct, IntPtr.Zero, path)); }