Hello all,
for all the newbies (like me) that struggled a lot to understand how to let the users to take a screenshot of their webgl game (or application), and directly open it in a new tab of their browser without blocking, here a brief tutorial (without explanations).
I’ve resarched a bit to understand how to use data:URI, that does not write anything on disk (very important since we don’t know the target platform) but simply use the buffer, and I’ve use the preciuos tutorial from Valentin Simonov to open the new tab without blocking.
Please support him! He’s great!
I’m not a coder so probably it will not be the best, and it will have some mistakes (so forgive me), but it work.
-
First you need a button that users will push to take the screenshot and open it in a new tab of their browser, so create a button.
-
Create this script and named it “TakeScreenshot” (and put it maybe under your “script” folder)
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class TakeScreenshot : MonoBehaviour {
// Use this for initialization
public void Screenshot () {
StartCoroutine(UploadPNG());
//Debug.log (encodedText);
}
IEnumerator UploadPNG() {
// We should only read the screen after all rendering is complete
yield return new WaitForEndOfFrame();
// Create a texture the size of the screen, RGB24 format
int width = Screen.width;
int height = Screen.height;
var tex = new Texture2D( width, height, TextureFormat.RGB24, false );
// Read screen contents into the texture
tex.ReadPixels( new Rect(0, 0, width, height), 0, 0 );
tex.Apply();
// Encode texture into PNG
byte[] bytes = tex.EncodeToPNG();
Destroy( tex );
//string ToBase64String byte[]
string encodedText = System.Convert.ToBase64String (bytes);
var image_url = "data:image/png;base64," + encodedText;
Debug.Log (image_url);
#if !UNITY_EDITOR
openWindow(image_url);
#endif
}
[DllImport("__Internal")]
private static extern void openWindow(string url);
}
- Create this other script
(many thanks to Valentin Simonov! You can watch his thread at Opening links in a Unity WebGL project)
and named it “PressHandler” (and put it maybe under your “script” folder)
using UnityEngine;
using UnityEngine.EventSystems;
using System;
using UnityEngine.Events;
public class PressHandler : MonoBehaviour, IPointerDownHandler
{
[Serializable]
public class ButtonPressEvent : UnityEvent { }
public ButtonPressEvent OnPress = new ButtonPressEvent();
public void OnPointerDown(PointerEventData eventData)
{
OnPress.Invoke();
}
}
- Create this last Java script, give it the name OpenWindow.jslib (not OpenwWindow.js, be careful) and put it under \Plugins\Webgl folder.
(Again, many thanks to Valentin Simonov! You can watch his thread at Opening links in a Unity WebGL project)
var OpenWindowPlugin = {
openWindow: function(link)
{
var url = Pointer_stringify(link);
document.onmouseup = function()
{
window.open(url);
document.onmouseup = null;
}
}
};
mergeInto(LibraryManager.library, OpenWindowPlugin);
-
Create a new empty GameObject, call it “Script” and attach to it “TakeScreenshot” script.
-
Select your (previously created) button in Inspector, and drag “PressHandler” script on it.
-
Under “Runtime Only” put the (previously created) GameObject “Script”, and from the functions on the right choose TakeScreenshot/Screenshot()
THAT’S ALL!
You must create a WebGL build to see it working.
When you will push your button the function “Screenshot”, from the script “TakeScreenshot”, attached to the GameObject “Script”, will be called, and a new tab (without pop-up blocking) should open with your screenshot.
UNFORTUNATELY
we are not still able to use it on mobile device: on mobiles, as on laptops (in which you use just the Touchpad), the “touch” seem to have a very different behavior from the “click” of the mouse . It seem to be a JavaScript issue and we are fighting on it, but with no luck for now
Enjoy.
Daniele