PackageInstaller.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Water Geometry Tools
  2. // Staggart Creations (http://staggart.xyz)
  3. // Copyright protected under Unity Asset Store EULA
  4. // Copying or referencing source code for the production of new asset store content is strictly prohibited.
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using UnityEditor.PackageManager;
  9. using UnityEditor.PackageManager.Requests;
  10. using UnityEngine;
  11. using UnityEditor;
  12. using PackageInfo = UnityEditor.PackageManager.PackageInfo;
  13. namespace sc.modeling.water.common.editor
  14. {
  15. public class PackageInstaller
  16. {
  17. private struct Package
  18. {
  19. public string name;
  20. public string minVersion;
  21. public string latestVersion;
  22. }
  23. protected static void InstallDependencies(string assetName, string[] requiredPackages)
  24. {
  25. List<Package> dependencies = new List<Package>();
  26. var isOffline = Application.internetReachability == NetworkReachability.NotReachable;
  27. //List all the installed packages
  28. ListRequest packageListRequest = Client.List(isOffline, true);
  29. while (packageListRequest.Status == StatusCode.InProgress)
  30. {
  31. //Waiting
  32. }
  33. PackageCollection packageCollection = packageListRequest.Result;
  34. //Check if dependencies are installed
  35. for (int i = 0; i < requiredPackages.Length; i++)
  36. {
  37. //Eg: com.unity.something
  38. string packageName = requiredPackages[i];
  39. string packageNameWithoutVersion = packageName.Split('@')[0];
  40. #if WGT_DEV
  41. Debug.Log($"Searching for package {packageNameWithoutVersion}");
  42. #endif
  43. SearchRequest request = Client.Search(packageNameWithoutVersion, isOffline);
  44. while (request.Status == StatusCode.InProgress)
  45. {
  46. /* Waiting... */
  47. }
  48. if (request.IsCompleted)
  49. {
  50. if (request.Result == null)
  51. {
  52. Debug.LogError($"Searching for package {requiredPackages[i]} failed");
  53. continue;
  54. }
  55. PackageInfo packageInfo = request.Result[0];
  56. //Installed in project?
  57. bool installed = packageCollection.FirstOrDefault(q => q.name == packageName) != null;
  58. bool outdated = false;
  59. bool hasMinVersion = packageName.Split('@').Length > 1;
  60. Version reqVersion = null;
  61. if (hasMinVersion)
  62. {
  63. reqVersion = new Version(packageName.Split('@')[1]);
  64. outdated = new Version(packageInfo.version) < reqVersion;
  65. }
  66. //Outdated?
  67. if (outdated)
  68. {
  69. #if WGT_DEV
  70. Debug.Log($"[{assetName}] {packageName} outdated and must be upgraded");
  71. #endif
  72. installed = false;
  73. }
  74. if (installed)
  75. {
  76. #if WGT_DEV
  77. Debug.Log($"[{assetName}] {packageName} already installed");
  78. #endif
  79. }
  80. else
  81. {
  82. #if WGT_DEV
  83. Debug.Log($"[{assetName}] {packageName} dependency not installed or outdated, so will be installed/updated");
  84. #endif
  85. Package package = new Package();
  86. string id = packageName.Split('@')[0];
  87. package.name = id;
  88. package.latestVersion = packageInfo.versions.latestCompatible;
  89. package.minVersion = hasMinVersion ? reqVersion.ToString() : package.latestVersion;
  90. dependencies.Add(package);
  91. }
  92. }
  93. }
  94. if (dependencies.Count > 0)
  95. {
  96. string message = "This asset has the following missing package dependencies:\n";
  97. int installCount = 0;
  98. for (int i = 0; i < dependencies.Count; i++)
  99. {
  100. message += $"\n- {dependencies[i].name} (v{dependencies[i].minVersion}+)";
  101. }
  102. if (EditorUtility.DisplayDialog(assetName, message, "Install now", "Ignore"))
  103. {
  104. for (int i = 0; i < dependencies.Count; i++)
  105. {
  106. AddRequest addRequest = Client.Add(dependencies[i].name + "@" + dependencies[i].latestVersion);
  107. //Wait until finished
  108. while (!addRequest.IsCompleted || addRequest.Status == StatusCode.InProgress) { }
  109. installCount++;
  110. }
  111. if (installCount > 0)
  112. {
  113. EditorUtility.DisplayDialog(assetName, $"One or more dependencies are going be installed." +
  114. $"\n\nBecause the asset \"{assetName}\" was imported BEFORE they were, some aspects like component data, Shader Graphs and VFX Graphs are most likely broken and need to be re-imported from the asset store." +
  115. $"\n\nIf you're unsure about this, simply delete and reimport the entire package from the Asset Store." +
  116. $"" +
  117. $"\n\nThis mainly applies to situations where you first import the asset into a project", "OK");
  118. }
  119. }
  120. else
  121. {
  122. EditorUtility.DisplayDialog(assetName, "The core functionality, or parts, of this asset will remain unavailable until these package(s) are installed or updated to the required version." +
  123. "\n\nAsset files that depend on a package (such as Shader/VFX Graphs) will be broken and require re-importing from the asset store.", "I understand");
  124. }
  125. }
  126. else
  127. {
  128. #if WGT_DEV
  129. Debug.Log($"[{assetName}] All dependencies installed!");
  130. #endif
  131. }
  132. }
  133. public static void InstallFBXExporter()
  134. {
  135. string packageName = "com.unity.formats.fbx";
  136. SearchRequest request = Client.Search(packageName);
  137. while (request.Status == StatusCode.InProgress) { /* Waiting... */ }
  138. if (request.Status == StatusCode.Failure)
  139. {
  140. Debug.LogError("Failed to retrieve FBX Exporter package from Package Manager...");
  141. return;
  142. }
  143. PackageInfo package = request.Result[0];
  144. AddRequest addRequest = Client.Add($"{packageName}@{package.versions.latestCompatible}");
  145. //Wait until finished
  146. while (!addRequest.IsCompleted || addRequest.Status == StatusCode.InProgress) { }
  147. Debug.Log($"Successfully installed the <b>{packageName}</b> package");
  148. }
  149. }
  150. }