2using System.Collections.Generic;
5using System.Reflection;
7using UnityEditor.Compilation;
9using PackageInfo = UnityEditor.PackageManager.PackageInfo;
18 private const string PackageManagerWindowGeneralMenu =
"Window/General/Package Manager";
19 private const string PackageManagerWindowLegacyMenu =
"Window/Package Manager";
20 private const string ServicesWindowMenu =
"Window/Services/";
22 private static readonly
string[] packageManagerMenus =
24 PackageManagerWindowGeneralMenu,
25 PackageManagerWindowLegacyMenu
28 #region Install Helpers
29 private static Aggregator GetSelectedAggregator() =>
30 (adAggregatorResource ? adAggregatorResource : AdAggregatorResource.Instance)
31 .Aggregators ==
null ?
null :
32 selectedAggregator >= adAggregatorResource.Aggregators.Length ? null :
33 adAggregatorResource.Aggregators[selectedAggregator];
35 private static bool IsInstallActionConfigured(Aggregator aggregator)
37 var install = aggregator?.Install;
41 return install.InstallMode != InstallOpenMode.ExternalUrl ||
42 !
string.IsNullOrWhiteSpace(install.InstallUrl);
45 private static void OpenInstall(Aggregator aggregator)
47 if (aggregator ==
null)
50 var install = aggregator.Install;
53 Debug.LogWarning($
"[{nameof(AdAggregatorSelector)}] Install resource is missing for '{aggregator.Name}'.");
59 if (TryOpenPackageManager(install))
62 if (!
string.IsNullOrWhiteSpace(install.InstallUrl))
64 Application.OpenURL(install.InstallUrl);
69 $
"[{nameof(AdAggregatorSelector)}] Package Manager is unavailable and fallback URL is missing for '{aggregator.Name}'.");
73 if (!
string.IsNullOrWhiteSpace(install.InstallUrl))
75 Application.OpenURL(install.InstallUrl);
79 Debug.LogWarning($
"[{nameof(AdAggregatorSelector)}] Install URL is missing for '{aggregator.Name}'.");
82 private static bool TryOpenPackageManager(AggregatorInstallResource install)
87 if (TryOpenPackageManagerByPackageId(install.InstallPackageIds))
90 var menuItems =
new List<string>();
91 if (!
string.IsNullOrWhiteSpace(install.PackageManagerFilter))
93 menuItems.Add(ServicesWindowMenu + install.PackageManagerFilter);
96 menuItems.AddRange(packageManagerMenus);
98 .Where(menuItem => !
string.IsNullOrWhiteSpace(menuItem))
99 .Distinct(StringComparer.Ordinal)
100 .Any(EditorApplication.ExecuteMenuItem);
103 private static bool TryOpenPackageManagerByPackageId(IEnumerable<string> packageIds)
105 var enumerable = packageIds as
string[] ?? packageIds.ToArray();
106 if (!HasValues(enumerable))
109 var packageManagerWindowType = FindPackageManagerWindowType();
110 if (packageManagerWindowType ==
null)
113 var openMethod = packageManagerWindowType.GetMethod(
115 BindingFlags.Public | BindingFlags.Static,
117 new[] { typeof(string) },
119 if (openMethod ==
null)
122 foreach (var packageId
in enumerable.Where(
id => !
string.IsNullOrWhiteSpace(
id)))
126 openMethod.Invoke(
null,
new object[] { packageId });
138 private static Type FindPackageManagerWindowType()
140 const string fullTypeName =
"UnityEditor.PackageManager.UI.Window";
142 var type = Type.GetType($
"{fullTypeName}, UnityEditor");
146 return AppDomain.CurrentDomain.GetAssemblies()
147 .Select(assembly => assembly.GetType(fullTypeName, throwOnError:
false))
148 .FirstOrDefault(foundType => foundType !=
null);
151 private static bool IsAggregatorInstalled(Aggregator aggregator)
153 var install = aggregator?.Install;
157 var hasChecks =
false;
159 if (HasValues(install.InstallPackageIds))
162 if (install.InstallPackageIds.Any(IsPackageInstalled))
166 if (HasValues(install.InstallFolderNames))
169 if (install.InstallFolderNames.Any(IsFolderInstalled))
173 if (!HasValues(install.InstallAssemblyNames))
return !hasChecks;
174 return install.InstallAssemblyNames.Any(IsAssemblyInstalled);
177 private static bool IsPackageInstalled(
string packageId)
179 if (
string.IsNullOrWhiteSpace(packageId))
182 if (IsPackageDefinedInManifest(packageId))
187 return PackageInfo.FindForAssetPath($
"Packages/{packageId}") !=
null;
195 private static bool IsPackageDefinedInManifest(
string packageId)
197 if (
string.IsNullOrWhiteSpace(packageId))
200 var manifestPath = Path.Combine(GetProjectRootPath(),
"Packages",
"manifest.json");
201 if (!File.Exists(manifestPath))
206 var manifest = File.ReadAllText(manifestPath);
207 return manifest.Contains($
"\"{packageId}\"", StringComparison.Ordinal);
215 private static bool IsFolderInstalled(
string folderName)
217 if (
string.IsNullOrWhiteSpace(folderName))
220 var normalizedFolder = folderName.Replace(
'\\',
'/').Trim(
'/');
221 if (
string.IsNullOrWhiteSpace(normalizedFolder))
224 var candidateAssetFolders =
new[]
227 $
"Assets/{normalizedFolder}",
228 $
"Packages/{normalizedFolder}"
230 if (candidateAssetFolders.Any(AssetDatabase.IsValidFolder))
233 var projectRoot = GetProjectRootPath();
234 var candidateDiskFolders =
new[]
236 Path.Combine(projectRoot, normalizedFolder),
237 Path.Combine(projectRoot,
"Assets", normalizedFolder),
238 Path.Combine(projectRoot,
"Packages", normalizedFolder)
240 return candidateDiskFolders.Any(Directory.Exists);
243 private static bool IsAssemblyInstalled(
string assemblyName)
245 if (
string.IsNullOrWhiteSpace(assemblyName))
250 return CompilationPipeline.GetAssemblies().Any(assembly =>
251 string.Equals(assembly.name, assemblyName, StringComparison.OrdinalIgnoreCase));
255 return AppDomain.CurrentDomain.GetAssemblies().Any(assembly =>
256 string.Equals(assembly.GetName().Name, assemblyName, StringComparison.OrdinalIgnoreCase));
260 private static bool HasValues(IEnumerable<string> values) =>
261 values !=
null && values.Any(value => !
string.IsNullOrWhiteSpace(value));
263 private static string GetProjectRootPath() =>
264 Path.GetFullPath(Path.Combine(Application.dataPath,
".."));
Provides ad aggregator selector functionality.
InstallOpenMode
Defines the target destination for the Install action in the aggregator selector. External URL opens ...