Screenshot coroutine not working

Hi everyone,

I have been trying to introduce a screenshot capturing function into my CorgiEngine game. Effectively when the player dies, after 1.5 seconds, I want to capture a screenshot. Then another 1.5 seconds would pass and the game over ui would pop up which would include that screenshot just captured. Unfortunately I havent been able to get this coroutine to work and gives an error.

Is there something obvious which I am not doing correctly? Any insight would be much appreciated!

Here are my 2 scripts;

LevelManager.cs - I am trying to call screenshot function into lines 84-85
VoxelBustersManager.cs - line 35 starts the screenshot

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;
using UnityEngine;
using UnityEngine.SceneManagement;
using MoreMountains.Tools;
using MoreMountains.MMInterface;

namespace MoreMountains.CorgiEngine
{   
    /// <summary>
    /// Spawns the player, handles checkpoints and respawn
    /// </summary>
    [AddComponentMenu("Corgi Engine/Managers/Level Manager")]
    public class LevelManager : Singleton<LevelManager>, MMEventListener<CorgiEngineEvent>
    {   

        /// the prefab you want for your player
        [Header("Playable Characters")]
        [Information("The LevelManager is responsible for handling spawn/respawn, checkpoints management and level bounds. Here you can define one or more playable characters for your level..",InformationAttribute.InformationType.Info,false)]
        /// the list of player prefabs to instantiate
        public Character[] PlayerPrefabs ;
        /// should the player IDs be auto attributed (usually yes)
        public bool AutoAttributePlayerIDs = true;

       
        [Space(10)]
        [Header("Intro and Outro durations")]
        [Information("Here you can specify the length of the fade in and fade out at the start and end of your level. You can also determine the delay before a respawn.",InformationAttribute.InformationType.Info,false)]
        /// duration of the initial fade in (in seconds)
        public float IntroFadeDuration=1f;
        /// duration of the fade to black at the end of the level (in seconds)
        public float OutroFadeDuration=1f;
        /// duration between a death of the main character and its respawn
        public float RespawnDelay = 3f;
        public float ScreenshotDelay = 1.5f;

        /// the elapsed time since the start of the level
        public TimeSpan RunningTime { get { return DateTime.UtcNow - _started ;}}
        public CameraController LevelCameraController { get; set; }

        // private stuff
        public List<Character> Players { get; protected set; }
        public List<CheckPoint> Checkpoints { get; protected set; }
        protected DateTime _started;
        protected int _savedPoints;
        public NoGoingBack NoGoingBackObject { get; protected set; }
        protected string _nextLevel = null;
       

        /// <summary>
        /// Kills the player.
        /// </summary>
        public virtual void KillPlayer(Character player)
        {
            Health characterHealth = player.GetComponent<Health>();
            if (characterHealth == null)
            {
                return;
            }
            else
            {
               
                // we kill the character
                characterHealth.Kill ();
                MMEventManager.TriggerEvent(new CorgiEngineEvent(CorgiEngineEventTypes.PlayerDeath));

                // if we have only one player, we restart the level
                if (Players.Count < 2)
                {
                    StartCoroutine (SoloModeRestart ());
                }
            }
        }

        /// <summary>
        /// Coroutine that kills the player, stops the camera, resets the points.
        /// </summary>
        /// <returns>The player co.</returns>
        protected virtual IEnumerator SoloModeRestart()
        {
            /// Trying to call a SCREENSHOT function from VoxelBustersManager.
            yield return new WaitForSeconds(ScreenshotDelayDelay);
            StartCoroutine (VoxelBustersManager.Instance.CaptureScreenShoot());
            ///
       
            if (PlayerPrefabs.Count() <= 0)
            {
                yield break;
            }

            // if we've setup our game manager to use lives (meaning our max lives is more than zero)
            if (GameManager.Instance.MaximumLives > 0)
            {
                // we lose a life
                GameManager.Instance.LoseLife ();
                // if we're out of lives, we check if we have an exit scene, and move there
                if (GameManager.Instance.CurrentLives <= 0)
                {
                    GameOver();
                }
            }

            if (LevelCameraController != null)
            {
                LevelCameraController.FollowsPlayer=false;
            }

            yield return new WaitForSeconds(RespawnDelay);

            if (LevelCameraController != null)
            {
                LevelCameraController.FollowsPlayer=true;
            }

            if (CurrentCheckPoint != null)
            {
                CurrentCheckPoint.SpawnPlayer(Players[0]);
            }           
            _started = DateTime.UtcNow;
            // we send a new points event for the GameManager to catch (and other classes that may listen to it too)
            MMEventManager.TriggerEvent (new CorgiEnginePointsEvent (PointsMethods.Set, 0));
            // we trigger a respawn event
            MMEventManager.TriggerEvent(new CorgiEngineEvent(CorgiEngineEventTypes.Respawn));     

        }

        public void GameOver()
        {
            MMEventManager.TriggerEvent(new CorgiEngineEvent(CorgiEngineEventTypes.Pause));
            MMEventManager.TriggerEvent(new CorgiEngineEvent(CorgiEngineEventTypes.GameOver));
        }


    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using VoxelBusters;
using VoxelBusters.NativePlugins;

public class VoxelBustersManager : MonoBehaviour {

        private bool isSharing = false;

        public void RateMyApp()
        {
                if (Application.platform == RuntimePlatform.Android)
                {
                        NPBinding.Utility.OpenStoreLink ("com.RoixoGames.TwinSuns");
                }
        }

        public void ShareSocialMedia ()
        {
                isSharing = true;
        }

        void LateUpdate ()
        {
                if (isSharing == true)
                {
                        isSharing = false;

                        StartCoroutine (CaptureScreenShoot());
                }
        }

        IEnumerator CaptureScreenShoot ()
        {
                yield return new WaitForEndOfFrame ();

                Texture2D texture = ScreenCapture.CaptureScreenshotAsTexture ();

                ShareSheet (texture);

                Object.Destroy (texture);
                       
        }

        private void ShareSheet (Texture2D texture)
        {
                ShareSheet _shareSheet = new ShareSheet ();

                _shareSheet.Text = "Hello world!!!";
                _shareSheet.AttachImage (texture);
                _shareSheet.URL = "https://twitter.com/RoixoGames
                NPBinding.Sharing.ShowView (_shareSheet, FinishSharing);
        }

        private void FinishSharing (eShareResult _result)
        {
                Debug.Log (_result);
        }
}

Not sure what NPBinding.Sharing.ShowView() does but probably it makes an asynchronous call to some API.
That means that it doesn’t finish immediately but can take some time (that’s why there is the callback argument).

What you do is destroying the texture right after you trigger to share the sheet. When the Texture is actually needed for upload or something, it is already destroyed.
Solution: put the destruction of the texture into the FinishSharing() method.

BTW: there is also a compile error. you should add "; at the end of the line where you assign the URL.