void OnDestroy()
    {
        isDestroyed = true;

        if (hqTextureHandler != null)
        {
            hqTextureHandler.Dispose();
            hqTextureHandler = null;
        }

        if (gifPlayer != null)
        {
            gifPlayer.OnFrameTextureChanged -= UpdateTexture;
            gifPlayer.Dispose();
        }

        if (assetPromise != null)
        {
            assetPromise.Forget();
            assetPromise = null;
        }

        if (backgroundMaterial != null)
        {
            Object.Destroy(backgroundMaterial);
        }
        if (imageMaterial != null)
        {
            Object.Destroy(imageMaterial);
        }
    }
    protected void SetUp()
    {
        isHQAsset = false;
        camera    = new GameObject("Camera")
        {
            tag = "MainCamera"
        }.AddComponent <Camera>();

        asset = Substitute.For <INFTAsset>();
        asset.When(a => a.RestorePreviewAsset())
        .Do(i =>
        {
            isHQAsset = false;
            asset.isHQ.Returns(false);
        });
        asset.WhenForAnyArgs(a => a.FetchAndSetHQAsset(null, null, null))
        .Do(i =>
        {
            isHQAsset = true;
            asset.isHQ.Returns(true);
        });

        nftGO = new GameObject();
        var nftController = NFTShapeFactory.InstantiateLoaderController(0).GetComponent <NFTShapeLoaderController>();

        nftController.transform.SetParent(nftGO.transform);
        nftController.transform.ResetLocalTRS();

        nftGO.transform.position = new Vector3(10, 0, 10);
        nftShapeConfig           = nftController.config;

        var config = new NFTShapeHQImageConfig()
        {
            asset      = asset,
            controller = nftController,
            nftConfig  = nftShapeConfig
        };

        imageHandler = NFTShapeHQImageHandler.Create(config);
    }
    IEnumerator FetchNFTImage()
    {
        if (spinner != null)
        {
            spinner.SetActive(true);
        }

        NFTInfo nftInfo = new NFTInfo();

        bool isError = false;

        yield return(NFTHelper.FetchNFTInfo(darURLRegistry, darURLAsset,
                                            (info) =>
        {
            nftInfo = info;
        },
                                            (error) =>
        {
            Debug.LogError($"Couldn't fetch NFT: '{darURLRegistry}/{darURLAsset}' {error}");
            OnLoadingAssetFail?.Invoke();
            isError = true;
        }));

        if (isError)
        {
            yield break;
        }

        yield return(new DCL.WaitUntil(() => (CommonScriptableObjects.playerUnityPosition - transform.position).sqrMagnitude < (config.loadingMinDistance * config.loadingMinDistance)));

        // We download the "preview" 256px image
        bool foundDCLImage = false;

        if (!string.IsNullOrEmpty(nftInfo.previewImageUrl))
        {
            yield return(WrappedTextureUtils.Fetch(nftInfo.previewImageUrl, (promise) =>
            {
                foundDCLImage = true;
                this.assetPromise = promise;
                SetFrameImage(promise.asset, resizeFrameMesh: true);
                SetupGifPlayer(promise.asset);

                var hqImageHandlerConfig = new NFTShapeHQImageConfig()
                {
                    controller = this,
                    nftConfig = config,
                    nftInfo = nftInfo,
                    asset = NFTAssetFactory.CreateAsset(promise.asset, config, UpdateTexture, gifPlayer)
                };
                hqTextureHandler = NFTShapeHQImageHandler.Create(hqImageHandlerConfig);
            }));
        }

        //We fall back to the nft original image which can have a really big size
        if (!foundDCLImage && !string.IsNullOrEmpty(nftInfo.originalImageUrl))
        {
            yield return(WrappedTextureUtils.Fetch(nftInfo.originalImageUrl,
                                                   (promise) =>
            {
                foundDCLImage = true;
                this.assetPromise = promise;
                SetFrameImage(promise.asset, resizeFrameMesh: true);
                SetupGifPlayer(promise.asset);
            }, () => isError = true));
        }

        if (isError)
        {
            Debug.LogError($"Couldn't fetch NFT image for: '{darURLRegistry}/{darURLAsset}' {nftInfo.originalImageUrl}");
            OnLoadingAssetFail?.Invoke();
            yield break;
        }

        FinishLoading(foundDCLImage);
    }