예제 #1
0
        /// <summary>
        /// Unload a previously loaded audio asset
        /// </summary>
        /// <param name="asset">Audio asset</param>
        public void SoundUnload(AudioAsset asset)
        {
            if (asset == null)
            {
                return;
            }

            // Let audio know this sound is about to be unloaded so it can react as needed
            RetroBlitInternal.RBAPI.instance.Audio.SoundAssetWasUnloaded(asset);

            // Abort any existing async load for this asset
            AbortAsyncSoundLoad(asset);

            asset.InternalSetErrorStatus(RB.AssetStatus.Invalid, RB.Result.Undefined);

            if (asset.audioClip != null)
            {
                asset.audioClip.UnloadAudioData();
                asset.audioClip = null;
            }
        }
예제 #2
0
        /// <summary>
        /// Load a sound asset from the given location
        /// </summary>
        /// <param name="fileName">Filename</param>
        /// <param name="asset">Asset object to load into</param>
        /// <param name="source">Source type</param>
        /// <returns>True if successful</returns>
        public bool SoundLoad(string fileName, AudioAsset asset, RB.AssetSource source)
        {
            if (asset == null)
            {
                return(false);
            }

            asset.progress = 0;

            if (asset.audioClip != null)
            {
                asset.audioClip.UnloadAudioData();
            }

            // Abort any existing async load for this asset
            AbortAsyncSoundLoad(asset);

            if (fileName == null)
            {
                Debug.LogError("Audio filename is null!");
                asset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam);
                return(false);
            }

            fileName.Replace('\\', '/');

            var loader = new RBAudioLoader();

            loader.Load(fileName, asset, source);

            if (asset.status == RB.AssetStatus.Ready)
            {
                return(true);
            }

            // Always add to async queue, even if immediately failed. This gives out consistent async method of error checking
            mASyncSoundClips.Add(loader);

            return(true);
        }
예제 #3
0
        /// <summary>
        /// Update asynchronous loading
        /// </summary>
        public void Update()
        {
            // If not loading then there is nothing to update
            if (audioAsset == null || audioAsset.status != RB.AssetStatus.Loading)
            {
                return;
            }

            if (mResourceRequest != null)
            {
                if (mResourceRequest.isDone)
                {
                    if (mResourceRequest.asset == null)
                    {
                        audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined);
                    }
                    else
                    {
                        audioAsset.audioClip = (AudioClip)mResourceRequest.asset;
                        audioAsset.progress  = 1;
                        audioAsset.InternalSetErrorStatus(RB.AssetStatus.Ready, RB.Result.Success);
                    }
                }
                else
                {
                    audioAsset.progress = mResourceRequest.progress;
                }
            }
            else if (mWebRequest != null)
            {
                try
                {
                    if (mWebRequest.isDone)
                    {
#if UNITY_2020_1_OR_NEWER
                        if (mWebRequest.result == UnityWebRequest.Result.ConnectionError)
#else
                        if (mWebRequest.isNetworkError)
#endif
                        {
                            audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NetworkError);
                        }
#if UNITY_2020_1_OR_NEWER
                        else if (mWebRequest.result == UnityWebRequest.Result.ProtocolError)
#else
                        else if (mWebRequest.isHttpError)
#endif
                        {
                            // Start with generic "ServerError" for all HTTP errors
                            var resultError = RB.Result.ServerError;

                            // Assign specific code for common HTTP errors
                            switch (mWebRequest.responseCode)
                            {
                            case 400:
                                resultError = RB.Result.BadParam;
                                break;

                            case 403:
                                resultError = RB.Result.NoPermission;
                                break;

                            case 404:
                                resultError = RB.Result.NotFound;
                                break;

                            case 500:
                                resultError = RB.Result.ServerError;
                                break;
                            }

                            audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, resultError);
                        }
                        else
                        {
                            audioAsset.progress  = 1;
                            audioAsset.audioClip = DownloadHandlerAudioClip.GetContent(mWebRequest);
                            audioAsset.InternalSetErrorStatus(RB.AssetStatus.Ready, RB.Result.Success);
                        }
                    }
                    else
                    {
                        audioAsset.progress = Mathf.Clamp01(mWebRequest.downloadProgress);
                    }
                }
                catch (Exception)
                {
                    audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined);
                }
            }
