gg.easy.airship 0.1.2221 → 0.1.2223

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/Editor/Accessories/AccessoryCollectionEditorTools.cs +1 -1
  2. package/Editor/Accessories/Clothing/PlatformGearBundleManifestEditor.cs +204 -184
  3. package/Editor/Packages/AirshipPackagesWindow.cs +81 -33
  4. package/Editor/Publish/Deploy.cs +1 -1
  5. package/Editor/Publish/PublishTargetWindow.cs +1 -1
  6. package/Editor/TypescriptServices/Compiler/TypescriptCompilationService.cs +46 -14
  7. package/Editor/TypescriptServices/Editor/NodeDetection/AirshipLinuxNodeDistribution.cs +47 -0
  8. package/Editor/TypescriptServices/Editor/NodeDetection/AirshipLinuxNodeDistribution.cs.meta +3 -0
  9. package/Editor/TypescriptServices/Editor/NodeDetection/AirshipNodeVersion.cs +2 -0
  10. package/Runtime/Code/Accessories/Clothing/Editor/PlatformGearDownloader.cs +1 -1
  11. package/Runtime/Code/AirshipConst.cs +1 -0
  12. package/Runtime/Code/Bootstrap/BundleDownloader.cs +13 -3
  13. package/Runtime/Code/Bootstrap/ClientBundleLoader.cs +1 -1
  14. package/Runtime/Code/Bootstrap/ClientNetworkConnector.cs +2 -2
  15. package/Runtime/Code/Bootstrap/ServerBootstrap.cs +1 -1
  16. package/Runtime/Code/Bundles/AirshipPackage.cs +2 -2
  17. package/Runtime/Code/Bundles/LoadedAssetBundle.cs +2 -2
  18. package/Runtime/Code/Bundles/SystemRoot.cs +9 -9
  19. package/Runtime/Code/CoreUI/Loading/CoreLoadingScreen.cs +18 -5
  20. package/Runtime/Code/Luau/AirshipComponent.cs +2 -2
  21. package/Runtime/Code/Luau/AirshipScriptableObject.cs +3 -3
  22. package/Runtime/Code/Luau/LuauCoreCallbacks.cs +1 -1
  23. package/Runtime/Code/Managers/CanvasDistanceManager.cs +5 -0
  24. package/Runtime/Code/Misc/AirshipBuildInfo.cs +3 -3
  25. package/Runtime/Code/Misc/CanvasDistanceCondition.cs +24 -0
  26. package/Runtime/Code/Misc/EasyFileService.cs +3 -3
  27. package/Runtime/Code/Quality/QualityManager.cs +16 -14
  28. package/Runtime/Code/TextureLoader/TextureLoader.cs +1 -1
  29. package/Runtime/Code/VisualGraph/VisualGraphUIMat.mat +4 -0
  30. package/Runtime/Code/VoxelWorld/Resources/VoxelWorldMatURP.mat +3 -3
  31. package/Runtime/Code/VoxelWorld/WorldSaveFile.cs +25 -20
  32. package/URP/AirshipMobileURPAsset_Renderer.asset +1 -1
  33. package/package.json +1 -1
