/// <summary> /// Load shader asset from the given source /// </summary> /// <remarks> /// Load a shader asset which can be used when drawing sprites or applying screen effects. There are various asset sources supported: /// <list type="bullet"> /// <item><b>Resources</b> - Synchronously loaded shader assets from a <b>Resources</b> folder. This was the only asset source supported in RetroBlit prior to 3.0.</item> /// <item><b>ResourcesAsync</b> - Asynchronously loaded shader assets from a <b>Resources</b> folder.</item> /// <item><b>AddressableAssets</b> - Asynchronously loaded shader assets from Unity Addressable Assets.</item> /// <item><b>Existing Assets</b> - Synchronously loaded shader assets from an existing Unity <b>Shader</b>.</item> /// </list> /// /// If the asset is loaded via a synchronous method then <b>Load</b> will block until the loading is complete. /// If the asset is loaded via an asynchronous method then <b>Load</b> will immediately return and the asset loading will /// continue in a background thread. The status of an asynchronous loading asset can be check by looking at <see cref="RBAsset.status"/>, /// or by using the event system with <see cref="RBAsset.OnLoadComplete"/> to get a callback when the asset is done loading. /// /// Note that unlike other asset types, <b>WWW</b> does not support loading shaders, this is a limitation of Unity. /// <seedoc>Features:Shaders (Advanced Topic)</seedoc> /// <seedoc>Features:Asynchronous Asset Loading</seedoc> /// </remarks> /// <code> /// ShaderAsset shaderFancy = new ShaderAsset(); /// /// public void Initialize() /// { /// // Load asset from Resources asynchronously. This method call will immediately return without blocking. /// shaderFancy.Load("fancy_shader", RB.AssetSource.ResourcesAsync); /// } /// /// public void Render() /// { /// if (shaderFancy.status == RB.AssetStatus.Ready) /// { /// RB.ShaderSet(shaderFancy); /// } /// /// // Draw a sprite with the shader applied if the shader has finished loading. /// RB.DrawSprite("hero/walk1", playerPos); /// } /// </code> /// <param name="filename">File name to load from</param> /// <param name="source">Asset source type</param> /// <returns>Load status</returns> /// <seealso cref="RB.Result"/> /// <seealso cref="RB.AssetStatus"/> /// <seealso cref="RB.AssetSource"/> public RB.AssetStatus Load(string filename, RB.AssetSource source = RB.AssetSource.Resources) { Unload(); if (!RetroBlitInternal.RBAssetManager.CheckSourceSupport(source)) { InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotSupported); return(status); } RetroBlitInternal.RBAPI.instance.AssetManager.ShaderLoad(filename, this, source); return(status); }
/// <summary> /// Load Map /// </summary> /// <param name="path">Path to load from</param> /// <param name="asset">TMXMapAsset to load into</param> /// <param name="source">Asset source</param> /// <returns>True if successful</returns> public bool Load(string path, TMXMapAsset asset, RB.AssetSource source) { this.mapAsset = asset; this.path = path; mSource = source; if (asset == null) { Debug.LogError("TMXMapAsset is null!"); return(false); } LoadMapInfo(); return(true); }
/// <summary> /// Load sprite sheet asset /// </summary> /// <param name="path">Path to load from</param> /// <param name="asset">SpriteSheetAsset to load into</param> /// <param name="source">Source type</param> /// <returns>True if successful</returns> public bool Load(string path, SpriteSheetAsset asset, RB.AssetSource source) { this.spriteSheetAsset = asset; this.path = path; mSource = source; if (asset == null) { Debug.LogError("SpriteSheetAsset is null!"); return(false); } LoadSpritePackInfo(); return(true); }
/// <summary> /// Constructor /// </summary> /// <param name="layerState">Layer state</param> /// <param name="tmxSourceLayer">TMX source layer</param> /// <param name="destinationLayer">Destination layer</param> /// <param name="chunkOffset">Chunk offset</param> /// <param name="destPos">Destination position</param> /// <param name="packedSpriteLookup">Packed sprite lookup</param> /// <param name="source">Source type</param> public RBTMXLayerChunkLoader(TMXMapAsset.TMXLayerLoadState layerState, string tmxSourceLayer, int destinationLayer, Vector2i chunkOffset, Vector2i destPos, PackedSpriteID[] packedSpriteLookup, RB.AssetSource source) { if (layerState == null) { Debug.LogError("LayerLoadState is null!"); return; } this.layerState = layerState; mSource = source; mChunkOffset = chunkOffset; mDestPos = destPos; mPackedSpriteLookup = packedSpriteLookup; mTmxSourceLayer = tmxSourceLayer; mDestinationLayer = destinationLayer; LoadLayerChunkIndex(); return; }
/// <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); }
/// <summary> /// Check if given source type is supported /// </summary> /// <param name="source">Source type</param> /// <returns>True if supported, false otherwise</returns> public static bool CheckSourceSupport(RB.AssetSource source) { if (source == RB.AssetSource.Resources || source == RB.AssetSource.ResourcesAsync || source == RB.AssetSource.WWW) { return(true); } else if (source == RB.AssetSource.AddressableAssets) { #if ADDRESSABLES_PACKAGE_AVAILABLE return(true); #else Debug.LogError("Addressable Assets support is disabled. Please go to \"File->Build Settings->Player Settings->Other Settings->Scripting Define Symbols\"" + " and make sure ADDRESSABLES_PACKAGE_AVAILABLE is defined. If you have not done so already you may also need to install Addressable Assets Unity package for your project."); return(false); #endif } Debug.LogError(source.ToString() + " asset source is not supported!"); return(false); }
/// <summary> /// Load sprites from the given source /// </summary> /// <remarks> /// Load sprites which can be drawn to display or offscreen surfaces. This method is used to load both <b>SheetType.SpriteSheet</b> and <b>SheetType.SpritePack</b>. /// There are various asset sources supported: /// <list type="bullet"> /// <item><b>Resources</b> - Synchronously loaded sprite assets from a <b>Resources</b> folder. This was the only asset source supported in RetroBlit prior to 3.0.</item> /// <item><b>ResourcesAsync</b> - Asynchronously loaded sprite assets from a <b>Resources</b> folder.</item> /// <item><b>WWW</b> - Asynchronously loaded sprite assets from a URL.</item> /// <item><b>AddressableAssets</b> - Asynchronously loaded sprite assets from Unity Addressable Assets.</item> /// <item><b>Existing Assets</b> - Synchronously loaded sprite assets from an existing Unity <b>Texture2D</b> or <b>RenderTexture</b>.</item> /// </list> /// /// If the asset is loaded via a synchronous method then <b>Load</b> will block until the loading is complete. /// If the asset is loaded via an asynchronous method then <b>Load</b> will immediately return and the asset loading will /// continue in a background thread. The status of an asynchronous loading asset can be check by looking at <see cref="RBAsset.status"/>, /// or by using the event system with <see cref="RBAsset.OnLoadComplete"/> to get a callback when the asset is done loading. /// /// <seedoc>Features:Sprites</seedoc> /// <seedoc>Features:Asynchronous Asset Loading</seedoc> /// </remarks> /// <code> /// SpriteSheetAsset spriteMain = new SpriteSheetAsset(); /// /// public void Initialize() /// { /// // Load asset from Resources asynchronously. This method call will immediately return without blocking. /// spriteMain.Load("main_spritepack", RB.SheetType.SpritePack, RB.AssetSource.ResourcesAsync); /// } /// /// public void Render() /// { /// // Don't draw anything until sprites are loaded /// if (spriteMain.status != RB.AssetStatus.Ready) /// { /// return; /// } /// /// RB.SpriteSheetSet(spriteMain); /// RB.DrawSprite("hero/walk1", playerPos); /// } /// </code> /// <param name="path">Path of the sprite sheet</param> /// <param name="sheetType">The type of sprite sheet, either <see cref="SheetType.SpriteSheet"/> or <see cref="SheetType.SpritePack"/></param> /// <param name="source">Source type of the asset</param> /// <returns>Load status</returns> /// <seealso cref="RB.Result"/> /// <seealso cref="RB.AssetStatus"/> /// <seealso cref="RB.AssetSource"/> /// <seealso cref="RB.SheetType"/> public RB.AssetStatus Load(string path, SheetType sheetType = SheetType.SpriteSheet, RB.AssetSource source = RB.AssetSource.Resources) { Unload(); if (!RetroBlitInternal.RBAssetManager.CheckSourceSupport(source)) { InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotSupported); return(status); } RetroBlitInternal.RBAPI.instance.AssetManager.SpriteSheetLoad(this, new Vector2i(0, 0), path, null, source, sheetType); grid = SpriteGrid.fullSheet; return(status); }
/// <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); }
/// <summary> /// Load a sprite sheet or sprite pack from the given file, or create a blank one of given size, or load from an existing texture /// </summary> /// <param name="asset">Asset object to load into</param> /// <param name="size">Size of new empty spritesheet if no filename is specified</param> /// <param name="fileName">Filename</param> /// <param name="texture">Existing texture to use</param> /// <param name="source">Source type</param> /// <param name="sheetType">Sheet type</param> /// <returns>True if successful</returns> public bool SpriteSheetLoad(SpriteSheetAsset asset, Vector2i size, string fileName, RenderTexture texture, RB.AssetSource source, SpriteSheetAsset.SheetType sheetType) { if (asset == null) { return(false); } asset.progress = 0; // Release any existing asset SpriteSheetUnload(asset); asset.InternalSetErrorStatus(RB.AssetStatus.Invalid, RB.Result.Undefined); if (fileName != null) { fileName.Replace('\\', '/'); if (fileName.EndsWith(".sp.rb")) { Debug.LogError("Do not specify the .sp.rb file extension when loading a sprite pack"); asset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam); return(false); } else if ((sheetType == SpriteSheetAsset.SheetType.SpriteSheet && source != RB.AssetSource.WWW) && (fileName.EndsWith(".png") || fileName.EndsWith(".jpg") || fileName.EndsWith(".jpeg") || fileName.EndsWith(".gif") || fileName.EndsWith(".tif") || fileName.EndsWith(".tga") || fileName.EndsWith(".psd"))) { // Does not apply to WWW, must specify extension there to form valid http request Debug.LogError("Do not specify the image file extension when loading a sprite. For example, use \"hero\", instead of \"hero.png\""); asset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam); return(false); } } // Async loading implies we are not creating an empty texture, nor initializing from an existing texture if (source != RB.AssetSource.Resources && fileName == null) { asset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam); } else { if (sheetType == SpriteSheetAsset.SheetType.SpritePack) { // Abort any existing async load for this asset AbortAsyncSpritePackLoad(asset); var asyncSpritePackResource = new RBSpritePackLoader(); asyncSpritePackResource.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 mASyncSpritePacks.Add(asyncSpritePackResource); return(true); } else if (sheetType == SpriteSheetAsset.SheetType.SpriteSheet) { // Abort any existing async load for this asset AbortAsyncSpriteSheetLoad(asset); var asyncResource = new RBSpriteSheetLoader(); asyncResource.Load(fileName, texture, size, 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 mASyncSpriteSheets.Add(asyncResource); return(true); } else { asset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam); return(false); } } return(false); }
/// <summary> /// Load sprite sheet asset /// </summary> /// <param name="path">Path to asset</param> /// <param name="existingTexture">Existing texture to load from</param> /// <param name="size">Size of the texture</param> /// <param name="asset">SpriteSheetAsset to load into</param> /// <param name="source">Asset source type</param> /// <returns>True if successful</returns> public bool Load(string path, RenderTexture existingTexture, Vector2i size, SpriteSheetAsset asset, RB.AssetSource source) { this.spriteSheetAsset = asset; this.path = path; if (asset == null) { Debug.LogError("SpriteSheetAsset is null!"); return(false); } if (source == RB.AssetSource.Resources) { // Empty texture if (path == null && existingTexture == null) { if (size.x <= 0 || size.y <= 0) { spriteSheetAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam); return(false); } RenderTexture tex = new RenderTexture(size.x, size.y, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default); if (tex == null) { spriteSheetAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources); return(false); } tex.filterMode = FilterMode.Point; tex.wrapMode = TextureWrapMode.Clamp; tex.anisoLevel = 0; tex.antiAliasing = 1; tex.autoGenerateMips = false; tex.depth = 0; tex.useMipMap = false; tex.Create(); asset.internalState.texture = tex; asset.internalState.textureWidth = (ushort)tex.width; asset.internalState.textureHeight = (ushort)tex.height; #if MESH_UPLOAD_2019_3 asset.internalState.texelWidth = 0xFFFF / (float)tex.width; asset.internalState.texelHeight = 0xFFFF / (float)tex.height; #endif asset.internalState.spriteGrid.cellSize.width = (ushort)tex.width; asset.internalState.spriteGrid.cellSize.height = (ushort)tex.height; asset.internalState.columns = (ushort)(asset.internalState.textureWidth / asset.internalState.spriteGrid.cellSize.width); asset.internalState.rows = (ushort)(asset.internalState.textureHeight / asset.internalState.spriteGrid.cellSize.height); asset.internalState.needsClear = true; if (asset.internalState.columns < 1) { asset.internalState.columns = 1; } if (asset.internalState.rows < 1) { asset.internalState.rows = 1; } // If there is no spritesheet set then set this one as the current one if (RetroBlitInternal.RBAPI.instance.Renderer.CurrentSpriteSheet == null) { RetroBlitInternal.RBAPI.instance.Renderer.SpriteSheetSet(asset); } asset.progress = 1; spriteSheetAsset.InternalSetErrorStatus(RB.AssetStatus.Ready, RB.Result.Success); return(true); } else if (existingTexture != null) { asset.internalState.texture = existingTexture; asset.internalState.textureWidth = (ushort)existingTexture.width; asset.internalState.textureHeight = (ushort)existingTexture.height; #if MESH_UPLOAD_2019_3 asset.internalState.texelWidth = 0xFFFF / (float)existingTexture.width; asset.internalState.texelHeight = 0xFFFF / (float)existingTexture.height; #endif asset.internalState.spriteGrid.cellSize.width = (ushort)existingTexture.width; asset.internalState.spriteGrid.cellSize.height = (ushort)existingTexture.height; asset.internalState.columns = (ushort)(asset.internalState.textureWidth / asset.internalState.spriteGrid.cellSize.width); asset.internalState.rows = (ushort)(asset.internalState.textureHeight / asset.internalState.spriteGrid.cellSize.height); if (asset.internalState.columns < 1) { asset.internalState.columns = 1; } if (asset.internalState.rows < 1) { asset.internalState.rows = 1; } // If there is no spritesheet set then set this one as the current one if (RetroBlitInternal.RBAPI.instance.Renderer.CurrentSpriteSheet == null) { RetroBlitInternal.RBAPI.instance.Renderer.SpriteSheetSet(asset); } asset.progress = 1; spriteSheetAsset.InternalSetErrorStatus(RB.AssetStatus.Ready, RB.Result.Success); return(true); } else { // Synchronous load var spritesTextureOriginal = Resources.Load <Texture2D>(path); if (spritesTextureOriginal == null) { Debug.LogError("Could not load sprite sheet from " + path + ", make sure the resource is placed somehwere in Assets/Resources folder. " + "If you're trying to load a Sprite Pack then please specify \"SpriteSheetAsset.SheetType.SpritePack\" as \"sheetType\". " + "If you're trying to load from an WWW address, or Addressable Assets then please specify so with the \"source\" parameter."); asset.internalState.texture = null; spriteSheetAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotFound); return(false); } FinalizeTexture(spritesTextureOriginal); return(asset.status == RB.AssetStatus.Ready ? true : false); } } else if (source == RB.AssetSource.WWW) { if (!ImageTypeSupported(path)) { Debug.LogError("WWW source supports only PNG and JPG images"); spriteSheetAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotSupported); return(false); } mWebRequest = UnityWebRequestTexture.GetTexture(path, true); if (mWebRequest == null) { spriteSheetAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources); return(false); } if (mWebRequest.SendWebRequest() == null) { spriteSheetAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources); return(false); } spriteSheetAsset.InternalSetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending); return(true); } else if (source == RB.AssetSource.ResourcesAsync) { mResourceRequest = Resources.LoadAsync <Texture2D>(this.path); if (mResourceRequest == null) { spriteSheetAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources); return(false); } } #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 <Texture2D>(path); } catch (UnityEngine.AddressableAssets.InvalidKeyException e) { RBUtil.Unused(e); spriteSheetAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotFound); return(false); } catch (Exception e) { RBUtil.Unused(e); spriteSheetAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined); return(false); } // Check for an immediate failure if (mAddressableRequest.Status == AsyncOperationStatus.Failed) { Addressables.Release(mAddressableRequest); spriteSheetAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined); return(false); } spriteSheetAsset.progress = 0; spriteSheetAsset.SetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending); return(true); } #endif spriteSheetAsset.InternalSetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending); return(true); }
/// <summary> /// Load shader asset /// </summary> /// <param name="path">Path to load from</param> /// <param name="asset">ShaderAsset to load into</param> /// <param name="source">Source type</param> /// <returns>True if successful</returns> public bool Load(string path, ShaderAsset asset, RB.AssetSource source) { shaderAsset = asset; this.path = path; if (path == null) { shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam); } if (asset == null) { Debug.LogError("ShaderAsset is null!"); return(false); } if (source == RB.AssetSource.Resources) { // Synchronous load if (path == null) { Debug.LogError("Shader filename is null!"); shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam); return(false); } var shader = Resources.Load <Shader>(path); if (shader == null) { Debug.LogError("Could not load shader from " + path + ", make sure the resource is placed somehwere in Assets/Resources folder"); shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotFound); return(false); } return(FinalizeShader(shader)); } else if (source == RB.AssetSource.WWW) { // Not a supported source, should never get here shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotSupported); return(false); } else if (source == RB.AssetSource.ResourcesAsync) { // Finally attempt async resource load mResourceRequest = Resources.LoadAsync <Shader>(this.path); if (mResourceRequest == null) { shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources); return(false); } shaderAsset.progress = 0; shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending); } #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 <Shader>(this.path); } catch (UnityEngine.AddressableAssets.InvalidKeyException e) { RBUtil.Unused(e); shaderAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotFound); return(false); } catch (Exception e) { RBUtil.Unused(e); shaderAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined); return(false); } // Check for an immediate failure if (mAddressableRequest.Status == AsyncOperationStatus.Failed) { Addressables.Release(mAddressableRequest); shaderAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined); return(false); } shaderAsset.SetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending); shaderAsset.progress = 0; return(true); } #endif else { shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotSupported); return(false); } return(true); }