Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Knowing when a web game loses focus

Discussion in 'Scripting' started by manuelflara, Nov 14, 2007.

  1. manuelflara

    manuelflara

    Joined:
    Jan 21, 2007
    Posts:
    87
    I'd like to know when the window where my Unity web game is located loses the focus of the input so I can instantly pause it. Yes, I know Unity does that. What I also want to do is draw an overlay screen on top of everything until the user not just focuses on the window again, but clicks on the window. You know, a semitransparent black layer with a PAUSED, click inside to continue kind of feature.
     
  2. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
    An untested idea is to use OnApplicationPause to instantiate/enable your overlay, and then force a render with Camera.main.Render(). I don't know if this would work, but I thought I'd share it.

    Cheers,
    -Jon
     
  3. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    You might try the following:

    - Have your Unity content *not* automatically pause when in the background.

    - Have in-browser JavaScript code that looks for the window losing/regaining focus; when "focus transitions" happen you send a message to the Unity content

    - Your Unity content can then respond to lost/regained focus events as you wish (overlay and time-step controls?)
     
  4. Brian-Kehrer

    Brian-Kehrer

    Joined:
    Nov 7, 2006
    Posts:
    411
    How do we make a web player not automatically pause?

    It seems Application.RunInBackground isn't doing it...
     
  5. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    "Run in Background" will work with web players in Unity 2.0.2.
     
  6. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Can someone show me how this is done? I tried using window.onblur, but that doesn't seem to get called when switching to a new tab, and opening a new window in Safari, using that command, sent me into an infinite loop of blurring.
     
  7. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    I've got a busy morning today (Friday) and once I'm done with that I'll see about knocking out a quick example of this in action. Stay tuned.

    Edit: I posted info here but thought I'd use a new post instead to more actively attract folks back to the new info...
     
  8. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    I'm back with an example, but unfortunately it doesn't yet cover all cases. My example works great for all browsers when window focus changes are made (hiding/revealing, selecting the desktop/finder then back in the browser window, etc.). My example struggles a bit with detecting tab changes in all browsers, notably it seems to fail completely in Safari and only gaining focus (window.onfocus) works in Firefox (note that tab changes are successfully detected in Firefox on Windows).

    Here's the set-up:

    • I have a simple scene, just a camera (named "Camera") with one script attached to it. That script draws a simple "log" window and it defines two functions in particular: BrowserBlur and BrowserFocus. When either of those functions are called the log display is updated indicating which one was called and a time-stamp (just Time.time). Here are the functions as defined in the script (note that they receive, but ignore a string argument):

      Code (csharp):
      1. function BrowserBlur (aString : String) {
      2.    
      3.     LogText = "browser blur [" + Time.time.ToString() + "]\n" + LogText;
      4.    
      5. }
      6.  
      7. function BrowserFocus (aString : String) {
      8.    
      9.     LogText = "browser focus [" + Time.time.ToString() + "]\n" + LogText;
      10.    
      11. }
      I modified the default HTML template in a few minor ways. In the script block in the head I added code to define two functions, MyBrowserBlur and MyBrowserFocus, then some simple code that declares those as callbacks for the window.onblur and window.onfocus events. Here is the code I added to the end of the <script> block in the default HTML created:

      Code (csharp):
      1. function MyOnBlur() {
      2.  
      3.         GetUnity().SendMessage("Camera", "BrowserBlur", "...");
      4.  
      5. }
      6.    
      7. function MyOnFocus() {
      8.            
      9.         GetUnity().SendMessage("Camera", "BrowserFocus", "...");
      10.            
      11. }
      12.    
      13. window.onblur = MyOnBlur;
      14. window.onfocus = MyOnFocus;

    With that in place it works as I described, catching all window and tab focus changes except within Safari where tab switching isn't caught and in Firefox (OS X) where only selecting the tab triggers an event. I suspect that's happening because that particular browser isn't generating the window.onblur and window.onfocus events for tab changes. I'm not sure if there are ways around that, perhaps another event?

    View the Demo
    Download the Project


    Here are the browsers I tested:

    OS X 10.4.11/Firefox 3.0.1
    OS X 10.4.11/Safari 3.1.2
    Windows XP (Parallels)/2.0.0.16
    Windows XP (Parallels)/IE6.0
     
  9. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Beautiful, Tom. Thanks!

    The behavior for mine differs from yours slightly though, between browsers. Safari does it right, which means it loses keyboard focus immediately upon switching tabs, and regains it when tabbing back, but Firefox doesn't disable them at all, until the entire application loses focus. Camino can't make up its mind if it wants to work perfectly, or more like Firefox. Either way, it's a significant improvement. If I've got Safari on OS X, and all Windows browsers covered, that's a great start.

    (Windows handled the keyboard focus problem just fine for me without needing your script.)

    http://forum.unity3d.com/viewtopic.php?p=88257#88257

    Here's what's attached to my jukebox in Unity:

    Code (csharp):
    1. function BrowserBlur (nothing : String) {  
    2.    shortcuts = false;    
    3. }
    4.  
    5. function BrowserFocus (nothing : String) {    
    6.    shortcuts = true;    
    7. }
    I then just do it like this:

    Code (csharp):
    1. function Update() {
    2.      if (shortcuts) {//shortcuts};
    3. }
     
  10. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    Being as your behavior (with respect to the browser providing onblur/onfocus events) is different than mine, can you share how you're setting things up in your browser-based JavaScript?
     
  11. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    http://teamuv.net/jessy/music/

    If you view the page source, you should find that I have copied your code exactly, save for the ellipsis changing to "nothing", and accounting for the different name of my Game Object.
     
  12. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    Ok, that's odd that you and I get different behavior then. When using the demo I posted what behavior do you experience (the same as I get or again something different)? What OS/browser combos are you testing?


    Edit: and I'm asking as if you take focus away from your window you would of course not have keyboard entries working as they wouldn't go to the browser window nor the tab showing your content (so regardless of whether or not your callbacks set your property to true/false it "won't work" when your window doesn't have focus). As such I'm keen on understanding whether or not you see the same blur/focus messaging as I do.
     
  13. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    My results for your example (perfect implies that tabs, new windows, and clicking elsewhere create onblur's, and clicking back creates onfocus's):

    Win XP / Safari, Firefox, and IE - perfect, except that you need to click outside of your actual unity content. If the game has focus instead of the containing window, no messages are logged.

    OS X / Safari: tabs (opening or closing) do not cause messages to be logged.
    OS X / Firefox: closing tabs/windows logs messages, opening them does not
    OS X / Camino: works perfectly, except each message is logged twice!

    Yeah, you'd think, huh?! However, that's not how my jukebox worked, on OS X. On Windows, it would not receive keyboard input if not focused, but on OS X, it would. I tried to build a small example project to confirm this discrepancy between OS's, but it behaved the way you said it should. Very weird!
     
  14. AbgaryanFX

    AbgaryanFX

    Joined:
    Jan 9, 2010
    Posts:
    167