Search Unity

OnGui in WebGL for mobile

Discussion in 'Immediate Mode GUI (IMGUI)' started by ScottYann, Feb 14, 2017.

  1. ScottYann

    ScottYann

    Joined:
    Jun 14, 2013
    Posts:
    12
    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:
    Code (csharp):
    1.  
    2. float xshift = 150;
    3. float yshift = -0.5f;
    4.  
    5. Event e = Event.current;
    6.  
    7.      
    8. Rect myButtonRect = new Rect (Screen.width-250-20+xshift, 0+yshift, 200+xshift, 28+yshift);
    9.      foreach (Touch touch in Input.touches) {
    10.         if (touch.phase == TouchPhase.Began) {
    11.             if(myButtonRect.Contains(touch.position)){
    12.                 // touch is in Rect
    13.                 goMenu();
    14.            }
    15.        }
    16.  }
    17.  
    18. if (GUI.Button (myButtonRect, btnTexture)) {
    19.             //do nothing here
    20. }
    21.  
    22.  
    23. if(myButtonRect.Contains(e.mousePosition) && ( Input.GetMouseButton(0))){
    24.       // mouse is in Rect
    25.        goMenu();
    26. }
    27.  
    and I tried messing with this both ways:

    Code (csharp):
    1.  
    2. Input.simulateMouseWithTouches = true;
    3.  
    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
     
  2. ScottYann

    ScottYann

    Joined:
    Jun 14, 2013
    Posts:
    12

    Attached Files:

  3. ScottYann

    ScottYann

    Joined:
    Jun 14, 2013
    Posts:
    12
    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.
     
  4. ScottYann

    ScottYann

    Joined:
    Jun 14, 2013
    Posts:
    12
    ah! Unity had the answer all along from this post:

    https://docs.unity3d.com/ScriptReference/Input-touches.html

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

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using System;
    6. public class OnGuiButton : MonoBehaviour {
    7.     public TextMesh someText;
    8.     void OnGUI(){
    9.  
    10.         Rect buttonRect = new Rect (Screen.width / 2 - 50 - 100, Screen.height / 2 - 20, 100, 50);
    11.  
    12.         touchButton (buttonRect, "flieble", doSomething);
    13.     }
    14.  
    15.  
    16.     void touchButton (Rect rect, string title, Action method){
    17.         if (GUI.Button (rect, title)) {
    18.             method ();
    19.         }
    20.         foreach (Touch touch in Input.touches) {
    21.             if (touch.phase != TouchPhase.Ended && touch.phase != TouchPhase.Canceled) {
    22.                 if (rect.Contains(touch.position)){
    23.                     method();
    24.                 }
    25.             }
    26.         }
    27.     }
    28.  
    29.     void doSomething(){
    30.         someText.text = "Mac Flieble!!!!";
    31.     }
    32. }
    33.  
    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 :D
     

    Attached Files:

  5. ScottYann

    ScottYann

    Joined:
    Jun 14, 2013
    Posts:
    12
    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:

    Code (csharp):
    1.  
    2.     void touchButton (Rect rect, Texture texture, Action method, GUIStyle style = null){
    3.         if (GUI.Button (rect, texture, style)) {
    4.             //method ();
    5.         }
    6.  
    7.         Vector2 TranslatedPosition = new Vector2(Input.mousePosition.x,Screen.height-Input.mousePosition.y);
    8.  
    9.  
    10.         if (rect.Contains(TranslatedPosition) && Input.GetMouseButton(0)){
    11.             method();
    12.         }
    13.         foreach (Touch touch in Input.touches) {
    14.             if (touch.phase != TouchPhase.Ended && touch.phase != TouchPhase.Canceled) {
    15.                 TranslatedPosition = new Vector2(touch.position.x,Screen.height-touch.position.y);
    16.                 if (rect.Contains(TranslatedPosition)){
    17.                     method();
    18.                 }
    19.             }
    20.         }
    21.     }
    22.  
     
  6. Jazon-Burnell

    Jazon-Burnell

    Joined:
    Oct 4, 2014
    Posts:
    14
    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.
     
  7. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,598
    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
     
    Last edited: Nov 17, 2017