예제 #1
0
        internal AsyncOperationHandle <TObject> GetAssetAsync <TObject>(AssetTableEntry entry) where TObject : Object
        {
            if (!entry.AsyncOperation.HasValue)
            {
                // Empty entries are treated as null.
                if (string.IsNullOrEmpty(entry.Guid))
                {
                    entry.AsyncOperation = ResourceManager.CreateCompletedOperation <TObject>(null, null);
                }
                else
                {
                    entry.AsyncOperation = AddressablesInterface.LoadAssetFromGUID <TObject>(entry.Guid);
                }
            }

            var operation = entry.AsyncOperation.Value;

            try
            {
                return(operation.Convert <TObject>());
            }
            catch (InvalidCastException)
            {
                // If we preloaded then the operation will be of type AsyncOperationHandle<Object[]> however we now
                // need to extract the asset and convert to AsyncOperationHandle<TObject>.

                if (operation.IsDone)
                {
                    if (operation.Status != AsyncOperationStatus.Succeeded)
                    {
                        return(ResourceManager.CreateCompletedOperation <TObject>(null, operation.OperationException.Message));
                    }

                    // Extract the asset from the array of preloaded sub objects.
                    if (operation.Result is Object[] subObjects)
                    {
                        foreach (var obj in subObjects)
                        {
                            if (obj is TObject target)
                            {
                                var convertedCompletedOperation = ResourceManager.CreateCompletedOperation(target, null);
                                entry.AsyncOperation = convertedCompletedOperation;
                                AddressablesInterface.Release(operation); // Release the old operation
                                return(convertedCompletedOperation);
                            }
                        }
                    }
                    throw new InvalidCastException($"Could not convert asset of type {operation.Result.GetType().Name} to {typeof(TObject).Name}.");
                }

                // Wait for the operation to complete before attempting again
                var convertedOperation = ResourceManager.CreateChainOperation(operation, (op) => GetAssetAsync <TObject>(entry));
                entry.AsyncOperation = convertedOperation;
                AddressablesInterface.Release(operation); // Release the old operation
                return(convertedOperation);
            }
        }
예제 #2
0
        AsyncOperationHandle PreloadAssets()
        {
            // Check the metadata to see if we should preload. First we check the table preload data, if one does not exist then check the key database(global).
            var preload = GetMetadata <PreloadAssetTableMetadata>() ?? SharedData.Metadata.GetMetadata <PreloadAssetTableMetadata>();

            // If no preload metadata was found then we will preload all assets by default.
            if (preload?.Behaviour != PreloadAssetTableMetadata.PreloadBehaviour.NoPreload)
            {
                var handleList = ListPool <AsyncOperationHandle> .Get();

                // Preload all
                foreach (var entry in Values)
                {
                    if (!entry.IsEmpty && !entry.AsyncOperation.HasValue)
                    {
                        // We have to preload the asset as an array so that we get all sub objects. The reason for this is that some assets,
                        // such as Sprite can contain multiple sub objects and if we load it as Object then we may get the wrong one.
                        // For example, if we load a Sprite as an Object and it has the same name as its Texture asset then it will load as a Texture,
                        // not Sprite. So if we load as an array we get both, we can then pick the one we need later based on the type passed into GetAssetAsync. (LOC-143)
                        entry.AsyncOperation = AddressablesInterface.LoadAssetFromGUID <Object[]>(entry.Guid);
                        ResourceManager.Acquire(entry.AsyncOperation.Value);
                        handleList.Add(entry.AsyncOperation.Value);
                    }
                }
                if (handleList.Count > 0)
                {
                    return(ResourceManager.CreateGenericGroupOperation(handleList));
                }
                else
                {
                    ListPool <AsyncOperationHandle> .Release(handleList);
                }
            }

            // Nothing to preload, we are done
            return(ResourceManager.CreateCompletedOperation(this, null));
        }