@@ -315,7 +315,7 @@ public class AccessoryCollectionTools {
315
315
 
316
316
  //Guess the avatar slot based on the name
317
317
  private static AccessorySlot GetSlot(string name, bool skinnedMesh){
318
- string lower = name.ToLower().Replace("_", "").Replace(" ", "");
318
+ string lower = name.ToLowerInvariant().Replace("_", "").Replace(" ", "");
319
319
 
320
320
  //TODO: For non skinned meshes I need to evaulate if it is a Left or Right version of things like hands and feet
321
321
 
@@ -7,6 +7,7 @@ using System.Linq;
7
7
  using System.Text;
8
8
  using System.Threading.Tasks;
9
9
  using Code.Accessories.Clothing;
10
+ using Code.Authentication;
10
11
  using Code.Bootstrap;
11
12
  using Code.Http.Internal;
12
13
  using Code.Platform.Shared;
@@ -16,6 +17,7 @@ using UnityEditor;
16
17
  using UnityEditor.Build.Pipeline;
17
18
  using UnityEngine;
18
19
  using UnityEngine.Networking;
20
+ using UnityEngine.SceneManagement;
19
21
  using Debug = UnityEngine.Debug;
20
22
  using Object = UnityEngine.Object;
21
23
 
@@ -68,234 +70,249 @@ namespace Editor.Accessories.Clothing {
68
70
  GUILayout.Space(20);
69
71
 
70
72
  if (GUILayout.Button("Publish")) {
71
- this.BuildAllPlatforms();
73
+ Debug.Log("Publishing");
74
+ BuildAllPlatforms();
72
75
  }
73
76
 
74
77
  GUILayout.Space(10);
75
- this.skipBuild = EditorGUILayout.Toggle("Skip Build", this.skipBuild);
78
+ skipBuild = EditorGUILayout.Toggle("Skip Build", this.skipBuild);
76
79
  }
77
80
 
78
81
  public async Task BuildAllPlatforms() {
79
- var st = Stopwatch.StartNew();
80
-
81
- if (!AirshipPackagesWindow.VerifyBuildModules(true)) {
82
+ if (EditorAuthManager.signInStatus != EditorAuthSignInStatus.SIGNED_IN) {
83
+ Debug.LogError("Must sign in to build and upload asset bundles");
82
84
  return;
83
85
  }
84
86
 
85
- bool success = true;
87
+ if (SceneManager.GetActiveScene().isDirty) {
88
+ Debug.LogError("Must save current scene before building");
89
+ return;
90
+ }
86
91
 
87
- List<AirshipPlatform> platforms = new();
88
- platforms.AddRange(AirshipPlatformUtil.livePlatforms);
89
- // platforms.Add(AirshipPlatform.Mac); // debug
92
+ if (!AirshipPackagesWindow.VerifyBuildModules(true)) {
93
+ Debug.LogError("ERROR Missing Modules");
94
+ return;
95
+ }
90
96
 
91
- // ********************************* //
92
- var manifest = (PlatformGearBundleManifest)this.target;
97
+ var st = Stopwatch.StartNew();
98
+ Debug.Log("Build All Platforms Started");
99
+ try {
100
+ List<AirshipPlatform> platforms = new();
101
+ platforms.AddRange(AirshipPlatformUtil.livePlatforms);
102
+ // platforms.Add(AirshipPlatform.Mac); // debug
103
+
104
+ // ********************************* //
105
+ var manifest = (PlatformGearBundleManifest)this.target;
106
+
107
+ (string category, string subcategory) GetGearCategory(PlatformGear gear) {
108
+ string category = "Clothing";
109
+ string subcategory = "";
110
+ if (gear.accessoryPrefabs.Length > 0) {
111
+ subcategory = gear.accessoryPrefabs[0].accessorySlot.ToString();
112
+ } else if (gear.face != null) {
113
+ category = "FaceDecal";
114
+ subcategory = "None";
115
+ }
93
116
 
94
- (string category, string subcategory) GetGearCategory(PlatformGear gear) {
95
- string category = "Clothing";
96
- string subcategory = "";
97
- if (gear.accessoryPrefabs.Length > 0) {
98
- subcategory = gear.accessoryPrefabs[0].accessorySlot.ToString();
99
- } else if (gear.face != null) {
100
- category = "FaceDecal";
101
- subcategory = "None";
117
+ return (category, subcategory);
102
118
  }
103
119
 
104
- return (category, subcategory);
105
- }
106
-
107
- // Pre-build check: Make sure all gear accessory LOD's are in the right folder
108
- foreach (var gear in manifest.gearList) {
109
- if (gear.accessoryPrefabs != null) {
110
- foreach (var accessory in gear.accessoryPrefabs) {
111
- foreach (var mesh in accessory.meshLods) {
112
- var path = AssetDatabase.GetAssetPath(mesh);
113
- if (!path.StartsWith("Assets/Gear")) {
114
- Debug.LogError($"{accessory.gameObject.name} has an LOD mesh outside of the gear folder. Place all assets (including LOD meshes) inside of the gear folder. Invalid mesh path: " + path);
115
- return;
120
+ // Pre-build check: Make sure all gear accessory LOD's are in the right folder
121
+ foreach (var gear in manifest.gearList) {
122
+ if (gear.accessoryPrefabs != null) {
123
+ foreach (var accessory in gear.accessoryPrefabs) {
124
+ foreach (var mesh in accessory.meshLods) {
125
+ var path = AssetDatabase.GetAssetPath(mesh);
126
+ if (!path.StartsWith("Assets/Gear")) {
127
+ Debug.LogError($"{accessory.gameObject.name} has an LOD mesh outside of the gear folder. Place all assets (including LOD meshes) inside of the gear folder. Invalid mesh path: " + path);
128
+ return;
129
+ }
116
130
  }
117
131
  }
118
132
  }
119
133
  }
120
- }
121
134
 
122
- if (!CreateAssetBundles.PrePublishChecks()) return;
135
+ if (!CreateAssetBundles.PrePublishChecks()) return;
123
136
 
124
137
 
125
- // Create Class ID's for each gear piece
126
- foreach (var gear in manifest.gearList) {
127
- if (!string.IsNullOrEmpty(gear.classId)) continue;
138
+ // Create Class ID's for each gear piece
139
+ foreach (var gear in manifest.gearList) {
140
+ // Ignore if gear already has a class id
141
+ if (!string.IsNullOrEmpty(gear.classId)) continue;
128
142
 
129
- // Grab class id from the old accessory.classId
130
- if (gear.accessoryPrefabs.Length > 0 &&
131
- !string.IsNullOrEmpty(gear.accessoryPrefabs[0].serverClassId)) {
132
- gear.classId = gear.accessoryPrefabs[0].serverClassId;
133
- EditorUtility.SetDirty(gear);
134
- AssetDatabase.SaveAssets();
135
- continue;
136
- }
137
- if (gear.face != null && !string.IsNullOrEmpty(gear.face.serverClassId)) {
138
- gear.classId = gear.face.serverClassId;
143
+ // Grab class id from the old accessory.classId
144
+ if (gear.accessoryPrefabs.Length > 0 &&
145
+ !string.IsNullOrEmpty(gear.accessoryPrefabs[0].serverClassId)) {
146
+ // Found id in accessory
147
+ gear.classId = gear.accessoryPrefabs[0].serverClassId;
148
+ EditorUtility.SetDirty(gear);
149
+ AssetDatabase.SaveAssets();
150
+ continue;
151
+ }
152
+ if (gear.face != null && !string.IsNullOrEmpty(gear.face.serverClassId)) {
153
+ // found id in face
154
+ gear.classId = gear.face.serverClassId;
155
+ EditorUtility.SetDirty(gear);
156
+ AssetDatabase.SaveAssets();
157
+ continue;
158
+ }
159
+
160
+ (string category, string subcategory) = GetGearCategory(gear);
161
+
162
+ // Create a new class id
163
+ var data = JsonUtility.ToJson(new GearCreateRequest() {
164
+ name = gear.name,
165
+ imageId = defaultImageId,
166
+ description = "Clothing",
167
+ airAssets = new string[] { },
168
+ category = category,
169
+ subcategory = subcategory,
170
+ });
171
+ Debug.Log("Creating new class id for gear: " + gear.name);
172
+ var req = UnityWebRequest.Post($"{AirshipPlatformUrl.contentService}/gear/resource-id/{easyOrgId}", data, "application/json");
173
+ req.SetRequestHeader("Authorization", "Bearer " + InternalHttpManager.editorAuthToken);
174
+ req.SetRequestHeader("x-airship-ignore-rate-limit", "true");
175
+ await req.SendWebRequest();
176
+ if (req.result != UnityWebRequest.Result.Success) {
177
+ Debug.Log("Post request: " + data);
178
+ Debug.LogError("Failed to create gear class: " + req.downloadHandler.text);
179
+ return;
180
+ }
181
+ Debug.Log("Create classId response: " + req.downloadHandler.text);
182
+ var createResponse = JsonUtility.FromJson<GearCreateResponse>(req.downloadHandler.text);
183
+ gear.classId = createResponse.classId;
139
184
  EditorUtility.SetDirty(gear);
140
185
  AssetDatabase.SaveAssets();
141
- continue;
142
- }
143
-
144
- (string category, string subcategory) = GetGearCategory(gear);
145
-
146
- // Create a new class id
147
- var data = JsonUtility.ToJson(new GearCreateRequest() {
148
- name = gear.name,
149
- imageId = defaultImageId,
150
- description = "Clothing",
151
- airAssets = new string[] { },
152
- category = category,
153
- subcategory = subcategory,
154
- });
155
- var req = UnityWebRequest.Post($"{AirshipPlatformUrl.contentService}/gear/resource-id/{easyOrgId}", data, "application/json");
156
- req.SetRequestHeader("Authorization", "Bearer " + InternalHttpManager.editorAuthToken);
157
- req.SetRequestHeader("x-airship-ignore-rate-limit", "true");
158
- await req.SendWebRequest();
159
- if (req.result != UnityWebRequest.Result.Success) {
160
- Debug.Log("Post request: " + data);
161
- Debug.LogError("Failed to create gear class: " + req.downloadHandler.text);
162
- return;
163
186
  }
164
- Debug.Log("Create classId response: " + req.downloadHandler.text);
165
- var createResponse = JsonUtility.FromJson<GearCreateResponse>(req.downloadHandler.text);
166
- gear.classId = createResponse.classId;
167
- EditorUtility.SetDirty(gear);
168
- AssetDatabase.SaveAssets();
169
- }
170
187
 
171
- string airId = manifest.airId;
188
+ string airId = manifest.airId;
172
189
 
173
- var contentName = manifest.gearList[0].name;
174
- var contentDescription = "Clothing";
190
+ var contentName = manifest.gearList[0].name;
191
+ var contentDescription = "Clothing";
175
192
 
176
- if (string.IsNullOrEmpty(airId)) {
177
- // Create new air asset
178
- var req = UnityWebRequest.PostWwwForm(
179
- AirshipPlatformUrl.deploymentService + $"/air-assets/owner-type/ORGANIZATION/owner-id/{easyOrgId}",
180
- JsonUtility.ToJson(new AirAssetCreateRequest() {
193
+ if (string.IsNullOrEmpty(airId)) {
194
+ // Create new air asset
195
+ var airPath = AirshipPlatformUrl.deploymentService +
196
+ $"/air-assets/owner-type/ORGANIZATION/owner-id/{easyOrgId}";
197
+ var airJson = JsonUtility.ToJson(new AirAssetCreateRequest() {
181
198
  contentType = "application/airasset",
182
199
  contentLength = 1,
183
200
  name = contentName,
184
201
  description = contentDescription,
185
202
  platforms = platforms.Select((p) => AirshipPlatformUtil.GetStringName(p)).ToArray(),
186
- }));
187
- req.SetRequestHeader("Authorization", "Bearer " + InternalHttpManager.editorAuthToken);
188
- await req.SendWebRequest();
189
- Debug.Log("create response: " + req.downloadHandler.text);
190
- var data = JsonUtility.FromJson<AirAssetCreateResponse>(req.downloadHandler.text);
191
- manifest.airId = data.airAssetId;
192
- EditorUtility.SetDirty(this.target);
193
- this.SaveChanges();
194
- airId = data.airAssetId;
195
- }
196
-
197
- List<string> bundlePaths = new();
198
- foreach (var platform in platforms) {
199
- var path = await this.BuildPlatform(platform, airId);
200
- if (string.IsNullOrEmpty(path)) {
201
- success = false;
202
- return;
203
+ });
204
+ Debug.Log("Creating air asset at: " + airPath);
205
+ Debug.Log("With json: " + airJson);
206
+ var req = UnityWebRequest.Post(airPath, airJson, "application/json");
207
+ req.SetRequestHeader("Authorization", "Bearer " + InternalHttpManager.editorAuthToken);
208
+ req.SetRequestHeader("x-airship-ignore-rate-limit", "true");
209
+ await req.SendWebRequest();
210
+ Debug.Log("create response: " + req.downloadHandler.text);
211
+ if (req.result != UnityWebRequest.Result.Success) {
212
+ Debug.LogError("Error creating air asset: " + req.error);
213
+ return;
214
+ }
215
+ var data = JsonUtility.FromJson<AirAssetCreateResponse>(req.downloadHandler.text);
216
+ manifest.airId = data.airAssetId;
217
+ EditorUtility.SetDirty(this.target);
218
+ this.SaveChanges();
219
+ airId = data.airAssetId;
203
220
  }
204
221
 
205
- bundlePaths.Add(path);
206
- }
207
- // {
208
- // var path = await this.BuildPlatform(AirshipPlatform.Windows, airId);
209
- // if (string.IsNullOrEmpty(path)) {
210
- // success = false;
211
- // return;
212
- // }
213
- //
214
- // bundlePaths.Add(path);
215
- // }
216
-
217
- if (!success) return;
218
-
219
- // ******************** //
220
-
221
- int bytesCount = 0;
222
- for (int i = 0; i < platforms.Count; i++) {
223
- var platform = platforms[i];
224
- var buildOutputFile = bundlePaths[i];
225
- // var buildOutputFile = bundlePaths[0];
226
-
227
- // Update air asset
228
- var bytes = await File.ReadAllBytesAsync(buildOutputFile);
229
- Debug.Log("bytes length: " + bytes.Length + ", path: " + buildOutputFile);
230
- bytesCount = bytes.Length;
231
- var updateReq = UnityWebRequest.Put(AirshipPlatformUrl.deploymentService + $"/air-assets/{airId}",
232
- JsonUtility.ToJson(new AirAssetCreateRequest() {
233
- contentType = "application/airasset",
234
- contentLength = bytes.Length,
235
- name = contentName,
236
- description = contentDescription,
237
- platforms = platforms.Select((p) => AirshipPlatformUtil.GetStringName(p)).ToArray(),
238
- }));
239
- updateReq.SetRequestHeader("Content-Type", "application/json");
240
- updateReq.SetRequestHeader("Authorization", "Bearer " + InternalHttpManager.editorAuthToken);
241
- updateReq.SetRequestHeader("x-airship-ignore-rate-limit", "true");
242
- await updateReq.SendWebRequest();
243
- if (updateReq.result != UnityWebRequest.Result.Success) {
244
- Debug.LogError("Failed to update air asset: " + updateReq.downloadHandler.text);
245
- EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows);
246
- return;
222
+ List<string> bundlePaths = new();
223
+ foreach (var platform in platforms) {
224
+ var path = await this.BuildPlatform(platform, airId);
225
+ if (string.IsNullOrEmpty(path)) {
226
+ Debug.LogError("Unable to build platform: " + platform);
227
+ return;
228
+ }
229
+
230
+ bundlePaths.Add(path);
247
231
  }
248
- var updateData = JsonUtility.FromJson<AirAssetCreateResponse>(updateReq.downloadHandler.text);
249
- var uploadUrl = updateData.urls.UrlFromPlatform(platform);
250
-
251
- // Upload asset bundle
252
- {
253
- UnityWebRequest putReq = UnityWebRequest.Put(uploadUrl, bytes);
254
- foreach (var pair in updateData.headers) {
255
- putReq.SetRequestHeader(pair.key, pair.value);
232
+
233
+ int bytesCount = 0;
234
+ for (int i = 0; i < platforms.Count; i++) {
235
+ var platform = platforms[i];
236
+ var buildOutputFile = bundlePaths[i];
237
+ // var buildOutputFile = bundlePaths[0];
238
+
239
+ // Update air asset
240
+ var bytes = await File.ReadAllBytesAsync(buildOutputFile);
241
+ Debug.Log("bytes length: " + bytes.Length + ", path: " + buildOutputFile);
242
+ bytesCount = bytes.Length;
243
+ var updateReq = UnityWebRequest.Put(AirshipPlatformUrl.deploymentService + $"/air-assets/{airId}",
244
+ JsonUtility.ToJson(new AirAssetCreateRequest() {
245
+ contentType = "application/airasset",
246
+ contentLength = bytes.Length,
247
+ name = contentName,
248
+ description = contentDescription,
249
+ platforms = platforms.Select((p) => AirshipPlatformUtil.GetStringName(p)).ToArray(),
250
+ }));
251
+ updateReq.SetRequestHeader("Content-Type", "application/json");
252
+ updateReq.SetRequestHeader("Authorization", "Bearer " + InternalHttpManager.editorAuthToken);
253
+ updateReq.SetRequestHeader("x-airship-ignore-rate-limit", "true");
254
+ await updateReq.SendWebRequest();
255
+ if (updateReq.result != UnityWebRequest.Result.Success) {
256
+ Debug.LogError("Failed to update air asset: " + updateReq.downloadHandler.text);
257
+ EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows);
258
+ return;
256
259
  }
257
- putReq.SetRequestHeader("x-airship-ignore-rate-limit", "true");
260
+ var updateData = JsonUtility.FromJson<AirAssetCreateResponse>(updateReq.downloadHandler.text);
261
+ var uploadUrl = updateData.urls.UrlFromPlatform(platform);
262
+
263
+ // Upload asset bundle
264
+ {
265
+ UnityWebRequest putReq = UnityWebRequest.Put(uploadUrl, bytes);
266
+ foreach (var pair in updateData.headers) {
267
+ putReq.SetRequestHeader(pair.key, pair.value);
268
+ }
269
+ putReq.SetRequestHeader("x-airship-ignore-rate-limit", "true");
258
270
 
259
- Debug.Log("Uploading asset bundle...");
260
- await putReq.SendWebRequest();
261
- Debug.Log("Finished upload! Updating gear classes...");
271
+ Debug.Log("Uploading asset bundle");
272
+ await putReq.SendWebRequest();
262
273
 
263
- if (putReq.result != UnityWebRequest.Result.Success) {
264
- Debug.LogError(putReq.error);
265
- Debug.LogError(putReq.downloadHandler.text);
274
+ if (putReq.result != UnityWebRequest.Result.Success) {
275
+ Debug.LogError(putReq.error);
276
+ Debug.LogError(putReq.downloadHandler.text);
277
+ EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows);
278
+ return;
279
+ }
280
+ }
281
+ }
282
+
283
+ // ******************** //
284
+ // Update all ClassID's to point to the airId
285
+ foreach (var gear in manifest.gearList) {
286
+ (string category, string subcategory) = GetGearCategory(gear);
287
+ var data = new GearPatchRequest() {
288
+ airAssets = new string[] { airId },
289
+ category = category,
290
+ subcategory = subcategory,
291
+ };
292
+ var url = $"{AirshipPlatformUrl.contentService}/gear/class-id/{gear.classId}";
293
+ var req = UnityWebRequest.Put(url,
294
+ JsonUtility.ToJson(data));
295
+ req.method = "PATCH";
296
+ req.SetRequestHeader("Content-Type","application/json");
297
+ req.SetRequestHeader("Authorization", "Bearer " + InternalHttpManager.editorAuthToken);
298
+ req.SetRequestHeader("x-airship-ignore-rate-limit", "true");
299
+ await req.SendWebRequest();
300
+ if (req.result != UnityWebRequest.Result.Success) {
301
+ Debug.LogError($"patch classId. url: {url}, response: {req.downloadHandler.text}, authToken: {InternalHttpManager.editorAuthToken}");
266
302
  EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows);
267
303
  return;
268
304
  }
269
305
  }
270
- }
271
306
 
272
- // ******************** //
273
- // Update all ClassID's to point to the airId
274
- foreach (var gear in manifest.gearList) {
275
- (string category, string subcategory) = GetGearCategory(gear);
276
- var data = new GearPatchRequest() {
277
- airAssets = new string[] { airId },
278
- category = category,
279
- subcategory = subcategory,
280
- };
281
- var url = $"{AirshipPlatformUrl.contentService}/gear/class-id/{gear.classId}";
282
- var req = UnityWebRequest.Put(url,
283
- JsonUtility.ToJson(data));
284
- req.method = "PATCH";
285
- req.SetRequestHeader("Content-Type","application/json");
286
- req.SetRequestHeader("Authorization", "Bearer " + InternalHttpManager.editorAuthToken);
287
- req.SetRequestHeader("x-airship-ignore-rate-limit", "true");
288
- await req.SendWebRequest();
289
- if (req.result != UnityWebRequest.Result.Success) {
290
- Debug.LogError($"patch classId. url: {url}, response: {req.downloadHandler.text}, authToken: {InternalHttpManager.editorAuthToken}");
307
+ if (EditorUserBuildSettings.activeBuildTarget != BuildTarget.StandaloneWindows) {
291
308
  EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows);
292
- return;
293
309
  }
310
+
311
+ Debug.Log($"<color=green>Finished building {bundlePaths.Count} asset bundles for all platforms in {st.Elapsed.Seconds} seconds.</color> File size: " + AirshipEditorUtil.GetFileSizeText(bytesCount));
312
+ } catch (Exception e) {
313
+ Debug.LogError("ERROR: " + e.Message);
294
314
  }
295
315
 
296
- EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows);
297
-
298
- Debug.Log($"<color=green>Finished building {bundlePaths.Count} asset bundles for all platforms in {st.Elapsed.Seconds} seconds.</color> File size: " + AirshipEditorUtil.GetFileSizeText(bytesCount));
299
316
  }
300
317
 
301
318
  /// <summary>
@@ -317,8 +334,8 @@ namespace Editor.Accessories.Clothing {
317
334
  var assetGuids = AssetDatabase.FindAssets("*", new string[] {sourceFolderPath}).ToList();
318
335
  var assetPaths = assetGuids
319
336
  .Select((guid) => AssetDatabase.GUIDToAssetPath(guid))
320
- .Where((path) => !path.ToLower().Contains("editor/"))
321
- .Where((path) => !path.ToLower().Contains("exclude/"))
337
+ .Where((path) => !path.ToLowerInvariant().Contains("editor/"))
338
+ .Where((path) => !path.ToLowerInvariant().Contains("exclude/"))
322
339
  .Where((p) => !AssetDatabase.IsValidFolder(p))
323
340
  .ToArray();
324
341
  Debug.Log("Resources:");
@@ -326,7 +343,7 @@ namespace Editor.Accessories.Clothing {
326
343
  Debug.Log(" - " + path);
327
344
  }
328
345
  var addressableNames = assetPaths
329
- .Select((p) => p.ToLower())
346
+ .Select((p) => p.ToLowerInvariant())
330
347
  .Select((p) => {
331
348
  if (p.Contains("gear bundle manifest")) {
332
349
  // strip the path so it's easier to load later
@@ -349,7 +366,10 @@ namespace Editor.Accessories.Clothing {
349
366
  if (platform is AirshipPlatform.Windows or AirshipPlatform.Mac or AirshipPlatform.Linux) {
350
367
  buildTargetGroup = BuildTargetGroup.Standalone;
351
368
  }
352
- EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup, buildTarget);
369
+
370
+ if (EditorUserBuildSettings.activeBuildTarget != buildTarget) {
371
+ EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup, buildTarget);
372
+ }
353
373
  var buildParams = new BundleBuildParameters(
354
374
  buildTarget,
355
375
  buildTargetGroup,