#if ADDRESSABLES_PACKAGE_AVAILABLE
            else if (mAddressableRequest.IsValid())
            {
                if (mAddressableRequest.Status == AsyncOperationStatus.Failed)
                {
                    // Can't really figure out failure reason
                    Addressables.Release(mAddressableRequest);
                    audioAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined);
                    return;
                }
                else if (mAddressableRequest.Status == AsyncOperationStatus.Succeeded)
                {
                    audioAsset.progress          = 1;
                    audioAsset.audioClip         = mAddressableRequest.Result;
                    audioAsset.addressableHandle = mAddressableRequest;
                    audioAsset.SetErrorStatus(RB.AssetStatus.Ready, RB.Result.Success);
                    return;
                }

                if (!mAddressableRequest.IsDone)
                {
                    audioAsset.progress = mAddressableRequest.PercentComplete;
                    return;
                }
            }
#endif
        }
예제 #4
0
        /// <summary>
        /// Load audio asset
        /// </summary>
        /// <param name="path">Path to load from</param>
        /// <param name="asset">AudioAsset to load into</param>
        /// <param name="source">Source type</param>
        /// <returns>True if successful</returns>
        public bool Load(string path, AudioAsset asset, RB.AssetSource source)
        {
            audioAsset = asset;
            this.path  = path;

            if (path == null)
            {
                audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam);
            }

            if (asset == null)
            {
                Debug.LogError("AudioAsset is null!");
                return(false);
            }

            if (source == RB.AssetSource.Resources)
            {
                // Synchronous load
                if (path == null)
                {
                    Debug.LogError("Audio filename is null!");
                    audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam);
                    return(false);
                }

#if !RETROBLIT_STANDALONE
                var clip = Resources.Load <AudioClip>(path);
#else
                var clip = Resources.LoadAudioSample(path);
#endif

                if (clip == null)
                {
                    Debug.LogError("Can't find sound file " + path + ", it must be under the Assets/Resources folder. " +
                                   "If you're trying to load from an WWW address, or Addressable Assets then please specify so with the \"source\" parameter.");

                    audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotFound);
                    return(false);
                }

                // If current music clip is affected then update the clip
                if (asset == RetroBlitInternal.RBAPI.instance.Audio.currentMusicClip)
                {
                    var channel = RetroBlitInternal.RBAPI.instance.Audio.musicChannel;
                    if (channel.Source != null)
                    {
                        channel.Source.clip = clip;
                        channel.Source.loop = true;
                        channel.Source.Play();
                    }
                }

                asset.audioClip = clip;
                asset.progress  = 1;
                audioAsset.InternalSetErrorStatus(RB.AssetStatus.Ready, RB.Result.Success);

                return(true);
            }
            else if (source == RB.AssetSource.WWW)
            {
                var audioType = AudioTypeFromPath(path);
                if (audioType == AudioType.UNKNOWN)
                {
                    audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotSupported);
                    return(false);
                }

                mWebRequest = UnityWebRequestMultimedia.GetAudioClip(path, audioType);
                if (mWebRequest == null)
                {
                    audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources);
                    return(false);
                }

                if (mWebRequest.SendWebRequest() == null)
                {
                    audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources);
                    return(false);
                }

                audioAsset.progress = 0;
                audioAsset.InternalSetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending);

                return(true);
            }
#if ADDRESSABLES_PACKAGE_AVAILABLE
            else if (source == RB.AssetSource.AddressableAssets)
            {
                // Exceptions on LoadAssetAsync can't actually be caught... this might work in the future so leaving it here
                try
                {
                    mAddressableRequest = Addressables.LoadAssetAsync <AudioClip>(path);
                }
                catch (UnityEngine.AddressableAssets.InvalidKeyException e)
                {
                    RBUtil.Unused(e);
                    audioAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotFound);
                    return(false);
                }
                catch (Exception e)
                {
                    RBUtil.Unused(e);
                    audioAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined);
                    return(false);
                }

                // Check for an immediate failure
                if (mAddressableRequest.Status == AsyncOperationStatus.Failed)
                {
                    audioAsset.addressableHandle = mAddressableRequest;
                    audioAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined);
                    return(false);
                }

                audioAsset.progress = 0;
                audioAsset.SetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending);

                return(true);
            }
#endif
            else if (source == RB.AssetSource.ResourcesAsync)
            {
                // Finally attempt async resource load
                mResourceRequest = Resources.LoadAsync <AudioClip>(this.path);

                if (mResourceRequest == null)
                {
                    audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources);
                    return(false);
                }

                audioAsset.InternalSetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending);
            }
            else
            {
                audioAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotSupported);
                return(false);
            }

            return(true);
        }