public override void PostBuild(NativePlugin plugin, NativeBuildOptions buildOptions) { base.PostBuild(plugin, buildOptions); string archName = buildOptions.Architecture == Architecture.ARMv7 ? "armeabi-v7a" : "x86"; string assetFile = CombinePath( AssetDatabase.GetAssetPath(plugin.pluginBinaryFolder), "Android", archName, string.Format("lib{0}.so", plugin.Name)); PluginImporter pluginImporter = PluginImporter.GetAtPath((assetFile)) as PluginImporter; if (pluginImporter != null) { SetPluginBaseInfo(plugin, buildOptions, pluginImporter); pluginImporter.SetCompatibleWithAnyPlatform(false); pluginImporter.SetCompatibleWithPlatform(BuildTarget.Android, true); pluginImporter.SetEditorData("CPU", buildOptions.Architecture.ToString()); pluginImporter.SetEditorData("ANDROID_SDK_VERSION", buildOptions.AndroidSdkVersion.ToString()); pluginImporter.SaveAndReimport(); } }
/// <summary> /// Sets the plugins. /// </summary> /// <param name="files">Files.</param> /// <param name="editorSettings">Editor settings.</param> /// <param name="settings">Settings.</param> static void SetPlugins(string[] files, Dictionary <string, string> editorSettings, Dictionary <BuildTarget, Dictionary <string, string> > settings) { if (files == null) { return; } foreach (string item in files) { PluginImporter pluginImporter = PluginImporter.GetAtPath(item) as PluginImporter; if (pluginImporter != null) { pluginImporter.SetCompatibleWithAnyPlatform(false); pluginImporter.SetCompatibleWithEditor(false); if (editorSettings != null) { pluginImporter.SetCompatibleWithEditor(true); foreach (KeyValuePair <string, string> pair in editorSettings) { pluginImporter.SetEditorData(pair.Key, pair.Value); } } if (settings != null) { foreach (KeyValuePair <BuildTarget, Dictionary <string, string> > settingPair in settings) { pluginImporter.SetCompatibleWithPlatform(settingPair.Key, true); if (settingPair.Value != null) { foreach (KeyValuePair <string, string> pair in settingPair.Value) { pluginImporter.SetPlatformData(settingPair.Key, pair.Key, pair.Value); } } } } else { foreach (BuildTarget target in Enum.GetValues(typeof(BuildTarget))) { pluginImporter.SetCompatibleWithPlatform(target, false); } } pluginImporter.SaveAndReimport(); Debug.Log("SetPluginImportSettings Success :" + item); } else { Debug.LogWarning("SetPluginImportSettings Faild :" + item); } } }
static PackageExporter() { assetProcessorLookup = new Dictionary <string, AssetProcessor>(); assetProcessorLookup[".png"] = delegate(string assetPath) { var importer = (TextureImporter)TextureImporter.GetAtPath(assetPath); importer.textureType = TextureImporterType.Default; importer.mipmapEnabled = false; importer.filterMode = FilterMode.Point; importer.npotScale = TextureImporterNPOTScale.None; importer.textureCompression = TextureImporterCompression.Uncompressed; importer.alphaSource = TextureImporterAlphaSource.None; importer.SaveAndReimport(); }; assetProcessorLookup[".h"] = assetProcessorLookup[".m"] = assetProcessorLookup[".mm"] = delegate(string assetPath) { var importer = (PluginImporter)PluginImporter.GetAtPath(assetPath); importer.SetCompatibleWithEditor(false); importer.SetCompatibleWithPlatform(BuildTarget.iOS, false); importer.SetCompatibleWithPlatform(BuildTarget.Android, false); importer.SetCompatibleWithPlatform(BuildTarget.WebGL, false); importer.SaveAndReimport(); }; assetProcessorLookup[".aar"] = delegate(string assetPath) { var importer = (PluginImporter)PluginImporter.GetAtPath(assetPath); importer.SetCompatibleWithEditor(false); importer.SetCompatibleWithPlatform(BuildTarget.Android, true); importer.SetCompatibleWithPlatform(BuildTarget.iOS, false); importer.SetCompatibleWithPlatform(BuildTarget.WebGL, false); importer.SaveAndReimport(); }; }
private static void SetPluginCompatibleIdp(BuildTarget target, string path, bool enable) { // if (File.Exists (path) == true || Directory.Exists (path) == true) { // FileAttributes attr = File.GetAttributes (path); // string[] pathSplit = path.Split ('/'); // string name = pathSplit [pathSplit.Length - 1]; // if ((attr & FileAttributes.Directory) == FileAttributes.Directory && name.Contains (".") == false) { // Debug.LogError ("directory : " + path); // string[] directoryPaths = Directory.GetDirectories (path, "*", SearchOption.TopDirectoryOnly); // foreach (string directoryPath in directoryPaths) { // SetPluginCompatibleIdp (target, directoryPath, enable); // } // } else { // Debug.LogError ("file : " + path); if (File.Exists(path) == true || Directory.Exists(path) == true) { PluginImporter pluginImporter = PluginImporter.GetAtPath(path) as PluginImporter; if (pluginImporter != null) { if (pluginImporter.GetCompatibleWithAnyPlatform() == true) { pluginImporter.SetCompatibleWithAnyPlatform(false); } if (pluginImporter.GetCompatibleWithPlatform(target) != enable) { pluginImporter.SetCompatibleWithPlatform(target, enable); pluginImporter.SaveAndReimport(); } } } // } // } }
public override void PostBuild(NativePlugin plugin, NativeBuildOptions buildOptions) { base.PostBuild(plugin, buildOptions); string assetFile = CombinePath( AssetDatabase.GetAssetPath(plugin.pluginBinaryFolder), "Linux", buildOptions.Architecture.ToString(), string.Format("lib{0}.so", plugin.Name)); PluginImporter pluginImporter = PluginImporter.GetAtPath((assetFile)) as PluginImporter; if (pluginImporter != null) { SetPluginBaseInfo(plugin, buildOptions, pluginImporter); pluginImporter.SetCompatibleWithAnyPlatform(false); pluginImporter.SetCompatibleWithEditor(true); pluginImporter.SetEditorData("OS", "Linux"); pluginImporter.SetEditorData("CPU", buildOptions.Architecture.ToString()); if (buildOptions.Architecture == Architecture.x86) { pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneLinux, true); } else { pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneLinux64, true); } pluginImporter.SaveAndReimport(); } }
static void OnPostprocessAllAssets ( string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths ) { #if false //UNITY_5_0 foreach ( string asset in importedAssets ) { if ( asset.ToLower() == "assets/plugins/x86/oculusplugin.dll" || asset.ToLower() == "assets/plugins/x86_64/oculusplugin.dll" ) { Debug.Log( "[OVRImportProcessor] Updating plugin compatibility: " + asset ); PluginImporter pluginImporter = PluginImporter.GetAtPath( asset ) as PluginImporter; if ( pluginImporter != null ) { bool x86_64 = asset.Contains( "x86_64" ); pluginImporter.SetCompatibleWithEditor( true ); pluginImporter.SetCompatibleWithAnyPlatform( false ); pluginImporter.SetEditorData( "OS", "Windows" ); if ( x86_64 ) { pluginImporter.SetCompatibleWithPlatform( BuildTarget.StandaloneWindows, false ); pluginImporter.SetCompatibleWithPlatform( BuildTarget.StandaloneWindows64, true ); } else { pluginImporter.SetCompatibleWithPlatform( BuildTarget.StandaloneWindows64, false ); pluginImporter.SetCompatibleWithPlatform( BuildTarget.StandaloneWindows, true ); } } AssetDatabase.WriteImportSettingsIfDirty( asset ); } } #endif }
public static void SetEnabled(bool enabled) { var androidPathAAR = FileUtils.FixAssetPath(EditorConstants.EditorPathAndroidAAR); if (androidPathAAR == null || !FileUtils.AssetPathExists(androidPathAAR)) { Debug.LogErrorFormat("Can't {0} Android plugin: missing required file '{1}'. Re-install {2} to fix the issue.", enabled ? "enable" : "disable", androidPathAAR, Constants.PluginDisplayName); return; } var importer = (PluginImporter)PluginImporter.GetAtPath(androidPathAAR); if (importer == null) { Debug.LogErrorFormat("Can't {0} Android plugin: unable to create importer for '{1}'. Re-install {2} to fix the issue.", enabled ? "enable" : "disable", androidPathAAR, Constants.PluginDisplayName); return; } if (importer.GetCompatibleWithPlatform(BuildTarget.Android) != enabled) { importer.SetCompatibleWithPlatform(BuildTarget.Android, enabled); importer.SaveAndReimport(); } }
public static void EnforcePluginPlatformSettings(PluginPlatform platform) { string path = GetPlatformPluginPath(platform); if (!Directory.Exists(path) && !File.Exists(path)) { path += PluginDisabledSuffix; } if ((Directory.Exists(path)) || (File.Exists(path))) { string basePath = GetCurrentProjectPath(); string relPath = path.Substring(basePath.Length + 1); PluginImporter pi = PluginImporter.GetAtPath(relPath) as PluginImporter; if (pi == null) { return; } // Disable support for all platforms, then conditionally enable desired support below pi.SetCompatibleWithEditor(false); pi.SetCompatibleWithAnyPlatform(false); pi.SetCompatibleWithPlatform(BuildTarget.Android, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneLinux, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneLinux64, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneLinuxUniversal, false); #if UNITY_2017_3_OR_NEWER pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, false); #else pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXUniversal, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel64, false); #endif switch (platform) { case PluginPlatform.Android32: pi.SetCompatibleWithPlatform(BuildTarget.Android, true); pi.SetPlatformData(BuildTarget.Android, "CPU", "ARMv7"); break; case PluginPlatform.Android64: pi.SetCompatibleWithPlatform(BuildTarget.Android, true); pi.SetPlatformData(BuildTarget.Android, "CPU", "ARM64"); break; default: throw new ArgumentException("Attempted to enable platform support for unsupported platform: " + platform); } AssetDatabase.ImportAsset(relPath, ImportAssetOptions.ForceUpdate); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); } }
void SelectStaticLib() { const string pluginPath = "Packages/com.unity.xr.arkit/Runtime/iOS"; LibUtil.SelectPlugin( PluginImporter.GetAtPath($"{pluginPath}/Xcode1000/libUnityARKit.a") as PluginImporter, PluginImporter.GetAtPath($"{pluginPath}/Xcode1100/libUnityARKit.a") as PluginImporter); }
public void OnPreprocessBuild(BuildReport report) { if (report.summary.platform == BuildTarget.iOS) { const string pluginPath = "Packages/com.unity.xr.arkit-face-tracking/Runtime/iOS"; LibUtil.SelectPlugin( PluginImporter.GetAtPath($"{pluginPath}/Xcode1000/libUnityARKitFaceTracking.a") as PluginImporter, PluginImporter.GetAtPath($"{pluginPath}/Xcode1100/libUnityARKitFaceTracking.a") as PluginImporter); } }
static void AddPlugin(string editorDir, string pluginDir) { if (Directory.Exists(pluginDir)) { return; } // create plugin directory structure Debug.Log("Creating plugin dir: " + pluginDir); string[] components = pluginDir.Split('/'); // get path components if (components.Length == 0 || components[0] != "Assets") { Debug.LogError("Can't add " + Constants.PluginName + ". Unexpected plugin path: " + pluginDir); return; } string path = "Assets"; for (int i = 1; i < components.Length; ++i) { string subpath = path + "/" + components[i]; // can't use Path.Combine since it will screw it up on Windows if (!Directory.Exists(subpath)) { AssetDatabase.CreateFolder(path, components[i]); } path = subpath; } // copy plugin files string[] pluginFiles = { "AndroidManifest.xml", "project.properties", "libs", "res" }; foreach (string pluginFile in pluginFiles) { string srcPath = editorDir + "/" + pluginFile; string dstPath = pluginDir + "/" + pluginFile; AssetDatabase.CopyAsset(srcPath, dstPath); } PluginImporter pluginImporter = PluginImporter.GetAtPath(pluginDir) as PluginImporter; pluginImporter.SetCompatibleWithAnyPlatform(false); pluginImporter.SetCompatibleWithPlatform(BuildTarget.Android, true); AssetDatabase.ImportAsset(pluginDir, ImportAssetOptions.ImportRecursive); }
static void prepareWin10() { PluginImporter pi = (PluginImporter)PluginImporter.GetAtPath("Assets/Plugins/Metro/VungleSDKProxy.winmd"); pi.SetPlatformData(BuildTarget.WSAPlayer, "PlaceholderPath", "Assets/Plugins/VungleSDKProxy.dll"); pi.SaveAndReimport(); pi = (PluginImporter)PluginImporter.GetAtPath("Assets/Plugins/Metro/VungleSDK.winmd"); pi.SetPlatformData(BuildTarget.WSAPlayer, "SDK", "SDK81"); pi = (PluginImporter)PluginImporter.GetAtPath("Assets/Plugins/Metro/UWP/VungleSDK.winmd"); pi.SetCompatibleWithPlatform(BuildTarget.WSAPlayer, true); pi.SetPlatformData(BuildTarget.WSAPlayer, "SDK", "UWP"); pi.SaveAndReimport(); }
private static void SetPluginCompatibleAnyPlatform(string path, bool enable) { if (File.Exists(path) == true || Directory.Exists(path) == true) { PluginImporter pluginImporter = PluginImporter.GetAtPath(path) as PluginImporter; if (pluginImporter != null) { if (pluginImporter.GetCompatibleWithAnyPlatform() != enable) { pluginImporter.SetCompatibleWithAnyPlatform(enable); pluginImporter.SaveAndReimport(); } } } }
private static void Enable(params AndroidStore[] enabled) { foreach (AndroidStore p in Enum.GetValues(typeof(AndroidStore))) { string path = string.Format("Assets/Plugins/UnityPurchasing/Bin/Android/{0}.aar", p); var importer = (PluginImporter)PluginImporter.GetAtPath(path); if (null != importer) { var enable = Array.Exists(enabled, x => x == p); importer.SetCompatibleWithPlatform(BuildTarget.Android, enable); } } SetAndroidMode(enabled); }
public override void PostBuild(NativePlugin plugin, NativeBuildOptions buildOptions) { base.PostBuild(plugin, buildOptions); string assetFile = CombinePath( AssetDatabase.GetAssetPath(plugin.pluginBinaryFolder), "WebGL", string.Format("{0}.bc", plugin.Name)); PluginImporter pluginImporter = PluginImporter.GetAtPath((assetFile)) as PluginImporter; if (pluginImporter != null) { SetPluginBaseInfo(plugin, buildOptions, pluginImporter); pluginImporter.SaveAndReimport(); } }
public bool IsWin64Enabled() { string path = ""; if (Plugins.TryGetValue(PluginPlatform.Win64, out path)) { if (File.Exists(path)) { string basePath = GetCurrentProjectPath(); string relPath = path.Substring(basePath.Length + 1); PluginImporter pi = PluginImporter.GetAtPath(relPath) as PluginImporter; if (pi != null) { return(pi.GetCompatibleWithPlatform(BuildTarget.StandaloneWindows64) && pi.GetCompatibleWithEditor()); } } } return(false); }
public override void PostBuild(NativePlugin plugin, NativeBuildOptions buildOptions) { base.PostBuild(plugin, buildOptions); string assetFile = CombinePath( AssetDatabase.GetAssetPath(plugin.pluginBinaryFolder), "iOS", string.Format("lib{0}.a", plugin.Name)); PluginImporter pluginImporter = PluginImporter.GetAtPath((assetFile)) as PluginImporter; if (pluginImporter != null) { SetPluginBaseInfo(plugin, buildOptions, pluginImporter); pluginImporter.SetCompatibleWithAnyPlatform(false); pluginImporter.SetCompatibleWithPlatform(BuildTarget.iOS, true); pluginImporter.SaveAndReimport(); } }
public bool IsAndroidUniversalEnabled() { string path = ""; if (Plugins.TryGetValue(PluginPlatform.AndroidUniversal, out path)) { if (File.Exists(path)) { string basePath = GetCurrentProjectPath(); string relPath = path.Substring(basePath.Length + 1); PluginImporter pi = PluginImporter.GetAtPath(relPath) as PluginImporter; if (pi != null) { return(pi.GetCompatibleWithPlatform(BuildTarget.Android)); } } } return(false); }
public override void PostBuild(NativePlugin plugin, NativeBuildOptions buildOptions) { base.PostBuild(plugin, buildOptions); string assetFile = CombinePath( AssetDatabase.GetAssetPath(plugin.pluginBinaryFolder), "WSA", buildOptions.Architecture.ToString(), string.Format("{0}.dll", plugin.Name)); PluginImporter pluginImporter = PluginImporter.GetAtPath((assetFile)) as PluginImporter; if (pluginImporter != null) { SetPluginBaseInfo(plugin, buildOptions, pluginImporter); pluginImporter.SetCompatibleWithAnyPlatform(false); pluginImporter.SetCompatibleWithPlatform(BuildTarget.WSAPlayer, true); pluginImporter.SetPlatformData(BuildTarget.WSAPlayer, "CPU", buildOptions.Architecture.ToString()); pluginImporter.SaveAndReimport(); } }
public _PluginImporterSetter(BuildTarget buildTarget, string pluginName) { _buildTarget = buildTarget; _pluginName = pluginName; _pluginImporter = PluginImporter.GetAtPath(pluginName) as PluginImporter; }
/// <summary> /// Generates an AOT DLL, using the given parameters. /// </summary> public static void GenerateDLL(string dirPath, string assemblyName, List <Type> supportSerializedTypes, bool generateLinkXml = true) { if (!dirPath.EndsWith("/")) { dirPath += "/"; } var newDllPath = dirPath + assemblyName; var fullDllPath = newDllPath + ".dll"; var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName() { Name = assemblyName }, AssemblyBuilderAccess.Save, dirPath); var module = assembly.DefineDynamicModule(assemblyName); assembly.SetCustomAttribute(new CustomAttributeBuilder(typeof(EmittedAssemblyAttribute).GetConstructor(new Type[0]), new object[0])); // The following is a fix for Unity's crappy Mono runtime that doesn't know how to do this sort // of stuff properly // // We must manually remove the "Default Dynamic Assembly" module that is automatically defined, // otherwise a reference to that non-existent module will be saved into the assembly's IL, and // that will cause a multitude of issues. // // We do this by forcing there to be only one module - the one we just defined, and we set the // manifest module to be that module as well. { var modulesField = assembly.GetType().GetField("modules", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var manifestModuleField = assembly.GetType().GetField("manifest_module", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (modulesField != null) { modulesField.SetValue(assembly, new ModuleBuilder[] { module }); } if (manifestModuleField != null) { manifestModuleField.SetValue(assembly, module); } } var type = module.DefineType(assemblyName + ".PreventCodeStrippingViaReferences", TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.NotPublic); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(typeof(PreserveAttribute).GetConstructor(Type.EmptyTypes), new object[0]); type.SetCustomAttribute(attributeBuilder); var staticConstructor = type.DefineTypeInitializer(); var il = staticConstructor.GetILGenerator(); HashSet <Type> seenTypes = new HashSet <Type>(); //var endPoint = il.DefineLabel(); //il.Emit(OpCodes.Br, endPoint); foreach (var serializedType in supportSerializedTypes) { if (serializedType == null) { continue; } if (serializedType.IsAbstract || serializedType.IsInterface) { Debug.LogError("Skipping type '" + serializedType.GetNiceFullName() + "'! Type is abstract or an interface."); continue; } if (serializedType.IsGenericType && (serializedType.IsGenericTypeDefinition || !serializedType.IsFullyConstructedGenericType())) { Debug.LogError("Skipping type '" + serializedType.GetNiceFullName() + "'! Type is a generic type definition, or its arguments contain generic parameters; type must be a fully constructed generic type."); continue; } if (seenTypes.Contains(serializedType)) { continue; } seenTypes.Add(serializedType); // Reference serialized type { if (serializedType.IsValueType) { var local = il.DeclareLocal(serializedType); il.Emit(OpCodes.Ldloca, local); il.Emit(OpCodes.Initobj, serializedType); } else { var constructor = serializedType.GetConstructor(Type.EmptyTypes); if (constructor != null) { il.Emit(OpCodes.Newobj, constructor); il.Emit(OpCodes.Pop); } } } // Reference and/or create formatter type if (!FormatterUtilities.IsPrimitiveType(serializedType) && !typeof(UnityEngine.Object).IsAssignableFrom(serializedType)) { var actualFormatter = FormatterLocator.GetFormatter(serializedType, SerializationPolicies.Unity); if (actualFormatter.GetType().IsDefined <EmittedFormatterAttribute>()) { //TODO: Make emitted formatter code compatible with IL2CPP //// Emit an actual AOT formatter into the generated assembly //if (this.emitAOTFormatters) //{ // var emittedFormatter = FormatterEmitter.EmitAOTFormatter(typeEntry.Type, module, SerializationPolicies.Unity); // var emittedFormatterConstructor = emittedFormatter.GetConstructor(Type.EmptyTypes); // il.Emit(OpCodes.Newobj, emittedFormatterConstructor); // il.Emit(OpCodes.Pop); //} } var formatters = FormatterLocator.GetAllCompatiblePredefinedFormatters(serializedType, SerializationPolicies.Unity); foreach (var formatter in formatters) { // Reference the pre-existing formatter var formatterConstructor = formatter.GetType().GetConstructor(Type.EmptyTypes); if (formatterConstructor != null) { il.Emit(OpCodes.Newobj, formatterConstructor); il.Emit(OpCodes.Pop); } } //// Make sure we have a proper reflection formatter variant if all else goes wrong //il.Emit(OpCodes.Newobj, typeof(ReflectionFormatter<>).MakeGenericType(serializedType).GetConstructor(Type.EmptyTypes)); //il.Emit(OpCodes.Pop); } ConstructorInfo serializerConstructor; // Reference serializer variant if (serializedType.IsEnum) { serializerConstructor = typeof(EnumSerializer <>).MakeGenericType(serializedType).GetConstructor(Type.EmptyTypes); } else { serializerConstructor = typeof(ComplexTypeSerializer <>).MakeGenericType(serializedType).GetConstructor(Type.EmptyTypes); } il.Emit(OpCodes.Newobj, serializerConstructor); il.Emit(OpCodes.Pop); } //il.MarkLabel(endPoint); il.Emit(OpCodes.Ret); type.CreateType(); if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } if (File.Exists(fullDllPath)) { File.Delete(fullDllPath); } if (File.Exists(fullDllPath + ".meta")) { File.Delete(fullDllPath + ".meta"); } try { AssetDatabase.Refresh(); } catch (Exception) { // Sigh, Unity 5.3.0 } assembly.Save(assemblyName); File.Move(newDllPath, fullDllPath); if (generateLinkXml) { File.WriteAllText(dirPath + "link.xml", @"<linker> <assembly fullname=""" + assemblyName + @""" preserve=""all""/> </linker>"); } try { AssetDatabase.Refresh(); } catch (Exception) { // Sigh, Unity 5.3.0 } var pluginImporter = PluginImporter.GetAtPath(fullDllPath) as PluginImporter; if (pluginImporter != null) { //pluginImporter.ClearSettings(); pluginImporter.SetCompatibleWithEditor(false); pluginImporter.SetCompatibleWithAnyPlatform(true); // Disable for all standalones pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneLinux, false); pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneLinux64, false); pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneLinuxUniversal, false); // StandaloneOSXUniversal (<= 2017.2) / StandaloneOSX (>= 2017.3) pluginImporter.SetCompatibleWithPlatform((BuildTarget)2, false); if (!UnityVersion.IsVersionOrGreater(2017, 3)) { pluginImporter.SetCompatibleWithPlatform((BuildTarget)4, false); // StandaloneOSXIntel pluginImporter.SetCompatibleWithPlatform((BuildTarget)27, false); // StandaloneOSXIntel64 } pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false); pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false); //pluginImporter.SetCompatibleWithPlatform(BuildTarget.Android, false); pluginImporter.SaveAndReimport(); } AssetDatabase.SaveAssets(); }
private static void EnablePluginPackage(PluginPackage pluginPkg) { foreach (var kvp in pluginPkg.Plugins) { BuildTarget platform = kvp.Key; string path = kvp.Value; if ((Directory.Exists(path + GetDisabledPluginSuffix())) || (File.Exists(path + GetDisabledPluginSuffix()))) { string basePath = GetCurrentProjectPath(); string relPath = path.Substring(basePath.Length + 1); AssetDatabase.MoveAsset(relPath + GetDisabledPluginSuffix(), relPath); AssetDatabase.ImportAsset(relPath, ImportAssetOptions.ForceUpdate); PluginImporter pi = PluginImporter.GetAtPath(relPath) as PluginImporter; if (pi == null) { continue; } pi.SetCompatibleWithAnyPlatform(false); switch (platform) { case BuildTarget.Android: pi.SetCompatibleWithPlatform(BuildTarget.Android, true); pi.SetPlatformData(BuildTarget.Android, "CPU", "ARMv7"); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel64, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false); pi.SetCompatibleWithEditor(false); break; case BuildTarget.StandaloneOSX: pi.SetCompatibleWithPlatform(BuildTarget.Android, false); pi.SetPlatformData(BuildTarget.Android, "CPU", "ARMv7"); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, true); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel, true); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel64, true); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "AnyCPU"); pi.SetEditorData("OS", "OSX"); pi.SetPlatformData("Editor", "CPU", "AnyCPU"); pi.SetPlatformData("Editor", "OS", "OSX"); break; case BuildTarget.StandaloneWindows: pi.SetCompatibleWithPlatform(BuildTarget.Android, false); pi.SetPlatformData(BuildTarget.Android, "CPU", "ARMv7"); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel64, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, true); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "X86"); pi.SetEditorData("OS", "Windows"); pi.SetPlatformData("Editor", "CPU", "X86"); pi.SetPlatformData("Editor", "OS", "Windows"); break; case BuildTarget.StandaloneWindows64: pi.SetCompatibleWithPlatform(BuildTarget.Android, false); pi.SetPlatformData(BuildTarget.Android, "CPU", "ARMv7"); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel64, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, true); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "X86_64"); pi.SetEditorData("OS", "Windows"); pi.SetPlatformData("Editor", "CPU", "X86_64"); pi.SetPlatformData("Editor", "OS", "Windows"); break; default: throw new ArgumentException("Attempted EnablePluginPackage() for unsupported BuildTarget: " + platform); } AssetDatabase.ImportAsset(relPath, ImportAssetOptions.ForceUpdate); } } AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); }
private static void AttemptSpatializerPluginUpdate(bool triggeredByAutoUpdate) { // We use a simplified path to update spatializer plugins: // If there is a new AudioPluginOculusSpatializer.dll.new, we'll rename the original one to .old, and the new one to .dll, and restart the editor string pluginsPath = GetSpatializerPluginsRootPath(); string newX86PluginPath = Path.GetFullPath(Path.Combine(pluginsPath, "x86/AudioPluginOculusSpatializer.dll.new")); string newX64PluginPath = Path.GetFullPath(Path.Combine(pluginsPath, "x86_64/AudioPluginOculusSpatializer.dll.new")); if (File.Exists(newX86PluginPath) || File.Exists(newX64PluginPath)) { bool userAcceptsUpdate = false; if (unityRunningInBatchmode) { userAcceptsUpdate = true; } else { int dialogResult = EditorUtility.DisplayDialogComplex("Update Spatializer Plugins", "New spatializer plugin found. Do you want to upgrade? If you choose 'Upgrade', the old plugin will be renamed to AudioPluginOculusSpatializer.old", "Upgrade", "Don't upgrade", "Delete new plugin"); if (dialogResult == 0) { userAcceptsUpdate = true; } else if (dialogResult == 1) { // do nothing } else if (dialogResult == 2) { try { File.Delete(newX86PluginPath); File.Delete(newX86PluginPath + ".meta"); File.Delete(newX64PluginPath); File.Delete(newX64PluginPath + ".meta"); } catch (Exception e) { UnityEngine.Debug.LogWarning("Exception happened when deleting new spatializer plugin: " + e.Message); } } } if (userAcceptsUpdate) { bool upgradeDone = false; string curX86PluginPath = Path.Combine(pluginsPath, "x86/AudioPluginOculusSpatializer.dll"); if (File.Exists(newX86PluginPath)) { RenameSpatializerPluginToOld(curX86PluginPath); try { File.Move(newX86PluginPath, curX86PluginPath); File.Move(newX86PluginPath + ".meta", curX86PluginPath + ".meta"); // fix the platform string curX86PluginPathRel = "Assets/Oculus/Spatializer/Plugins/x86/AudioPluginOculusSpatializer.dll"; UnityEngine.Debug.Log("path = " + curX86PluginPathRel); AssetDatabase.ImportAsset(curX86PluginPathRel, ImportAssetOptions.ForceUpdate); PluginImporter pi = PluginImporter.GetAtPath(curX86PluginPathRel) as PluginImporter; pi.SetCompatibleWithEditor(false); pi.SetCompatibleWithAnyPlatform(false); pi.SetCompatibleWithPlatform(BuildTarget.Android, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false); #if UNITY_2017_3_OR_NEWER pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, false); #else pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXUniversal, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel64, false); #endif pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, true); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "X86"); pi.SetEditorData("OS", "Windows"); pi.SetPlatformData("Editor", "CPU", "X86"); pi.SetPlatformData("Editor", "OS", "Windows"); AssetDatabase.ImportAsset(curX86PluginPathRel, ImportAssetOptions.ForceUpdate); AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); upgradeDone = true; } catch (Exception e) { UnityEngine.Debug.LogWarning("Unable to rename the new spatializer plugin: " + e.Message); } } string curX64PluginPath = Path.Combine(pluginsPath, "x86_64/AudioPluginOculusSpatializer.dll"); if (File.Exists(newX64PluginPath)) { RenameSpatializerPluginToOld(curX64PluginPath); try { File.Move(newX64PluginPath, curX64PluginPath); File.Move(newX64PluginPath + ".meta", curX64PluginPath + ".meta"); // fix the platform string curX64PluginPathRel = "Assets/Oculus/Spatializer/Plugins/x86_64/AudioPluginOculusSpatializer.dll"; UnityEngine.Debug.Log("path = " + curX64PluginPathRel); AssetDatabase.ImportAsset(curX64PluginPathRel, ImportAssetOptions.ForceUpdate); PluginImporter pi = PluginImporter.GetAtPath(curX64PluginPathRel) as PluginImporter; pi.SetCompatibleWithEditor(false); pi.SetCompatibleWithAnyPlatform(false); pi.SetCompatibleWithPlatform(BuildTarget.Android, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false); #if UNITY_2017_3_OR_NEWER pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, false); #else pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXUniversal, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel64, false); #endif pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, true); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "X86_64"); pi.SetEditorData("OS", "Windows"); pi.SetPlatformData("Editor", "CPU", "X86_64"); pi.SetPlatformData("Editor", "OS", "Windows"); AssetDatabase.ImportAsset(curX64PluginPathRel, ImportAssetOptions.ForceUpdate); AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); upgradeDone = true; } catch (Exception e) { UnityEngine.Debug.LogWarning("Unable to rename the new spatializer plugin: " + e.Message); } } if (upgradeDone) { if (unityRunningInBatchmode || EditorUtility.DisplayDialog("Restart Unity", "Spatializer plugins has been upgraded." + "\n\nPlease restart the Unity Editor to complete the update process." #if !UNITY_2017_1_OR_NEWER + " You may need to manually relaunch Unity if you are using Unity 5.6 and higher." #endif , "Restart", "Not Now")) { RestartUnityEditor(); } } } } }
private static void EnablePluginPackage(PluginPackage pluginPkg) { #if UNITY_2020_1_OR_NEWER bool activateOpenXRPlugin = pluginPkg.Version >= minimalProductionVersionForOpenXR; if (activateOpenXRPlugin && !unityRunningInBatchmode) { while (true) { // display a dialog to prompt developer to confirm if they want to proceed with OpenXR backend int result = EditorUtility.DisplayDialogComplex("OpenXR Backend", "OpenXR is now fully supported by Oculus. However, some of the functionalities are not supported in the baseline OpenXR spec, which would be provided in our future releases.\n\nIf you depend on the following features in your project, please click Cancel to continue using the legacy backend:\n\n 1. Advanced hand tracking features (collision capsule, input metadata, Thumb0, default handmesh)\n 2. Mixed Reality Capture on Rift\n\nNew features, such as Passthrough API, are only supported through the OpenXR backend.\n\nPlease check our release notes for more details.\n\nReminder: you can switch the legacy and OpenXR backends at any time from Oculus > Tools > OpenXR menu options.", "Use OpenXR", "Cancel", "Release Notes"); if (result == 0) { break; } else if (result == 1) { activateOpenXRPlugin = false; break; } else if (result == 2) { Application.OpenURL("https://developer.oculus.com/downloads/package/unity-integration/"); } else { UnityEngine.Debug.LogWarningFormat("Unrecognized result from DisplayDialogComplex: {0}", result); break; } } } #else bool activateOpenXRPlugin = false; #endif if (activateOpenXRPlugin) { UnityEngine.Debug.Log("OVRPlugin with OpenXR backend is activated by default"); if (!unityRunningInBatchmode) { EditorUtility.DisplayDialog("OVRPlugin", "OVRPlugin with OpenXR backend will be activated by default", "Ok"); } } else { UnityEngine.Debug.Log("OVRPlugin with LibOVR/VRAPI backend is activated by default"); if (!unityRunningInBatchmode) { EditorUtility.DisplayDialog("OVRPlugin", "OVRPlugin with LibOVR/VRAPI backend will be activated by default", "Ok"); } } foreach (var kvp in pluginPkg.Plugins) { PluginPlatform platform = kvp.Key; string path = kvp.Value; if ((Directory.Exists(path + GetDisabledPluginSuffix())) || (File.Exists(path + GetDisabledPluginSuffix()))) { string basePath = GetCurrentProjectPath(); string relPath = path.Substring(basePath.Length + 1); string relDisabledPath = relPath + GetDisabledPluginSuffix(); AssetDatabase.MoveAsset(relDisabledPath, relPath); AssetDatabase.ImportAsset(relPath, ImportAssetOptions.ForceUpdate); PluginImporter pi = PluginImporter.GetAtPath(relPath) as PluginImporter; if (pi == null) { continue; } // Disable support for all platforms, then conditionally enable desired support below pi.SetCompatibleWithEditor(false); pi.SetCompatibleWithAnyPlatform(false); pi.SetCompatibleWithPlatform(BuildTarget.Android, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, false); switch (platform) { case PluginPlatform.Android: pi.SetCompatibleWithPlatform(BuildTarget.Android, !unityVersionSupportsAndroidUniversal); if (!unityVersionSupportsAndroidUniversal) { pi.SetPlatformData(BuildTarget.Android, "CPU", "ARMv7"); } break; case PluginPlatform.AndroidUniversal: if (!activateOpenXRPlugin) { pi.SetCompatibleWithPlatform(BuildTarget.Android, unityVersionSupportsAndroidUniversal); } break; case PluginPlatform.AndroidOpenXR: if (activateOpenXRPlugin) { pi.SetCompatibleWithPlatform(BuildTarget.Android, unityVersionSupportsAndroidUniversal); } break; case PluginPlatform.OSXUniversal: pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, true); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "AnyCPU"); pi.SetEditorData("OS", "OSX"); pi.SetPlatformData("Editor", "CPU", "AnyCPU"); pi.SetPlatformData("Editor", "OS", "OSX"); break; case PluginPlatform.Win: pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, true); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "X86"); pi.SetEditorData("OS", "Windows"); pi.SetPlatformData("Editor", "CPU", "X86"); pi.SetPlatformData("Editor", "OS", "Windows"); break; case PluginPlatform.Win64: if (!activateOpenXRPlugin) { pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, true); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "X86_64"); pi.SetEditorData("OS", "Windows"); pi.SetPlatformData("Editor", "CPU", "X86_64"); pi.SetPlatformData("Editor", "OS", "Windows"); } break; case PluginPlatform.Win64OpenXR: if (activateOpenXRPlugin) { pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, true); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "X86_64"); pi.SetEditorData("OS", "Windows"); pi.SetPlatformData("Editor", "CPU", "X86_64"); pi.SetPlatformData("Editor", "OS", "Windows"); } break; default: throw new ArgumentException("Attempted EnablePluginPackage() for unsupported BuildTarget: " + platform); } AssetDatabase.ImportAsset(relPath, ImportAssetOptions.ForceUpdate); } } AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); }
// Unfortunately the UnityEditor API updates only the in-memory list of // files available to the build when what we want is a persistent modification // to the .meta files. So we must also rely upon the PostProcessScene attribute // below to process the private static void ConfigureProject(AppStore target) { foreach (var mapping in StoreSpecificFiles) { // All files enabled when store is determined at runtime. var enabled = target == AppStore.NotSpecified; // Otherwise this file must be needed on the target. enabled |= mapping.Value == target; string path = string.Format("{0}/{1}", BinPath, mapping.Key); PluginImporter importer = ((PluginImporter)PluginImporter.GetAtPath(path)); if (importer != null) { importer.SetCompatibleWithPlatform(BuildTarget.Android, enabled); } else { // Search for any occurrence of this file // Only fail if more than one found string[] paths = FindPaths(mapping.Key); if (paths.Length == 1) { importer = ((PluginImporter)PluginImporter.GetAtPath(paths[0])); importer.SetCompatibleWithPlatform(BuildTarget.Android, enabled); } } } var UdpBinPath = IsUdpUmpPackageInstalled() ? PackManUdpBinPath : IsUdpAssetStorePackageInstalled() ? AssetStoreUdpBinPath : null; if (s_udpAvailable && !string.IsNullOrEmpty(UdpBinPath)) { foreach (var mapping in UdpSpecificFiles) { // All files enabled when store is determined at runtime. var enabled = target == AppStore.NotSpecified; // Otherwise this file must be needed on the target. enabled |= mapping.Value == target; var path = $"{UdpBinPath}/{mapping.Key}"; PluginImporter importer = ((PluginImporter)PluginImporter.GetAtPath(path)); if (importer != null) { importer.SetCompatibleWithPlatform(BuildTarget.Android, enabled); } else { // Search for any occurrence of this file // Only fail if more than one found string[] paths = FindPaths(mapping.Key); if (paths.Length == 1) { importer = ((PluginImporter)PluginImporter.GetAtPath(paths[0])); importer.SetCompatibleWithPlatform(BuildTarget.Android, enabled); } } } } }
public static void Check() { PluginImporter pluginIL2CPP = (PluginImporter)PluginImporter.GetAtPath(pathIL2CPP); PluginImporter pluginMONO = (PluginImporter)PluginImporter.GetAtPath(pathMONO); PluginImporter pluginIOS = (PluginImporter)PluginImporter.GetAtPath(pathIOS); if (pluginIL2CPP == null) { Debug.LogError("Il2cpp Dll not found: " + pathIL2CPP); return; } if (pluginMONO == null) { Debug.LogError("Mono Dll not found: " + pathMONO); return; } if (pluginIOS == null) { Debug.LogError("IOS Dll not found: " + pathIOS); return; } BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget; BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget); ScriptingImplementation backend = PlayerSettings.GetScriptingBackend(buildTargetGroup); Debug.Log("Current Scripting Backend " + PlayerSettings.GetScriptingBackend(buildTargetGroup) + " Target:" + buildTargetGroup); bool useStructureSensor = false; if (buildTargetGroup == BuildTargetGroup.iOS) { #if use_structure_sensor useStructureSensor = true; #else Debug.Log("If you need to use Structure Sensor add use_structure_sensor to Scripting Define Symbols in Player Settings..."); #endif Debug.Log("Used Structure Sensor: " + useStructureSensor); } if (buildTargetGroup == BuildTargetGroup.iOS) { SwitchDll.SwitchCompatibleWithPlatform(pluginMONO, false); if (useStructureSensor) { SwitchDll.SwitchCompatibleWithPlatform(pluginIL2CPP, false); SwitchDll.SwitchCompatibleWithPlatform(pluginIOS, true); } else { SwitchDll.SwitchCompatibleWithPlatform(pluginIL2CPP, true); SwitchDll.SwitchCompatibleWithPlatform(pluginIOS, false); } } else if ((buildTargetGroup == BuildTargetGroup.Android || buildTargetGroup == BuildTargetGroup.Standalone) && backend == ScriptingImplementation.IL2CPP) { SwitchDll.SwitchCompatibleWithPlatform(pluginIL2CPP, true); SwitchDll.SwitchCompatibleWithPlatform(pluginMONO, false); SwitchDll.SwitchCompatibleWithPlatform(pluginIOS, false); } else { SwitchDll.SwitchCompatibleWithPlatform(pluginIL2CPP, false); SwitchDll.SwitchCompatibleWithPlatform(pluginMONO, true); SwitchDll.SwitchCompatibleWithPlatform(pluginIOS, false); } }
private static void ActivateOVRPluginOpenXR() { if (!unityVersionSupportsAndroidUniversal) { UnityEngine.Debug.LogError("Unexpected error: Unity must support AndroidUniversal version of Oculus Utilities Plugin for accessing OpenXR"); return; } if (OVRPluginUpdaterStub.IsInsidePackageDistribution()) { UnityEngine.Debug.LogError("Unable to change plugin when using package distribution"); return; } #if !USING_XR_SDK && !REQUIRES_XR_SDK UnityEngine.Debug.LogError("Oculus Utilities Plugin with OpenXR only supports XR Plug-in Managmenent with Oculus XR Plugin"); return; #else List <PluginPackage> allUtilsPluginPkgs = GetAllUtilitiesPluginPackages(); PluginPackage enabledUtilsPluginPkg = null; foreach (PluginPackage pluginPkg in allUtilsPluginPkgs) { if (pluginPkg.IsEnabled()) { enabledUtilsPluginPkg = pluginPkg; break; } } if (enabledUtilsPluginPkg == null) { UnityEngine.Debug.LogError("Unable to Activate OVRPlugin with OpenXR: Oculus Utilities Plugin package not activated"); return; } if (!enabledUtilsPluginPkg.IsAndroidOpenXRPresent() && !enabledUtilsPluginPkg.IsWin64OpenXRPresent()) { UnityEngine.Debug.LogError("Unable to Activate OVRPlugin with OpenXR: Both AndroidOpenXR/OVRPlugin.aar or Win64OpenXR/OVRPlugin.dll does not exist"); return; } if (enabledUtilsPluginPkg.IsAndroidOpenXREnabled() && enabledUtilsPluginPkg.IsWin64OpenXREnabled()) { if (!unityRunningInBatchmode) { EditorUtility.DisplayDialog("Unable to Activate OVRPlugin with OpenXR", "Both AndroidOpenXR/OVRPlugin.aar and Win64OpenXR/OVRPlugin.dll already enabled", "Ok"); } return; } if (enabledUtilsPluginPkg.Version < minimalProductionVersionForOpenXR) { if (!unityRunningInBatchmode) { bool accepted = EditorUtility.DisplayDialog("Warning", "OVRPlugin with OpenXR backend is experimental before v31. You may expect to encounter stability issues and/or missing functionalities, " + "including but not limited to, fixed foveated rendering / composition layer / display refresh rates / etc." + "\n\n" + "Also, OVRPlugin with OpenXR backend only supports XR Plug-in Managmenent with Oculus XR Plugin on Quest", "Continue", "Cancel"); if (!accepted) { return; } } } if (enabledUtilsPluginPkg.IsAndroidOpenXRPresent() && !enabledUtilsPluginPkg.IsAndroidOpenXREnabled()) { if (enabledUtilsPluginPkg.IsAndroidUniversalEnabled()) { string androidUniveralPluginPath = enabledUtilsPluginPkg.Plugins[PluginPlatform.AndroidUniversal]; string androidUniveralPluginBasePath = GetCurrentProjectPath(); string androidUniveralPluginRelPath = androidUniveralPluginPath.Substring(androidUniveralPluginBasePath.Length + 1); PluginImporter pi = PluginImporter.GetAtPath(androidUniveralPluginRelPath) as PluginImporter; if (pi != null) { pi.SetCompatibleWithPlatform(BuildTarget.Android, false); AssetDatabase.ImportAsset(androidUniveralPluginRelPath, ImportAssetOptions.ForceUpdate); } else { UnityEngine.Debug.LogWarning("Unable to find PluginImporter: " + androidUniveralPluginRelPath); } } { string androidOpenXRPluginPath = enabledUtilsPluginPkg.Plugins[PluginPlatform.AndroidOpenXR]; string androidOpenXRPluginBasePath = GetCurrentProjectPath(); string androidOpenXRPluginRelPath = androidOpenXRPluginPath.Substring(androidOpenXRPluginBasePath.Length + 1); PluginImporter pi = PluginImporter.GetAtPath(androidOpenXRPluginRelPath) as PluginImporter; if (pi != null) { pi.SetCompatibleWithPlatform(BuildTarget.Android, true); AssetDatabase.ImportAsset(androidOpenXRPluginRelPath, ImportAssetOptions.ForceUpdate); } else { UnityEngine.Debug.LogWarning("Unable to find PluginImporter: " + androidOpenXRPluginRelPath); } } } bool win64PluginUpdated = false; if (enabledUtilsPluginPkg.IsWin64OpenXRPresent() && !enabledUtilsPluginPkg.IsWin64OpenXREnabled()) { if (enabledUtilsPluginPkg.IsWin64Enabled()) { string win64PluginPath = enabledUtilsPluginPkg.Plugins[PluginPlatform.Win64]; string win64PluginBasePath = GetCurrentProjectPath(); string win64PluginRelPath = win64PluginPath.Substring(win64PluginBasePath.Length + 1); PluginImporter pi = PluginImporter.GetAtPath(win64PluginRelPath) as PluginImporter; if (pi != null) { pi.ClearSettings(); pi.SetCompatibleWithEditor(false); pi.SetCompatibleWithAnyPlatform(false); AssetDatabase.ImportAsset(win64PluginRelPath, ImportAssetOptions.ForceUpdate); } else { UnityEngine.Debug.LogWarning("Unable to find PluginImporter: " + win64PluginRelPath); } } { string win64OpenXRPluginPath = enabledUtilsPluginPkg.Plugins[PluginPlatform.Win64OpenXR]; string win64OpenXRPluginBasePath = GetCurrentProjectPath(); string win64OpenXRPluginRelPath = win64OpenXRPluginPath.Substring(win64OpenXRPluginBasePath.Length + 1); PluginImporter pi = PluginImporter.GetAtPath(win64OpenXRPluginRelPath) as PluginImporter; if (pi != null) { pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, true); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "X86_64"); pi.SetEditorData("OS", "Windows"); pi.SetPlatformData("Editor", "CPU", "X86_64"); pi.SetPlatformData("Editor", "OS", "Windows"); AssetDatabase.ImportAsset(win64OpenXRPluginRelPath, ImportAssetOptions.ForceUpdate); } else { UnityEngine.Debug.LogWarning("Unable to find PluginImporter: " + win64OpenXRPluginRelPath); } } win64PluginUpdated = true; } AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); if (!unityRunningInBatchmode) { EditorUtility.DisplayDialog("Activate OVRPlugin with OpenXR", "Oculus Utilities Plugin with OpenXR has been enabled on Android", "Ok"); if (win64PluginUpdated && EditorUtility.DisplayDialog("Restart Unity", "Win64 plugin updated. Do you want to restart Unity editor?", "Restart", "Not Now")) { RestartUnityEditor(); } } #endif // !USING_XR_SDK }
private static void RestoreStandardOVRPlugin() { if (!unityVersionSupportsAndroidUniversal) // sanity check { UnityEngine.Debug.LogError("Unexpected error: Unity must support AndroidUniversal version of Oculus Utilities Plugin for accessing OpenXR"); return; } if (OVRPluginUpdaterStub.IsInsidePackageDistribution()) { UnityEngine.Debug.LogError("Unable to change plugin when using package distribution"); return; } List <PluginPackage> allUtilsPluginPkgs = GetAllUtilitiesPluginPackages(); PluginPackage enabledUtilsPluginPkg = null; foreach (PluginPackage pluginPkg in allUtilsPluginPkgs) { if (pluginPkg.IsEnabled()) { enabledUtilsPluginPkg = pluginPkg; break; } } if (enabledUtilsPluginPkg == null) { UnityEngine.Debug.LogError("Unable to Restore Standard Oculus Utilities Plugin: Oculus Utilities Plugin package not activated"); return; } if (!enabledUtilsPluginPkg.IsAndroidUniversalPresent() && !enabledUtilsPluginPkg.IsWin64Present()) { UnityEngine.Debug.LogError("Unable to Restore Standard Oculus Utilities Plugin: Both AndroidOpenXR/OVRPlugin.aar and Win64/OVRPlugin.dll does not exist"); return; } if (enabledUtilsPluginPkg.IsAndroidUniversalEnabled() && enabledUtilsPluginPkg.IsWin64Enabled()) { if (!unityRunningInBatchmode) { EditorUtility.DisplayDialog("Unable to Restore Standard Oculus Utilities Plugin", "Both AndroidUniversal/OVRPlugin.aar and Win64/OVRPlugin.dll already enabled", "Ok"); } return; } if (enabledUtilsPluginPkg.IsAndroidUniversalPresent() && !enabledUtilsPluginPkg.IsAndroidUniversalEnabled()) { if (enabledUtilsPluginPkg.IsAndroidOpenXREnabled()) { string androidOpenXRPluginPath = enabledUtilsPluginPkg.Plugins[PluginPlatform.AndroidOpenXR]; string androidOpenXRPluginBasePath = GetCurrentProjectPath(); string androidOpenXRPluginRelPath = androidOpenXRPluginPath.Substring(androidOpenXRPluginBasePath.Length + 1); PluginImporter pi = PluginImporter.GetAtPath(androidOpenXRPluginRelPath) as PluginImporter; if (pi != null) { pi.SetCompatibleWithPlatform(BuildTarget.Android, false); AssetDatabase.ImportAsset(androidOpenXRPluginRelPath, ImportAssetOptions.ForceUpdate); } else { UnityEngine.Debug.LogWarning("Unable to find PluginImporter: " + androidOpenXRPluginRelPath); } } { string androidUniveralPluginPath = enabledUtilsPluginPkg.Plugins[PluginPlatform.AndroidUniversal]; string androidUniveralPluginBasePath = GetCurrentProjectPath(); string androidUniveralPluginRelPath = androidUniveralPluginPath.Substring(androidUniveralPluginBasePath.Length + 1); PluginImporter pi = PluginImporter.GetAtPath(androidUniveralPluginRelPath) as PluginImporter; if (pi != null) { pi.SetCompatibleWithPlatform(BuildTarget.Android, true); AssetDatabase.ImportAsset(androidUniveralPluginRelPath, ImportAssetOptions.ForceUpdate); } else { UnityEngine.Debug.LogWarning("Unable to find PluginImporter: " + androidUniveralPluginRelPath); } } } bool win64PluginUpdated = false; if (enabledUtilsPluginPkg.IsWin64Present() && !enabledUtilsPluginPkg.IsWin64Enabled()) { if (enabledUtilsPluginPkg.IsWin64OpenXREnabled()) { string win64OpenXRPluginPath = enabledUtilsPluginPkg.Plugins[PluginPlatform.Win64OpenXR]; string win64OpenXRPluginBasePath = GetCurrentProjectPath(); string win64OpenXRPluginRelPath = win64OpenXRPluginPath.Substring(win64OpenXRPluginBasePath.Length + 1); PluginImporter pi = PluginImporter.GetAtPath(win64OpenXRPluginRelPath) as PluginImporter; if (pi != null) { pi.ClearSettings(); pi.SetCompatibleWithEditor(false); pi.SetCompatibleWithAnyPlatform(false); AssetDatabase.ImportAsset(win64OpenXRPluginRelPath, ImportAssetOptions.ForceUpdate); } else { UnityEngine.Debug.LogWarning("Unable to find PluginImporter: " + win64OpenXRPluginRelPath); } } { string win64PluginPath = enabledUtilsPluginPkg.Plugins[PluginPlatform.Win64]; string win64PluginBasePath = GetCurrentProjectPath(); string win64PluginRelPath = win64PluginPath.Substring(win64PluginBasePath.Length + 1); PluginImporter pi = PluginImporter.GetAtPath(win64PluginRelPath) as PluginImporter; if (pi != null) { pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, true); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "X86_64"); pi.SetEditorData("OS", "Windows"); pi.SetPlatformData("Editor", "CPU", "X86_64"); pi.SetPlatformData("Editor", "OS", "Windows"); AssetDatabase.ImportAsset(win64PluginRelPath, ImportAssetOptions.ForceUpdate); } else { UnityEngine.Debug.LogWarning("Unable to find PluginImporter: " + win64PluginRelPath); } } win64PluginUpdated = true; } AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); if (!unityRunningInBatchmode) { EditorUtility.DisplayDialog("Restore Standard OVRPlugin", "Standard version of Oculus Utilities Plugin has been enabled on Android", "Ok"); if (win64PluginUpdated && EditorUtility.DisplayDialog("Restart Unity", "Win64 plugin updated. Do you want to restart Unity editor?", "Restart", "Not Now")) { RestartUnityEditor(); } } }
/// <summary> /// Generates an AOT DLL, using the given parameters. /// </summary> public static void GenerateDLL(string dirPath, string assemblyName, List <Type> supportSerializedTypes, bool generateLinkXml = true) { #if UNITY_EDITOR && NET_4_6 if (!dirPath.EndsWith("/")) { dirPath += "/"; } var newDllPath = dirPath + assemblyName; var fullDllPath = newDllPath + ".dll"; var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName() { Name = assemblyName }, AssemblyBuilderAccess.Save, dirPath); var module = assembly.DefineDynamicModule(assemblyName); assembly.SetCustomAttribute(new CustomAttributeBuilder(typeof(EmittedAssemblyAttribute).GetConstructor(new Type[0]), new object[0])); // VRChat Edit: Add the UnityAPICompatibilityVersion Attribute for the current version of Unity to skip API Updating. #if UNITY_2019 assembly.SetCustomAttribute(new CustomAttributeBuilder( typeof(UnityAPICompatibilityVersionAttribute).GetConstructor(new[] { typeof(string), typeof(bool) }), new object[] { Application.unityVersion, true }) ); #else assembly.SetCustomAttribute(new CustomAttributeBuilder( typeof(UnityAPICompatibilityVersionAttribute).GetConstructor(new[] { typeof(string) }), new object[] { Application.unityVersion }) ); #endif // The following is a fix for Unity's crappy Mono runtime that doesn't know how to do this sort // of stuff properly // // We must manually remove the "Default Dynamic Assembly" module that is automatically defined, // otherwise a reference to that non-existent module will be saved into the assembly's IL, and // that will cause a multitude of issues. // // We do this by forcing there to be only one module - the one we just defined, and we set the // manifest module to be that module as well. { var modulesField = assembly.GetType().GetField("modules", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var manifestModuleField = assembly.GetType().GetField("manifest_module", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (modulesField != null) { modulesField.SetValue(assembly, new ModuleBuilder[] { module }); } if (manifestModuleField != null) { manifestModuleField.SetValue(assembly, module); } } var type = module.DefineType(assemblyName + ".PreventCodeStrippingViaReferences", TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.NotPublic); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(typeof(PreserveAttribute).GetConstructor(Type.EmptyTypes), new object[0]); type.SetCustomAttribute(attributeBuilder); var staticConstructor = type.DefineTypeInitializer(); var il = staticConstructor.GetILGenerator(); var falseLocal = il.DeclareLocal(typeof(bool)); il.Emit(OpCodes.Ldc_I4_0); // Load false il.Emit(OpCodes.Stloc, falseLocal); // Set to falseLocal HashSet <Type> seenTypes = new HashSet <Type>(); if (UnityVersion.Major == 2019 && UnityVersion.Minor == 2) { // This here is a hack that fixes Unity's assembly updater triggering faultily in Unity 2019.2 // (and in early 2019.3 alphas/betas, but we're not handling those). When it triggers, it edits // the generated AOT assembly such that it immediately causes Unity to hard crash. Having this // type reference present in the assembly prevents that from happening. (Any concrete type in // the serialization assembly would work, this one is just a random pick.) // // Unity should have fixed this in 2019.3, but said that a backport to 2019.2 is not guaranteed // to occur, though it might. supportSerializedTypes.Add(typeof(DateTimeFormatter)); } //var endPoint = il.DefineLabel(); //il.Emit(OpCodes.Br, endPoint); foreach (var serializedType in supportSerializedTypes) { if (serializedType == null) { continue; } bool isAbstract = serializedType.IsAbstract || serializedType.IsInterface; if (serializedType.IsGenericType && (serializedType.IsGenericTypeDefinition || !serializedType.IsFullyConstructedGenericType())) { Debug.LogError("Skipping type '" + serializedType.GetNiceFullName() + "'! Type is a generic type definition, or its arguments contain generic parameters; type must be a fully constructed generic type."); continue; } if (seenTypes.Contains(serializedType)) { continue; } seenTypes.Add(serializedType); // Reference serialized type { if (serializedType.IsValueType) { var local = il.DeclareLocal(serializedType); il.Emit(OpCodes.Ldloca, local); il.Emit(OpCodes.Initobj, serializedType); } else if (!isAbstract) { var constructor = serializedType.GetConstructor(Type.EmptyTypes); if (constructor != null) { il.Emit(OpCodes.Newobj, constructor); il.Emit(OpCodes.Pop); } } } // Reference and/or create formatter type if (!FormatterUtilities.IsPrimitiveType(serializedType) && !typeof(UnityEngine.Object).IsAssignableFrom(serializedType) && !isAbstract) { var actualFormatter = FormatterLocator.GetFormatter(serializedType, SerializationPolicies.Unity); if (actualFormatter.GetType().IsDefined <EmittedFormatterAttribute>()) { //TODO: Make emitted formatter code compatible with IL2CPP //// Emit an actual AOT formatter into the generated assembly //if (this.emitAOTFormatters) //{ // var emittedFormatter = FormatterEmitter.EmitAOTFormatter(typeEntry.Type, module, SerializationPolicies.Unity); // var emittedFormatterConstructor = emittedFormatter.GetConstructor(Type.EmptyTypes); // il.Emit(OpCodes.Newobj, emittedFormatterConstructor); // il.Emit(OpCodes.Pop); //} } var formatters = FormatterLocator.GetAllCompatiblePredefinedFormatters(serializedType, SerializationPolicies.Unity); foreach (var formatter in formatters) { // Reference the pre-existing formatter var formatterConstructor = formatter.GetType().GetConstructor(Type.EmptyTypes); if (formatterConstructor != null) { il.Emit(OpCodes.Newobj, formatterConstructor); il.Emit(OpCodes.Pop); } } //// Make sure we have a proper reflection formatter variant if all else goes wrong //il.Emit(OpCodes.Newobj, typeof(ReflectionFormatter<>).MakeGenericType(serializedType).GetConstructor(Type.EmptyTypes)); //il.Emit(OpCodes.Pop); } ConstructorInfo serializerConstructor; // Reference serializer variant if (serializedType.IsValueType) { serializerConstructor = Serializer.Get(serializedType).GetType().GetConstructor(Type.EmptyTypes); il.Emit(OpCodes.Newobj, serializerConstructor); // The following section is a fix for an issue on IL2CPP for PS4, where sometimes bytecode isn't // generated for methods in base types of needed types - FX, Serializer<T>.ReadValueWeak() // may be missing. This only seems to happen in a relevant way for value types. { var endLabel = il.DefineLabel(); // Load a false local value, then jump to the end of this segment of code due to that // false value. This is an attempt to trick any potential code flow analysis made // by IL2CPP that checks whether this segment of code is actually run. // // We don't run the code because if we did, that would actually throw a bunch of // exceptions from invalid calls to ReadValueWeak and WriteValueWeak. il.Emit(OpCodes.Ldloc, falseLocal); il.Emit(OpCodes.Brfalse, endLabel); var baseSerializerType = typeof(Serializer <>).MakeGenericType(serializedType); var readValueWeakMethod = baseSerializerType.GetMethod("ReadValueWeak", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, new Type[] { typeof(IDataReader) }, null); var writeValueWeakMethod = baseSerializerType.GetMethod("WriteValueWeak", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, new Type[] { typeof(string), typeof(object), typeof(IDataWriter) }, null); il.Emit(OpCodes.Dup); // Duplicate serializer instance il.Emit(OpCodes.Ldnull); // Load null argument for IDataReader reader il.Emit(OpCodes.Callvirt, readValueWeakMethod); // Call ReadValueWeak on serializer instance il.Emit(OpCodes.Pop); // Pop result of ReadValueWeak il.Emit(OpCodes.Dup); // Duplicate serializer instance il.Emit(OpCodes.Ldnull); // Load null argument for string name il.Emit(OpCodes.Ldnull); // Load null argument for object value il.Emit(OpCodes.Ldnull); // Load null argument for IDataWriter writer il.Emit(OpCodes.Callvirt, writeValueWeakMethod); // Call WriteValueWeak on serializer instance il.MarkLabel(endLabel); // This is where the code always jumps to, skipping the above } il.Emit(OpCodes.Pop); // Pop the serializer instance } else { serializerConstructor = typeof(ComplexTypeSerializer <>).MakeGenericType(serializedType).GetConstructor(Type.EmptyTypes); il.Emit(OpCodes.Newobj, serializerConstructor); il.Emit(OpCodes.Pop); } } //il.MarkLabel(endPoint); il.Emit(OpCodes.Ret); type.CreateType(); if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } if (File.Exists(fullDllPath)) { File.Delete(fullDllPath); } if (File.Exists(fullDllPath + ".meta")) { File.Delete(fullDllPath + ".meta"); } try { AssetDatabase.Refresh(); } catch (Exception) { // Sigh, Unity 5.3.0 } assembly.Save(assemblyName); File.Move(newDllPath, fullDllPath); if (generateLinkXml) { File.WriteAllText(dirPath + "link.xml", @"<linker> <assembly fullname=""" + assemblyName + @""" preserve=""all""/> </linker>"); } try { AssetDatabase.Refresh(); } catch (Exception) { // Sigh, Unity 5.3.0 } var pluginImporter = PluginImporter.GetAtPath(fullDllPath) as PluginImporter; if (pluginImporter != null) { //pluginImporter.ClearSettings(); pluginImporter.SetCompatibleWithEditor(false); pluginImporter.SetCompatibleWithAnyPlatform(true); // Disable for all standalones pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneLinux64, false); if (!UnityVersion.IsVersionOrGreater(2019, 2)) { pluginImporter.SetCompatibleWithPlatform((BuildTarget)17, false); // StandaloneLinux pluginImporter.SetCompatibleWithPlatform((BuildTarget)25, false); // StandaloneLinuxUniversal } // StandaloneOSXUniversal (<= 2017.2) / StandaloneOSX (>= 2017.3) pluginImporter.SetCompatibleWithPlatform((BuildTarget)2, false); if (!UnityVersion.IsVersionOrGreater(2017, 3)) { pluginImporter.SetCompatibleWithPlatform((BuildTarget)4, false); // StandaloneOSXIntel pluginImporter.SetCompatibleWithPlatform((BuildTarget)27, false); // StandaloneOSXIntel64 } pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false); //pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false); //pluginImporter.SetCompatibleWithPlatform(BuildTarget.Android, false); pluginImporter.SaveAndReimport(); } AssetDatabase.SaveAssets(); #endif }
private static void EnablePluginPackage(PluginPackage pluginPkg) { foreach (var kvp in pluginPkg.Plugins) { PluginPlatform platform = kvp.Key; string path = kvp.Value; if ((Directory.Exists(path + GetDisabledPluginSuffix())) || (File.Exists(path + GetDisabledPluginSuffix()))) { string basePath = GetCurrentProjectPath(); string relPath = path.Substring(basePath.Length + 1); string relDisabledPath = relPath + GetDisabledPluginSuffix(); AssetDatabase.MoveAsset(relDisabledPath, relPath); AssetDatabase.ImportAsset(relPath, ImportAssetOptions.ForceUpdate); PluginImporter pi = PluginImporter.GetAtPath(relPath) as PluginImporter; if (pi == null) { continue; } // Disable support for all platforms, then conditionally enable desired support below pi.SetCompatibleWithEditor(false); pi.SetCompatibleWithAnyPlatform(false); pi.SetCompatibleWithPlatform(BuildTarget.Android, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false); #if UNITY_2017_3_OR_NEWER pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, false); #else pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXUniversal, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel, false); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel64, false); #endif switch (platform) { case PluginPlatform.Android: pi.SetCompatibleWithPlatform(BuildTarget.Android, !unityVersionSupportsAndroidUniversal); pi.SetPlatformData(BuildTarget.Android, "CPU", "ARMv7"); break; case PluginPlatform.AndroidUniversal: pi.SetCompatibleWithPlatform(BuildTarget.Android, unityVersionSupportsAndroidUniversal); pi.SetPlatformData(BuildTarget.Android, "CPU", "ARM64"); break; case PluginPlatform.OSXUniversal: #if UNITY_2017_3_OR_NEWER pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSX, true); #else pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXUniversal, true); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel, true); pi.SetCompatibleWithPlatform(BuildTarget.StandaloneOSXIntel64, true); #endif pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "AnyCPU"); pi.SetEditorData("OS", "OSX"); pi.SetPlatformData("Editor", "CPU", "AnyCPU"); pi.SetPlatformData("Editor", "OS", "OSX"); break; case PluginPlatform.Win: pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, true); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "X86"); pi.SetEditorData("OS", "Windows"); pi.SetPlatformData("Editor", "CPU", "X86"); pi.SetPlatformData("Editor", "OS", "Windows"); break; case PluginPlatform.Win64: pi.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, true); pi.SetCompatibleWithEditor(true); pi.SetEditorData("CPU", "X86_64"); pi.SetEditorData("OS", "Windows"); pi.SetPlatformData("Editor", "CPU", "X86_64"); pi.SetPlatformData("Editor", "OS", "Windows"); break; default: throw new ArgumentException("Attempted EnablePluginPackage() for unsupported BuildTarget: " + platform); } AssetDatabase.ImportAsset(relPath, ImportAssetOptions.ForceUpdate); } } AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); }