Is there a way to detect if a mobile is using WebGL at run-time?
I’ve tried Application.isMobilePlatform, but it seems to return false, as I guess the run-time platform isn’t actually mobile, but WebGL instead. Maybe I need to use System.Info or something similar? However, I was wondering if Unity had something built in for this?
In the Unity installation folder, PlaybackEngines/WebGLSupport/BuildTools/UnityConfig/UnityConfig.js contains code to do that. You could do the same in a simple jslib and create the corresponding C# binding.
I’m pretty new to developing and can wrap my head around how to use C# for scripting for a webgl project I’m working but need it to detect whether it’s running on mobile and don’t understand what I need to do here. Could you point me in the right direction for how to create this jslib and C# binding? I’m also unable to find the UnityConfig.js on my system. Thanks for any help!
will print true/false depending on whether it’s running on a mobile browser.
So, the idea is that you make your own jslib (see manual) to get that information from JS to C#.
does that make sense?
I think the guy (rdurland) was stating that he is really new to dev and he uses C# + VS + Unity. Any other platform or language can be a problem for him (or - was) so writing about html is propably not that good idea.
There is simple explanation what to do, step by step:
Hey,
Could you explain more?
I’m new to WebGL Unity and I’m facing a problem with the Retina display on MacBooks
On windows it is all great and the FPS is 45-60 and the resolution is 1920 * 1xxx. On Macs the performance drops to 13-17 because of Retina and the resolution is 3300 * 2100 (double the laptop’s resolution).It is because the Macs DPI is 2.
Do you think your solution could solve this ? Like could I detect the Macs and change the DPI ? and where should I add this part of code ?
Thanks in advance
@MaskedMouse ’ s code example shows how rendering to low/standard DPI is done. In the main .html file, set “config.devicePixelRatio = 1;” to override the DPI rendering scale. This works in Unity 2020.1 and newer iirc.
Hi. I’m new to Unity WebGL and I’m still not very sure how to detect if a mobile is running in the WebGL Scene. The attached image is the error that I got after building and running it. I’ve also took reference from Detect mobile client in webgl - Questions & Answers - Unity Discussions, and the previous messages, but it still does not work.
Hi @Siba_M_M . We have an asset for your problem. The asset is modifying the DPI dynamically depending on current FPS. If FPS is too low, the asset will reduce DPI automatically. And it is effortless totally. You should just add the prefab to your scene, That’s all.
thank you for this but might i ask a question!? like how do we actually use it? i mean i have made a cross platform input system for a webgl game im making. inside unity it works fine ( when tested on device emulator it creates buttons on screen and when not you can move it the player with the keyboard and some other things ) but once i uploaded it to a testing server to try it , it didnt work, it detected it as webgl so i found this thread and used this code ( havent tested it yet ) but assuming in my case i want to use the code i have made already how would i do it??
this is the system check script
and ive added the code from above!
using System.Runtime.InteropServices;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SystemDetect : MonoBehaviour
{
public GameObject mobileControls;
public GameObject portraitWarning;
private bool playOnce = false;
public Text text;
[DllImport("__Internal")]
private static extern bool IsMobile();
void Start()
{
text.text = "";
}
public bool isMobile()
{
#if !UNITY_EDITOR && UNITY_WEBGL
return IsMobile();
#endif
return false;
}
// Start is called before the first frame update
// Update is called once per frame
void Update()
{
if (Application.platform == RuntimePlatform.WindowsEditor)
{
Debug.Log("webgl/windows");
Input.GetAxis("Horizontal");
}
else if (Application.platform == RuntimePlatform.Android)
{
if (Screen.orientation == ScreenOrientation.Portrait)
{
portraitWarning.SetActive(true);
}
else if (Screen.orientation == ScreenOrientation.Landscape)
{
portraitWarning.SetActive(false);
}
Debug.Log("Mobile");
mobileControls.SetActive(true);
}
}
public void Play()
{
if (Application.platform == RuntimePlatform.Android)
{
if (Screen.orientation == ScreenOrientation.Landscape)
{
SceneManager.LoadScene("Menu");
}
}else if (Application.platform == RuntimePlatform.WindowsEditor)
{
SceneManager.LoadScene("Menu");
}
}
public void ToggleFullScreen()
{
// Toggle fullscreen
Screen.fullScreen = !Screen.fullScreen;
}
}
and this my my controls. as you can see its nothing just a testing game to get things right
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
public float moveSpeed;
private float movement;
private bool moveRight;
private bool moveLeft;
private Rigidbody2D rb2d;
// Start is called before the first frame update
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
moveLeft = false;
moveRight = false;
}
// Update is called once per frame
void Update()
{
if (Application.platform == RuntimePlatform.WindowsEditor)
{
desktopMovement();
}
else if (Application.platform == RuntimePlatform.Android)
{
mobileMovement();
rb2d.velocity = new Vector2(movement, rb2d.velocity.y);
}
}
void desktopMovement()
{
movement = Input.GetAxis("Horizontal");
rb2d.velocity = new Vector2(movement * moveSpeed, rb2d.velocity.y);
}
void mobileMovement()
{
if (moveLeft)
{
movement = -moveSpeed;
}
else if (moveRight)
{
movement = moveSpeed;
}
else
{
movement = 0;
}
}
//settting up ui buttons movement
public void PointerDownLeft()
{
moveLeft = true;
}
public void PointerUpLeft()
{
moveLeft = false;
}
public void PointerDownRight()
{
moveRight = true;
}
public void PointerUpRight()
{
moveRight = false;
}
}
Create a file called like “Assets/Plugins/webgl.jslib” - this adds the Javascript to your project:
mergeInto(LibraryManager.library, {
IsMobileBrowser: function () {
return (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent));
}
});
Then create a file like “Assets/Scripts/WebGLHandler.cs” to expose the functions from the .jslib that you want access to from C#:
using UnityEngine;
using System.Runtime.InteropServices;
public class WebGLHandler : MonoBehaviour
{
[DllImport("__Internal")]
public static extern bool IsMobileBrowser();
}
Then make something like “Assets/Scripts/Platform.cs” to wrap conditional compilation:
public class Platform
{
public static bool IsMobileBrowser()
{
#if UNITY_EDITOR
return false; // value to return in Play Mode (in the editor)
#elif UNITY_WEBGL
return WebGLHandler.IsMobileBrowser(); // value based on the current browser
#else
return false; // value for builds other than WebGL
#endif
}
}
Then anywhere you want, you can do this:
if (Platform.IsMobileBrowser())
{
// whatever for mobile browser
} else {
// whatever for desktop browser
}
Edit: I don’t think you need the “WebGLHandler” to extend from MonoBehaviour, I just stripped the above example down from stuff I do. You could probably remove : MonoBehaviour and remove the using UnityEngine; from the top of that.
Edit: You could probably also combine WebGLHandler and Platform into the same class, just based the snippets on how I have things structured without much attention to simplifying.
thank you for your help , its a great start for me, but i cant get it work on Unity 2020. i changed all my code to this , but still it doesnt show the warning screen that forces the user to rotate the phone or the virtual buttons!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
public float moveSpeed;
private float movement;
private bool moveRight;
private bool moveLeft;
private Rigidbody2D rb2d;
// Start is called before the first frame update
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
moveLeft = false;
moveRight = false;
}
// Update is called once per frame
void Update()
{
if (PlatformOS.IsMobileBrowser())
{
mobileMovement();
rb2d.velocity = new Vector2(movement, rb2d.velocity.y);
}
else
{
desktopMovement();
}
}
void desktopMovement()
{
movement = Input.GetAxis("Horizontal");
rb2d.velocity = new Vector2(movement * moveSpeed, rb2d.velocity.y);
}
void mobileMovement()
{
if (moveLeft)
{
movement = -moveSpeed;
}
else if (moveRight)
{
movement = moveSpeed;
}
else
{
movement = 0;
}
}
//settting up ui buttons movement
public void PointerDownLeft()
{
moveLeft = true;
}
public void PointerUpLeft()
{
moveLeft = false;
}
public void PointerDownRight()
{
moveRight = true;
}
public void PointerUpRight()
{
moveRight = false;
}
}
and the gameManager Object that handles the controlls
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SystemDetect : MonoBehaviour
{
public GameObject mobileControls;
public GameObject portraitWarning;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (PlatformOS.IsMobileBrowser())
{
if (Screen.orientation == ScreenOrientation.Portrait)
{
portraitWarning.SetActive(true);
}
else if (Screen.orientation == ScreenOrientation.Landscape)
{
portraitWarning.SetActive(false);
}
Debug.Log("Mobile");
mobileControls.SetActive(true);
}
else
{
Debug.Log("webgl/windows");
}
}
public void Play()
{
if (PlatformOS.IsMobileBrowser())
{
if (Screen.orientation == ScreenOrientation.Landscape)
{
SceneManager.LoadScene("Menu");
}
}
else
{
SceneManager.LoadScene("Menu");
}
}
public void ToggleFullScreen()
{
// Toggle fullscreen
Screen.fullScreen = !Screen.fullScreen;
}
}