static void FinalizePublish(Stack <RequestHandle> requests)
        {
            var subscriber     = CreateSubscriber();
            var resourceFolder = CompanionResourceUtils.GetCurrentResourceFolder();
            var project        = new CompanionProject(Application.cloudProjectId, Application.productName, true);

            requests.Push(subscriber.GetCloudResourceList(project, resourceFolder, (success, resourceList) =>
            {
                foreach (var update in k_ResourceListUpdates)
                {
                    var key = update.ResourceKey;
                    resourceList.AddOrUpdateResource(key, update.Name, update.Type, update.FileSize, update.HasBundle);

                    var thumbnail = update.Thumbnail;
                    if (thumbnail != null)
                    {
                        subscriber.SaveThumbnailImage(project, resourceFolder, key, thumbnail, requests);
                    }
                }

                requests.Push(subscriber.WriteCloudResourceList(project, resourceFolder, resourceList, writeSuccess =>
                {
                    if (success)
                    {
                        CompanionResourceUtils.OnCloudResourceListChanged(resourceList);
                    }
                    else
                    {
                        Debug.LogError("Failed to write resource list");
                    }
                }));
            }));
        }
Esempio n. 2
0
        static RequestHandle GetAssetBundleAsset(this IUsesCloudStorage storageUser, string group, CompanionProject project,
                                                 string resourceFolder, string platform, string guid, Action <bool, UnityObject> callback)
        {
            const int timeout = 0; // Asset bundles may be quite large and take a long time to download

            // Write to local storage in case cloud isn't reachable
            var folder = CompanionResourceUtils.GetLocalResourceFolderPath(project, resourceFolder, group);
            var path   = Path.Combine(folder, guid);

            if (!project.linked)
            {
                UnityObject asset = null;
                if (File.Exists(path))
                {
                    asset = GetLocalAssetBundleAsset(path);
                }

                callback(asset != null, asset);
                return(default);
        static void Publish()
        {
            k_ResourceListUpdates.Clear();
            s_UploadCount = 0;
            var subscriber     = CreateSubscriber();
            var resourceFolder = CompanionResourceUtils.GetCurrentResourceFolder();
            var project        = new CompanionProject(Application.cloudProjectId, Application.productName, true);

            foreach (var selected in Selection.objects)
            {
                if (selected is SceneAsset sceneAsset)
                {
                    var path = AssetDatabase.GetAssetPath(sceneAsset);
                    if (string.IsNullOrEmpty(path))
                    {
                        Debug.LogError("Selected SceneAsset path is invalid");
                        continue;
                    }

                    var sceneAssetPack = CompanionSceneUtils.GetOrTryCreateAssetPackForSceneAsset(sceneAsset);
                    sceneAssetPack.Clear();
                    sceneAssetPack.SceneAsset = sceneAsset;
                    var removeScene = true;
                    var unload      = true;
                    var sceneCount  = SceneManager.sceneCount;
                    for (var i = 0; i < sceneCount; i++)
                    {
                        var existingScene = SceneManager.GetSceneAt(i);
                        if (existingScene.path == path)
                        {
                            if (existingScene.isLoaded)
                            {
                                unload = false;
                            }

                            removeScene = false;
                            break;
                        }
                    }

                    var scene     = EditorSceneManager.OpenScene(path, OpenSceneMode.Additive);
                    var assetGuid = AssetDatabase.AssetPathToGUID(path);
                    if (string.IsNullOrEmpty(assetGuid))
                    {
                        Debug.LogError("Could not get valid guid for asset at path " + path);
                        continue;
                    }

                    // Hide the OnDestroyNotifier so it is not saved
                    foreach (var root in scene.GetRootGameObjects())
                    {
                        var notifier = root.GetComponentInChildren <OnDestroyNotifier>();
                        if (notifier != null)
                        {
                            notifier.gameObject.hideFlags = HideFlags.HideAndDontSave;
                        }
                    }

                    // generate and save thumbnail image for the scene by running a one-shot simulation
                    var thumbnail = SimulateSceneAndCaptureThumbnail();
                    var cloudGuid = CompanionResourceSync.instance.GetCloudGuid(assetGuid);
                    s_UploadCount++;
                    k_Requests.Clear();
                    k_Requests.Push(subscriber.SaveScene(project, resourceFolder, cloudGuid, scene, sceneAssetPack,
                                                         (success, key, size) =>
                    {
                        if (scene.IsValid())
                        {
                            // Restore OnDestroyNotifier HideFlags so that it is discoverable
                            foreach (var root in scene.GetRootGameObjects())
                            {
                                var notifier = root.GetComponentInChildren <OnDestroyNotifier>();
                                if (notifier != null)
                                {
                                    notifier.gameObject.hideFlags = HideFlags.HideInHierarchy;
                                }
                            }
                        }

                        var sceneName = sceneAsset.name;
                        if (success)
                        {
                            k_ResourceListUpdates.Add(new ResourceListUpdate
                            {
                                ResourceKey = key,
                                Name        = sceneName,
                                Type        = ResourceType.Scene,
                                FileSize    = size,
                                HasBundle   = sceneAssetPack.AssetCount > 0,
                                Thumbnail   = thumbnail
                            });

                            Debug.Log($"Published {sceneName}");
                        }
                        else
                        {
                            Debug.LogError($"Failed to publish {sceneName}");
                        }

                        if (--s_UploadCount == 0)
                        {
                            FinalizePublish(k_Requests);
                        }
                    }));

                    // Scene serialization is synchronous, so we can close the scene while the upload completes
                    if (unload)
                    {
                        EditorSceneManager.CloseScene(scene, removeScene);
                    }

                    continue;
                }

                if (selected is GameObject prefab)
                {
                    var path = AssetDatabase.GetAssetPath(prefab);
                    if (string.IsNullOrEmpty(path))
                    {
                        Debug.LogError("SceneAsset for selected AssetPack path is invalid");
                        continue;
                    }

                    var guid = AssetDatabase.AssetPathToGUID(path);
                    if (string.IsNullOrEmpty(guid))
                    {
                        Debug.LogError("Could not get valid guid for asset at path " + path);
                        continue;
                    }

                    // Check existing asset bundle name to avoid overwriting it
                    var assetImporter = AssetImporter.GetAtPath(path);
                    if (!string.IsNullOrEmpty(assetImporter.assetBundleName) && assetImporter.assetBundleName != guid)
                    {
                        Debug.LogError(prefab.name + " is already part of an AssetBundle, and cannot be published to the cloud without overwriting its AssetBundle name");
                        continue;
                    }

                    var bounds = BoundsUtils.GetBounds(prefab.transform);
                    if (bounds.extents.MinComponent() < k_MinPrefabBound)
                    {
                        Debug.LogError(prefab.name + " is too small to be selectable. MARS prefabs must be selectable.");
                        continue;
                    }

                    var thumbnail = ThumbnailUtility.GeneratePrefabThumbnail(prefab);
                    if (thumbnail == null)
                    {
                        Debug.LogError(prefab.name + " is not a visible asset. MARS prefabs must be visible.");
                        continue;
                    }

                    s_UploadCount++;
                    k_Requests.Clear();
                    k_Requests.Push(subscriber.SavePrefab(project, resourceFolder, prefab, (success, key) =>
                    {
                        if (success)
                        {
                            k_ResourceListUpdates.Add(new ResourceListUpdate
                            {
                                ResourceKey = key,
                                Name        = prefab.name,
                                Type        = ResourceType.Prefab,
                                HasBundle   = true,
                                Thumbnail   = thumbnail
                            });

                            Debug.Log($"Published {prefab.name}");
                        }
                        else
                        {
                            Debug.LogError($"Failed to publish {prefab.name}");
                        }

                        if (--s_UploadCount == 0)
                        {
                            FinalizePublish(k_Requests);
                        }
                    }));
                }
            }
        }