OnGui in WebGL for mobile

Hey Unity Technologies! So nice that you’ve still somewhat maintained the legacy OnGui stuff in the latest version of Unity. We were surprised to see how well it still works. I love the newer one better of course but we’ve inherited a legacy project that they want to work on the web without the old plugin. It actually worked perfectly right out of the box after references to the reflection API were worked around. It works really well now inside of WebGL for desktop browsers.

After doing some simple optimizations to textures, I’ve been able to get WebGL to work ok on mobile even with only 64 megs allocated to it. The problem we are having now is that for some reason touch events are not registering at all with OnGui stuff. The interesting thing though is that if I slap a Unity UI button in there, that works fine. When making a button with OnGui there is no way to tell it to use touch one way or another it just works or it doesn’t. I tried some workarounds with no luck like this:

float xshift = 150;
float yshift = -0.5f;

Event e = Event.current;

     
Rect myButtonRect = new Rect (Screen.width-250-20+xshift, 0+yshift, 200+xshift, 28+yshift);
     foreach (Touch touch in Input.touches) {
        if (touch.phase == TouchPhase.Began) {
            if(myButtonRect.Contains(touch.position)){
                // touch is in Rect
                goMenu();
           }
       }
 }

if (GUI.Button (myButtonRect, btnTexture)) {
            //do nothing here
}

  
if(myButtonRect.Contains(e.mousePosition) && ( Input.GetMouseButton(0))){
      // mouse is in Rect
       goMenu();
}

and I tried messing with this both ways:

Input.simulateMouseWithTouches = true;

with no difference either way

Could you offer some advice on how to resolve the issue? It would appear that Unity Technologies is trying to support OnGui on WebGL after all it does work great on desktop browsers…

If we can get this one issue fixed it will allow us to proceed on more than a dozen projects. Otherwise, we may be forced to recreate everything.

Thanks in Advance,
Scott

Here is a super simple example. Try it first on a desktop then try it on mobile:

http://www.ohiovr.com/glproblem/

I’ve attached the project file for this

2960119–219717–example.zip (1.5 MB)

I’ve found that Input.mosuePosition fails to work in any case, GUI or not. I’m going to try the beta and see how it goes.

ah! Unity had the answer all along from this post:

there is a touch.position property which we can say if rect.contains(touch.position) like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class OnGuiButton : MonoBehaviour {
    public TextMesh someText;
    void OnGUI(){

        Rect buttonRect = new Rect (Screen.width / 2 - 50 - 100, Screen.height / 2 - 20, 100, 50);

        touchButton (buttonRect, "flieble", doSomething);
    }


    void touchButton (Rect rect, string title, Action method){
        if (GUI.Button (rect, title)) {
            method ();
        }
        foreach (Touch touch in Input.touches) {
            if (touch.phase != TouchPhase.Ended && touch.phase != TouchPhase.Canceled) {
                if (rect.Contains(touch.position)){
                    method();
                }
            }
        }
    }

    void doSomething(){
        someText.text = "Mac Flieble!!!!";
    }
}

I’ve updated my original webgl export so you can see for yourself. I’ll keep it up there for a while till I forget what it’s for and delete it :smile:

2961208–219829–example 2.zip (1.51 MB)

Ah found to my dismay that the example failed to work when I had a button at the top of the screen. I discovered that the Gui screen coords y value is inverted so you have to do something like this instead of my example above:

    void touchButton (Rect rect, Texture texture, Action method, GUIStyle style = null){
        if (GUI.Button (rect, texture, style)) {
            //method ();
        }

        Vector2 TranslatedPosition = new Vector2(Input.mousePosition.x,Screen.height-Input.mousePosition.y);


        if (rect.Contains(TranslatedPosition) && Input.GetMouseButton(0)){
            method();
        }
        foreach (Touch touch in Input.touches) {
            if (touch.phase != TouchPhase.Ended && touch.phase != TouchPhase.Canceled) {
                TranslatedPosition = new Vector2(touch.position.x,Screen.height-touch.position.y);
                if (rect.Contains(TranslatedPosition)){
                    method();
                }
            }
        }
    }

Just wanted to bump this and say supporting touch in WebGL in the legacy GUI would be very helpful for us too, targeting Surface tablets in our case. We have similar workarounds in place (things get a little more complicated when using the layout system, but a combination of GUILayoutUtility.GetLastRect() and GUIUtility.ScreenToGUIPoint() seem to more or less work) but built in support would definitely be helpful.

Also, one of the old projects we’re updating was built on the iGUI asset store package, which also appears to have been built on the legacy GUI and would need a Unity side fix to readily support touch in WebGL.

Me too, I have a very large project using legacyGUI that would be hellish to hack and hellish to convert to the new GUI

Weirdly OnGUI works perfectly well for iOS and Android builds so it’s all in there already just not exposed for WebGL for some reason