AsyncGPUReadback how to take simple screenshot no ienumerable

I’ve been trying to actually use Unity’s AsyncGPUReadback.Request with Jint in JavaScript also, but mainly just in C#, to make a basic screenshot without the use of IEnumerable or yield return new WaitForEndOfFrame or something (don’t remember exactly), but I want to use it only with checking the .done property in an Update loop. I have not been able to find any examples online, though I have read the documentation on it multiple times.

First this attempt

var cam = Camera.main;
			RenderTexture rat = new RenderTexture(
				1920, 1080, 24
			);
			cam.targetTexture = rat;
			Texture2D actual = new Texture2D(
				1920, 1080,
				TextureFormat.RGB24, false
			);
			cam.Render();
			RenderTexture.active = rat;
			
			
		/*	actual.ReadPixels(new Rect(0, 0, 1920, 1080),
				0, 	0);*/
				
			var reqt = AsyncGPUReadback.Request(rat);
			System.Action fncc = null;
			fncc = new System.Action(() => {
				if(reqt.done) {
					Debug.Log("well" + reqt.ToString());
					var data = reqt.GetData<byte>(0);
					Debug.Log(data);
					Yaakov.removeEvent("Update", fncc);
				}
				
			});
			Achdus.Yaakov.on("LateUpdate", fncc);//just some custom function to add events to the "Update" loop without monbehaviorus...
			
			cam.targetTexture = null;
			RenderTexture.active = null;
			var bite = actual.EncodeToPNG();
			System.IO.File.WriteAllBytes(
				path, bite
			);

gives me an error InvalidOperationException: Cannot access the data as it is not available, have absolutely no idea how to fix this

By combining some functions from the FFMPegOut library as well as [another script I found on github][1] I kind of almost got something

static Material blat;
		public static 
		void GetScreenshot(
			string path,
			System.Func<object, object> fnc
		) {
			
			
			var cam = Camera.main;
			var form = (
				cam
				.allowHDR ? RenderTextureFormat
					.DefaultHDR 
				:
				RenderTextureFormat.Default
			);
			int aal = cam.allowMSAA ? QualitySettings.
				antiAliasing : 1;
			int width = 1920;
			int height = 1080;
			RenderTexture rt;
			GameObject bl;
			if(cam.targetTexture == null) {
				rt = (
					new RenderTexture(
						width, height,
						24, form
					)
				);
				
				rt.antiAliasing = aal;
				
				cam.targetTexture = rt;
				
				bl = FFmpegOut
					.Blitter
					.CreateInstance(cam);
			}
			if(blat == null) {
				var shayd = Shader.Find(
					"Hidden/FFmpegOut/Preprocess"
				);
				blat = new Material(shayd);
			}
			
			var temp = RenderTexture.GetTemporary(
				cam.targetTexture.width,
				cam.targetTexture.height,
				0,
				RenderTextureFormat.ARGB32
			);
			
			Graphics.Blit(
				cam.targetTexture,
				temp,
				blat,
				0
			);
			
			var raq = UnityEngine
				.Rendering
				.AsyncGPUReadback.Request(
					temp
				);
				
			System.Action fncc = null;
			 var k = 0;
			fncc = new System.Action(() => {
				if(raq.done) {
					Debug.Log("ok man" + raq);
					var newTaxt = new Texture2D(
						cam.targetTexture.width,
						cam.targetTexture.height,
						TextureFormat.ARGB32, false
					);
					
					newTaxt.LoadRawTextureData(
						raq.GetData<uint>()
					);
					
					newTaxt.Apply();
					
					System.IO.File
					.WriteAllBytes(
						path,
						ImageConversion
						.EncodeToPNG(newTaxt)
					);
					Debug.Log("ok");
					Yaakov.removeEvent("Update", fncc);//not important here just imagine its all in another update
				}
			});
			Achdus.Yaakov.on("Update", fncc);//same as earlier just the same thing as having the above in an "Update" loop just without monos....
			
			RenderTexture.ReleaseTemporary(temp);
			
		}

which doesn’t give any errors but returns this
[![enter image description here][2]][2]
Don’t see much? Neither do I…

So does anyone actually know how to take a simple screenshot with AsyncGPUReadback.Request WITHOUT any IEnumerators?

And BTW, for those just wondering why not IEnumerators, many reasons, but when I try to use the script from Github I literally get no result unity 2020:

using UnityEngine;
using UnityEngine.Rendering;
using System.IO;
using System.Collections;

public class AsyncCapture : MonoBehaviour
{
    IEnumerator Start()
    {
        while (true)
        {
            yield return new WaitForSeconds(1);
            yield return new WaitForEndOfFrame();

            var rt = RenderTexture.GetTemporary(Screen.width, Screen.height, 0, RenderTextureFormat.ARGB32);
            ScreenCapture.CaptureScreenshotIntoRenderTexture(rt);
            AsyncGPUReadback.Request(rt, 0, TextureFormat.ARGB32, OnCompleteReadback);
            RenderTexture.ReleaseTemporary(rt);
        }
    }

    void OnCompleteReadback(AsyncGPUReadbackRequest request)
    {
        if (request.hasError)
        {
            Debug.Log("GPU readback error detected.");
            return;
        }

        var tex = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);
        tex.LoadRawTextureData(request.GetData<uint>());
        tex.Apply();
        File.WriteAllBytes("test.png", ImageConversion.EncodeToPNG(tex));
        Destroy(tex);
    }
}

it just seems to hang forever… but regardless I want to do this without IEnumerators
[1]: AsyncCaptureTest/Assets/AsyncCapture.cs at master · keijiro/AsyncCaptureTest · GitHub
[2]: https://i.stack.imgur.com/0QMUb.png

You can pass a callback in as a parameter to the Request function that will be executed when the data is available, very similarly to how you do it in the first example;

UnityEngine.Rendering.AsyncGPUReadback.Request (temp, (req) => 
{
    var newTex = new Texture2D
    (
        cam.targetTexture.width,
        cam.targetTexture.height,
        TextureFormat.ARGB32, 
        false
    );
                 
    newTex.LoadRawTextureData (req.GetData<uint>());
                 
    newTex.Apply();
                 
    System.IO.File.WriteAllBytes (path, ImageConversion.EncodeToPNG(newTex));
    Debug.Log("ok");
});

The AsyncGPUReadbackResult will be passed into the callback itself when finished, so you can just use it directly in there. Internally however, this is most likely implemented in a coroutine in the exact same way one could do it themselves;

public void Request (Texture a_Texture, Action<AsyncGPUReadbackRequest> a_Callback)
{
    IEnumerator RequestAsync (AsyncGPUReadbackRequest a_Request, Action<AsyncGPUReadbackRequest> a_Callback)
    {
        yield return a_Request;
        a_Callback?.Invoke (a_Request);
    }

    AsyncGPUReadbackRequest req = AsyncGPUReadback.Request (a_Texture);
    StartCoroutine (RequestAsync (req, a_Callback));
}