Updated 26 Nov 16: Since originally posting this blog, Chrome has made more changes that now prevent my Dropbox/iFrame (last section of this blog) solution from working. All browsers are working together on the future of the WebGL format, and Unity continue to make their own changes, too. The landscape is constantly shifting and while everything in here was useful info at time of writing, that may change over time. At time of update, the rest of this blog should still help you out with many problem areas that you may be having, though.
Updated 1 Dec 16: Further viewing. There was a more up to date talk at Unite (Los Angeles) 2016 that’s a slight bit higher-level than this, but is also useful.
Fair warning, this post is targeted solely at Unity game developers. Normally I write posts targeted at gamers. Not this time. Today this is a public service for game devs 😛
If you’re reading this then hopefully you’re new to Unity. I say ‘hopefully’ because if you’re not then, as is the case with me, the chances are high that you’ve been trying and failing on and off for almost a year now to get Unity’s Web “this is the future, no really” GL builds to work for you. For me, at least, the problem was probably compounded by the fact that I am the ‘layman’. I know nothing about html, C++, how Unity works under the hood, what a NPAPI is or what Google’s problem with it is. Any material I did find explaining WebGL always seemed to be aimed at those with a slightly higher level of knowledge in these areas than I possess.
At the time of writing I was using Unity 5.3.1f1
EDIT: Do read into the comments. There has been some interesting news from Unity themselves and others. I’ll edit the article to include some of it.
In September 2015, Google Chrome stopped supporting NPAPI. All I knew is that now all my Unity Web Player builds of games on my site wouldn’t run in Chrome, and that 66% of my visitors were using it. I put in messages for people to please use Firefox or download the PC build, but people are lazy. Giving them an extra step or two to play my crappy game jam entries and prototypes is more than many of them were willing to do. And that’s my problem, not theirs. It’s my responsibility to fix it. And fix it I… couldn’t!
I suffered all kinds of problems from builds simply failing (usually), to builds successfully loading an empty scene but failing on the 2nd one, to gamepad inputs being horribly messed up (mine still are, so if you’re expected a fix for that in this post, sorry) and builds running (for seconds) in one browser but not at all in another. Even when I got good builds more recently, I couldn’t get them onto my site for another while. There were also confusing messages about exceptions happening but exception handling not being enabled. I couldn’t see where to enable this (it’s not directly on the build screen) and didn’t really understand what it meant, or what the exception might have been.
I even met some Unity ‘evangelists’ (as they call them) from the company when they came to Ireland last year (sound folk!) and asked a few direct questions about my WebGL problems but got no immediately usable answers.
This was all extra frustrating because by now I was seeing plenty of other devs get working WebGL builds out into the world, and I was wondering what was so different about my projects that caused them to fail so completely!
Because there’s so little support out there so far and because I’ve made huge leaps in the last two weeks, I thought I’d write this up and share it. Big thanks to Chris Gregan from Fungus (a great Unity plugin. Check it out. It’s free!) for his help. He doesn’t know it, but playing (the fantastic) Snozbot’s Text Adventure, seeing another great game running in WebGL inspired me to finally brute force a solution to it for myself. Chris was also a big direct help several times during the last two weeks and made the first breakthrough suggestion.
EDIT: For the sake of completeness, I should also mention that when you download and install Unity you will want to ensure that “WebGL Build Support” is selected. If you installed Unity without this, just run the download assistant again and select only WebGL. You don’t have to completely reinstall Unity to get the support back.
Enough Background! Solve it, dimwit!
Okay. It turns out that my single biggest problem came from the fact that every game I tried to build in WebGL was one that I’d started under Unity 4, not 5. Naturally, this was because all my games on this site have stopped working in Chrome, and I wanted to fix it. Many of you are probably in the same boat. I’d upgraded all the projects to Unity 5 and made successful Web Player and PC builds, but never a working WebGL build. Even the simplest single-scene game jams here failed.
If you’ve no Unity 4 projects then you’re probably not experiencing this problem so skip this and the next section.
I was in the middle of taking Teluma and rebuilding the level generation line by line, taking 5 minutes every time I changed a line to test a new build (infuriatingly, the exact same code would fail sometimes and pass others) when Chris suggested the following.
Export a Unity 4 project as an asset pack into a clean Unity 5 project
This may sound painful, and let me assure you, it is, but it’s also the only solution I’ve seen to date since waiting and waiting for Unity updates to fix the problem hasn’t worked. Something deep in a project’s files is incompatible. Deleting the Library or meta files won’t help you (well, it didn’t help me anyway). If this is a project that you really want working in WebGL, then rip off the bandaid. If it’s not, maybe consider if the project is worth your time. At the time of writing this, Teluma is the only project on this site that’s been updated for WebGL.
Take literally everything in your project folder and select it (scenes, prefabs, materials, sounds, scripts) then right click and Export Package…
Select all dependencies. Select everything. Package it up into one little Unity package, open a new Unity 5 project, and import the package again.
Everything will be broken. To my knowledge, there’s no way to bring in the project settings like Input Controls, Physics collision matrices, Tags, Layers, Sorting Layers, and possibly lighting settings (I’m not sure because Teluma uses only unlit sprites and that’s the project I did this with). The more complicated your project is, the longer this will all take to fix and test. Them’s the breaks.
EDIT: Chris has suggested a way to do the export with your project settings intact. Check out the docs here. I haven’t tested this at time of writing.
FURTHER EDIT: Tested now. While this works to export your project settings, it seems to be those very settings (something within them) that causes Unity 4 projects to break in WebGL. The painful way is still the only way I know of to go.
I’ve packaged up a handy script based on that link to export your settings anyway if you want to. It adds a command to the Editor’s Menu Bar (Tools > Export Project Settings).
For me, it took a few hours to connect everything up again and test. Top Tip: If you put your Layers back into the exact same spelling and order as they were in before, then most of your prefabs and scene objects should fix themselves. I think this didn’t work for nested prefabs though. I can almost guarantee you’ll be fixing bugs for a while.
Once you’re sure everything is working as it should be (the confidence won’t return for a while) then you can make a build.
After the last step, I tried builds and I wasn’t really getting the exceptions error too often any more. However, it’s worth knowing where to turn these on and off if you don’t already.
I don’t know much about these save for the fact that you don’t really want them on. If your game is running well, you don’t get exceptions. If it’s got some bugs in it you’d be better off finding and fixing them than just allowing the exceptions.
I believe enabling them also makes your builds larger, and thus loading times are longer.
I’m a n00b in this field, though, so only listen to what I’m saying there if you know next-to-nothing on the subject yourself.
You can also set things like the company and game name from here, as well as put in a logo.
DataCaching is probably worth turning on for performance’s sake on subsequent visits by players, but you are telling their browsers to download game data, probably filling up their temp folders… as I understand it… which I’ve already admitted that I don’t.
Unity Docs has this to say on the subject: “The Data caching checkbox in Publishing Settings lets you enable automatic local caching of your player data. If this is enabled, your assets will be stored to a local cached in the browsers IndexedDB database, so that they won’t have to be re-downloaded in subsequent runs of your content. Note that different browsers have different rules on allowing IndexedDB storage, and may ask the user for permission to store the data if this is enabled, and your build exceeds some size limit defined by the browser.”
EDIT: Apparently this issue has been fixed in 5.4 so we have that to look forward to!
This still is totally broken for me and I’ve nothing to offer you here. I’m asking for your help if you have gotten a controller working correctly in WebGL.
For me the left stick works fine, but the game thinks that the Right Trigger is the Start button, and several other buttons are similarly remapped with no rhyme or reason behind it.
This was one of the things I asked the Unity evangelists about last Summer and they basically said that they’re aware of it and it’s on the list. I’m surprised that it’s still as broken several months later. For me, anyway.
According to Chris Gregan, audio is one of the bigger problems they’ve faced with WebGL. It uses WebAudio, while the other builds use FMOD. So there’s literally different rules and operations going on.
I experienced no problems but Chris said they had problems playing shorter sound clips in close succession. My gunshots in Teluma seem to be going okay, so your mileage may vary.
Third Party Assets
Given how much stuff there could be in your project that comes from the Asset Store and isn’t an officially supported Unity asset, the best thing I can say here is ‘be careful’. If you’re using assets or custom shaders that were written under Unity 4 and haven’t been updated, then they may be a source of trouble for you. Try building without them if you’re unsure, check out the forums, or email the developers.
In the case of Aron Granberg’s quite popular A* Pathfinding Project, I’m using it in Teluma and initially suspected it of causing trouble. Aron is still supporting it and he suggested one or two fixes on his forum. I had no trouble with it after doing the package export I mentioned above, though.
I like to use this so that the game keeps playing if I switch away from the screen. This keeps it going in the editor or in a build, except it doesn’t seem to work in WebGL and I haven’t gotten around it yet.
In other build types I can set the cursor lock mode but it doesn’t seem to work the same with WebGL. I attempted the solutions set out by Unity Docs but was unsuccessful. Now, that’s the official docs so I’m sure it’s correct and that my first attempt just got something wrong. Copying the First Person character controller script may be a good way to go. It corresponds to what the docs say about the events happening on button UP events.
Finally, deploying to Web
After all of that, my builds would run locally but I still couldn’t run them on the RetroNeo Games website. I opened this Unity Answers thread that was watched by 42 people but answered by nobody. The lack of response is what encouraged me to write this. Clearly it’s an issue people are having and there’s very little support for it.
If you know what an iframe is and this is painful to listen to, skip ahead. If not, then like me you may have attempted what worked with the old Web Player builds. That is to put the game in a public Dropbox folder (or similar) then edit the output html file of the game to reference the web link of the game’s .unity3d file, then copy all that new html into a code block on the site.
While this was how I handled the old Web Player builds, this totally failed for me with WebGL. There are several links which need referencing in the html file. Unity’s docs (bottom of the page) mention linking only 4 files. There are more like 8 in the index.html file. I tried linking 4 and I tried linking all, but both ways failed.
That’s when I learned about iframes (this guide is “for dimwits” remember).
So much simpler! I uploaded the build file to my Dropbox/Public folder, right clicked on the index.html file and got the public link.
On my web page I added a code block of html and said:
<iframe src=”myPublicLink.html” width = 860 height = 700></iframe>
Obviously, replace ‘myPublicLink.html’ with your own, and set the resolution to whatever you want it to be.
That’s it! Results can be seen here.
After that, the game finally ran. Two weeks of brute forcing the problem had (mostly) paid off.
Controller support and cursor locking are still hurdles to overcome, but they feel much more manageable now.
Unity’s WebGL builds are no longer in preview mode. They’re now considered the way you’re meant to do business. There’s been a shocking lack of guides like this one (only, you know, smarter and more coherent) from Unity themselves or from the normally extremely active YouTube community who are forever making tutorials on this, that or the other for Unity.
Hopefully this will be of some help to people. And it will only get easier as Unity iron out the remaining kinks. I’m sure they’ll do a tutorial or live session on building and hosting WebGL at some stage, but for now, this is actually the most comprehensive guide I can find to Unity WebGL anywhere online. I figured out surprisingly little for myself but instead gathered (or discarded) information from dozens of sources, (and of course, from Chris Gregan) and I can only claim credit for writing down the most useful of that information in one place.
Good luck fellow game devs. Game on!