For web player use, it looks like Unity allows me two solutions to open a link in a new browser window:
Open the link in the same window, killing the game itself.
Use a Javascript function contained elsewhere in the page to open a new window.
Normally, I think I would use method 2, despite finding it to be pretty boring because I have no desire to code web pages. However, what happens when you don’t have control over the rest of the window? It seems that this is the way it’s going to be for Top DOG, so that’s why I’m asking now, but this could be important in general.
What makes you think that you won’t have control over the containing page in Top DOG? A big part of the evaluation is how one interacts with the containing page. I don’t see how you could do that if you weren’t in complete control of the page.
I guess the problem lies within the definition of “game”. I will ask OTEE.
There is plenty of stuff you can do with Unity and web integration without opening pages outside of the game window. I just don’t want to do any of that right now.
To make a public clarification, when we ask you to submit your game, we mean both the .unityweb file and the .html file, along with any other files you are using. Web player integration is a judging criteria, so those who use the .html files in interesting ways will score higher in this category. This means that you are 100% allowed to modify the containing html page. If you want to use a php or perl script instead of html, that’s ok too. But you need to include some kind of containing web page.
Now, if for some reason your game is interfacing with a SQL database, it will be hard for that to be shared when you submit. In this case, you should contact contest@unity3d.com and we’ll figure out the best way for you to submit.
And you can be sure that we’re sensitive to those entries that do interact with the containing page, we won’t blindly break your content or anything like that. So as Sam indicated, submit your files to us and outline any interactions between the unityweb file and the html file (or any server-side scripts, etc.) so we can be sure to handle your content properly.
I tested it briefly in Firefox running locally on OS X, but it should work the same across all browsers. Make sure you don’t have a pop-up blocker enabled of something like that which might be preventing the new window from appearing.
As to your second question you’ll need to look at Application.platform and RuntimePlaform combined. Something like this:
The problem was with my pop-up blocker. I can’t expect people to take that off to play, so is there no realistic way for me to link to a url from within Unity?
Another couple of things that were really annoying is that my preference is to have links open in new tabs, and this code caused a new window to appear, and the cursor was invisible (using custom cursor in the game) even after giving focus to the new window. Blah.
Well, that’s not something unique to Unity, that’s just an honest welcome to web development where spawning a new browser window (or tab) isn’t always possible.
Hmm, in Firefox I too have my prefs set to open links in new tabs and it did just that (Firefox 2.0.0.6 on OS X).
If you wanted to look for more “robust” solutions then you might call an in-page JavaScript function which attempts to open a window, it also then sets a timeout to fire in half a second to see if the window actually opened or not. Doing that you’ll be able to know whether the new window/tab appeared or not and then message that pass/fail status back into the Unity content (mostly in the case of failure that way you can tell the user to unblock pop-ups).
Sounds very boring. Guess I get a zero in this category!
I am not trying to pass myself off as a web programmer. It’s just not something I have time for right now. I hope this sort of thing becomes more accessible for we who just care to make art, in the future.
If you use the Unity HTML template there is already a GetUnity() function, assuming that’s in place just add the following OpenWindow() function:
function OpenWindow (aURL, aGOName) {
var tWin = window.open(aURL);
if (!tWin) {
GetUnity().SendMessage(aGOName, "PopupBlockerError", <params if you want to use 'em>);
}
}
Then in Unity use ExternalCall instead of ExternalEval (the difference being that call is for calling a function and passing parameters, eval is for evaluating a line of JS code), then define a PopupBlockerError function to respond if the window fails to open:
function PopupBlockerError (<params if you use 'em>) {
// respond to the window not opening here
}
So, when you try to open the window you use ExternalCall to trigger the OpenWindow function, passing it the URL to be opened and the name of the Game Object you’re calling from (or at least the name of the GO with some script attached that defines the PopupBlockerError function). If the new window opens then great, if not the PopupBlockerError function (in a script attached to the named Game Object) will get called and you can respond to that if you’d like. But in doing that be aware that the user may have already seen a popup blocker error/alert from their browser and/or installed toolbars. At least at that point you’ll know whether it opened or not, what you do from there is up to you… Voila.
Thanks for this info Tom… quick question, how does one check to see if a window opened or not? I’m not much on web programming beyond the database layer.
Also, I’m using ExternalEval and it’s great when users don’t have a pop-up blocker, but most browsers now have one on by default (Safari included).
I notice when accessing content that uses ExternalEval and window.open, with a default Safari install, Safari doesn’t say anything to the user… no warning or anything.
Is there a way around this? Obviously it’s not in anyone’s interest to have Unity content that has buttons that appear to do nothing (even though it’s really a browser issue).
The window.open() call will return either a reference to the window if opened or null if not (like when it’s blocked by a pop-up blocker). Therefore as per my example above your browser JS code will attempt to open the window and check the result returned by window.open(). If the result is null then the window didn’t open and a message is sent to a Game Object within Unity notifying you of that error.
Well, the way around that issue is to check whether the window.open() call succeeded or not (see my answer above), then notify the user if not so your button doesn’t really “fail silently”.
I would argue that using pre-processor directives would be slightly better practice. It may not make a significant difference in this example, but putting platform dependent code (and subsequently those if statements) in an Update function would.