Search Unity

webplayer hijacks page it's embedded on

Discussion in 'Editor & General Support' started by made-on-jupiter, Apr 21, 2014.

  1. made-on-jupiter

    made-on-jupiter

    Joined:
    May 19, 2013
    Posts:
    25
    We are building an app that can cause the Unity plugin to go into long (or even infinite) loops, with many seconds inbetween Update() calls. As we save the state on the JavaScript side, we can actually kill reload the Unity webplayer to allow the user to modify settings and try again.

    The problem is that Unity seems to hijack or choke the web page when it goes into such a long loop, and we are unable to use any of our dirty tricks to kill the embed (we basically remove the embed from the DOM). No JavaScript seems to run any more once Unity goes in overdrive.

    It does work perfectly well when Unity Update() calls continue (even at near 100% CPU load).

    (tested on OSX Chrome Safari, and PC IE11)

    Worse is that (at least on Chrome Safari OSX), it entirely locks the browser tab. It can't even be closed. Unity doesn't bail by itself, nor does Chrome figure out that there's something wrong and attempt to kill it itself. Only way to reset is to kill the Unity plugin in the task manager. Not the Chrome task manager, but the system one. Here's what the Unity plugin process looks like on Chrome OSX (not sure there's a PC equivalent) :

    $Screen Shot 2014-04-21 at 5.55.45 pm.png

    Any idea why the webplayer has such a strong hold on the Javascript side when going into high CPU, and whether this is acceptable behaviour?

    ---

    FYI, this is one of the ways we do kill and reload the plugin:

    We send an
    Code (csharp):
    1.  Application.ExternalCall ( "unityPing", "" );
    from a Unity Update() call, every 2 seconds or so.

    Then on the JavaScript (OK, CoffeeScript) side we check for that ping every 5 seconds:

    Code (csharp):
    1.  
    2.  
    3. @unityPing = =>
    4.   console.log 'ping!'
    5.   if not @lastPingTime?
    6.     window.setInterval(@checkUnityPing, 5000)
    7.   @lastPingTime = new Date().getTime()
    8.  
    9.  
    10. @checkUnityPing = =>
    11.   now = new Date().getTime();
    12.   console.log 'check ping!', now - @lastPingTime
    13.   if now - @lastPingTime > 10000
    14.     console.log 'Unity3D frozen?'
    15.     window.unity.parentElement.removeChild(unity)
    16.    
    17.  
    The last line removes the Unity embed from the DOM, if we haven't received a ping from Unity in the last 10 seconds.

    You can actually let Unity remove itself using
    Code (csharp):
    1. Application.ExternalEval ( "window.unity.parentElement.removeChild(unity)" );
    We then reload Unity:

    Code (csharp):
    1. unityObject2 = createUnityObject2()
    2. unityObject2.observeProgress (progress) ->
    3.   if progress.pluginStatus == 'first'
    4.     window.unity = unityObject2.getUnity()
    5.     window.graphEditor.sendSceneReset
    6. unityObject2.initPlugin $("#unityPlayer"), window.unity_url
    7.  
    window.graphEditor.sendSceneReset is how we re-inject our state into the player.
     
    Last edited: Apr 21, 2014