Our Journey to Unity 5 and WebGL

Check out our Unity-based social networking platform to see what you can do with Egowall. Then sign up for a free account and start using it to be The Real You™.


Unity Logo

The process of upgrading a large, complex application like Egowall to Unity 5 and WebGL™ is neither as easy nor straightforward as you might think - or hope. Beyond the fact that WebGL is significantly slower than native code, there are many other things to deal with.

We are sharing a series of posts with behind-the-scenes information about our journey on this road. In the articles, we talk about the issues we have encountered during the conversion and how we dealt (and are dealing) with them.

WebGl Logo

Below are links to all of those posts in a single place. We wanted to make it easy for newcomers to the series to read any or all of them. As additional articles in the series are written, this post will be updated.

We hope you get value from the information contained in the posts. Please share any thoughts you may have in the comments and let us what your path to Unity 5 and WebGL has been like.


Egowall and WebGL (Part 1): How We Got Here

In the first post in our series, we talk about Google’s early 2015 removal of support for the Unity plugin in Chrome and the resulting impact on our development process.

Egowall and WebGL (Part 2) - Art and Asset Issues

The second post covers the art and asset-related issues we encountered during the upgrade and how we dealt with them.

Egowall and WebGL (Part 3): Code-Related Issues

In this third post, we summarize the code base changes we had to make in order to resolve Web Player-related issues encountered during our Unity 5 upgrade.

Egowall and WebGL (Part 4): Web Player Performance Comparison

The fourth post summarizes the results of our performance testing at the end of the Unity Web Player 5.3 upgrade, comparing it to Web Player 4.3.

EGOWall and WebGL (Part 5): WebGL Issues

Coming soon.


WebGL and the WebGL logo are trademarks of the Khronos Group Inc.

Egowall and WebGL (Part 4): Web Player Performance Comparison

UPDATE: This post was modified on March 30, 2016 to correct some of the measurements in the table at the bottom. Numbers which were adjusted are marked with an asterisk (*).


In the first part of our Egowall and WebGL series, we discussed Google’s early 2015 removal of support for the Unity plugin in Chrome, making it necessary to move Egowall to Unity 5. Then in part two we detailed the art and asset-related issues we encountered as we began the upgrade.

Most recently, in part three we talked about the asset-based and code-based issues we encountered and the solutions/workarounds we implemented to address them.

Our next step in the migration to Unity 5 was to ensure that there was no performance degradation between the Unity 4.3 and Unity 5.3 web players. We needed to identify any Web Player-specific performance issues so that when we migrate to WebGL, we will be able to isolate any other performance problems encountered as being specific to WebGL.

In this blog post we want to give you the summary of our performance testing at the end of the Web Player 5.3 upgrade.

Performance Baseline and Metrics

We have an established group of performance metrics that we assess against sets of baseline measurements on each Unity upgrade and Egowall release. The baseline used in this instance was a test case with the following scenarios:

Environment:  Living Space (Castle)

Graphic Settings:  High, and from the player’s starting position after loading into the living space.

An Example of the Living Space Used in the Referenced Test Case

An Example of the Living Space Used in the Referenced Test Case

 Variation A:  Empty Living Space (Castle)

  • No user interaction objects

Variation B:  Loaded Living Space (Castle)

  • Unique mix of 112 user interaction objects such as furniture, photos and mini-games
  • All objects are positioned where they are at least partially visible from the player’s view at the starting position
  • All visible living space surfaces have a custom material applied to them

Variations A and B were executed identically using both the Unity 4.3 Web Player and the Unity 5.3 Web Player. We observed the following (details can be found in the table below):

  1. A drop in frame rate was observed on variation B when moving large stacks of objects all at once, which makes the physics exponentially more complex.
  2. Rendering performance slightly decreased in regards to the draw calls and tri count batching.
  3. Material memory went up significantly. (NO LONGER ACCURATE AS OF MARCH 30, 2016).

Web Player 4.3
Empty Space

Web Player 5.3
Empty Space

Web Player 4.3
Loaded Space

Web Player 5.3
Loaded Space

FPS Range

66-70

64-69

66-69

66-70

Tri Count

9.8K

16.5K

153.3K

155.0K

Batched Tris

208

448

166

7700

Draw Calls

76

107

532

472

Batched Draw Calls

21

35

19

114

Texture Count

1427

1439

1589

1586

Texture Memory

33.5MB

34.9MB

131.4MB

130.2MB

Material Count

213

598

556

638 (*)

Material Memory

113.8KB

0.6MB

293.8KB

0.7MB (*)

VRAM Usage

18.9MB - 29.5MB

21.5MB - 33.0MB

18.9MB - 79.3MB

23.7MB - 84.5MB

Game Objects

518

508

2657

2647

Total Objects

5383

5963

13763

13948

Stay tuned to find out more about what we have learned on the way to Unity 5 and WebGL.

WebGL and the WebGL logo are trademarks of the Khronos Group Inc.

Egowall and WebGL (Part 3): Code-Related Issues

In the first part of our Egowall and WebGL series,  we talked about Google’s early 2015 removal of support for the Unity plugin in Chrome, making it necessary to move Egowall to Unity 5. Then in part two we discussed our first steps toward the upgrade – detailing the art and asset-related issues we encountered.

In this blog post we will summarize the code base changes we had to make in order to resolve issues encountered during our Unity 5 upgrade. Please note we just are talking about the Web Player conversion; WebGL-related issues encountered will be discussed in a future post.

General Observations

Unity 5 comes with an Automatic Obsolete API Updater, which has been proven to be extremely convenient for us. This process traversed all of our code files and changed most of the code deprecated by Unity to the new standards.

For us, the majority of these changes were accessors that were removed (e.g., “this.collder” was replaced by “this.GetComponent<Collider>()”). Given the size of our code base, it would have taken an immense length of time to change all the obsolete API references. But with the auto-updater, this was done in a matter of minutes after opening up the project for the first time in Unity 5.

The Unity Release Notes were very helpful in providing advance notice about the drastic changes occurring internally in Unity. However, there were still a few things we had to discover for ourselves after the upgrade was done.


Code-Related Issues

Below is the list of all the technical code-related issues we encountered during our Unity 5 upgrade. Most of them have been resolved by code changes or by Unity 5.x updates. There are a few that we are still working to fix.

Unity 5.1

1. BoxColliders do not size to the Livingspace meshes

In Unity 4.3, when adding a BoxCollider to an object at runtime, the box would automatically resize itself to fit around the object’s mesh if there was one.

One of the first things we saw when running the upgraded project was that the collision on our environment assets seemed to be missing. As it turns out, the collision was there but not sized correctly.

Every collider was just a 1 x 1 box, so we had to resize it in code ourselves once the object had been loaded in. We simply accessed the mesh on each particular object and then sized the BoxCollider using the bounds of each mesh.

2. Collision detection became more sensitive

Another area of Unity that was drastically changed was the Physics. We noticed this in regard to some of our collision detection while moving various objects around the living spaces.

In Unity 4.3, objects would be able to touch other objects (or get so close they seemed to touch) without triggering a collision. This behavior has been adjusted in Unity 5, which required us to add a small buffer when moving objects around to prevent the collision from being detected.

This way, you can still stack objects without Unity thinking they are inside each other.

3. Bounds.Encapsulate() was not returning the right value

After upgrading, we noticed that the spacing of the dynamic buttons in our Interactive Object Menu was not quite right.

For some reason, a previously working segment of code that calculates each button’s bounding volume was not coming out to be correct any longer. The algorithm was modified slightly to only add the button bounds’ vertical size instead of tracking the total cumulative bounds. Functionally, this should have been exactly the same.

4. Physics accuracy value behavior changed

One of the values changed in the Unity upgrade was “Physics.defaultContactOffset.” This was previously called “Physics.minPenetrationForPenalty” and we discovered that more than just the name was changed.

Now the value must be a positive non-zero value, and at some points we were setting it to zero for the highest accuracy collision detection. The value is a floating point number, so we set it to the closest to zero positive value we could during those points: “float.Epsilon.”

5. Rigidbody Constraints did not keep the objects from moving

One of the things to occur when moving an object is that the Rigidbody settings are modified so that the object is not affected by colliding with other objects, other than just detecting it.

Something we noticed when moving Photo objects over Custom Frames is when the default frame is activated or deactivated, the physics caused it to move slightly. You would start out with an upright frame and end up with a tilted one.

We added in setting the “isKinematic” flag of the Rigidbodies, as well as the “constraints” when enabling or disabling the frame to prevent this.

6. Wheel Colliders were revamped and rendered unusable in our system

The way Wheel Colliders work in Unity 5 drastically changed, which has caused our RC Car minigames to become unplayable.

Many developers have reported similar issues – a result of Unity’s physics engine changes - in the Unity forum. We are hoping that Unity will iron out some of these problems before we take a stab at fixing it, as the RC cars are fairly complex internally and might require more changes after another update.

7. Using Shader.Find() in member initialization causes an error

This issue was difficult to identify because the error did not indicate clearly what the problem was.

Eventually, through trial and error, we located the cause - using Shader.Find() in a class member initialization. This was moved to an initialize function, which resolved the issue.

•    Error: “Recursive Serialization is not supported. You can't dereference a PPtr while loading.”

Unity 5.2

8. Using NameToLayer in member initialization causes an error

This issue was similar to the Shader.Find() issue above, but was a little more clear on what the issue actually was.

The error showed up when an AssetBundle that had a script associated with it (in this case, our Door class) had a layer mask as a class member initializer. We cleaned this up and moved the necessary code into the Awake() function of the base class and it cleared up the issue.

•    Error: “NameToLayer can only be called from the main thread. Constructors and field initializers will be executed from the loading thread when loading a scene. Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.”

Stay tuned to find out what we have learned, what we did to address issues identified, and where we are in the process of upgrading to Unity 5 and WebGL. Our story continues with Egowall and WebGL (Part 4): Web Player Performance Comparison.

WebGL and the WebGL logo are trademarks of the Khronos Group Inc.

Egowall and WebGL (Part 2) - Art and Asset Issues

Check out our Unity-based social networking platform to see what you can do with Egowall. Then sign up for a free account and start using it to be The Real You™.


In Egowall and WebGL (Part 1) - How We Got Here we talked about Google’s early 2015 removal of support for the Unity plugin in Chrome, making it necessary to move Egowall to Unity 5.

Our first step in that process was ensuring a successful upgrade of our code base from the Unity 4.3 Web Player to the Unity 5 Web Player (i.e., no performance degradation and no loss of functionality with the usage of Unity 5 functions). 

Egowall has over 10,000 game objects (e.g., audio, fonts, menus/UI, models, materials, and textures), which are grouped into individual Unity asset bundles and delivered via our Content Delivery Network on an as-needed basis based on player interaction.

As part of the upgrade we needed not only to guarantee that the code base worked, but also that all the asset bundles behaved and functioned as before (or better).  After almost 700 man-hours of slogging, we have resolved all unexpected issues, completed the successful upgrade of the code base, and verified that everything works.

In future blog posts in this series, we will compare performance between the Unity versions. But in this one, we will cover the art and asset-related issues we encountered during the upgrade.

 

TAG MANAGER INDEX SHIFT

 After allowing the Unity auto script updater to execute the upgrade, we found that the one of our defined tags in Unity’s Tag Manager was shifted by one slot. This happened because we had removed an unwanted tag in our code base in the past, leaving an empty entry at index 1.

During the upgrade this empty slot was removed by Unity, which caused all the subsequent tags to be offset by 1. To address this we updated our tag class to reflect the new values shown in the Tag Manager. The main impact of this shift was on our asset bundles.  We set our tags in the bundles and this tag shift required that all of our bundles be rebuilt.

The bundles were going to have to be rebuilt anyway to be compatible with Unity 5. So this issue was taken care of by the required rebuild of our 10,000 assets. No additional action was required.  

 

Transitioning from Beast to Enlighten

While Enlighten - Unity 5’s new light mapping tool - has a lot to offer, we encountered some issues updating from Unity 4’s light mapping tool, Beast

Foremost among them was loss of the ability to specify absolute UV cluster locations on a given lightmap. With Beast we could layout UVs in advance, specifying a specific lightmap for each object, and be assured its UV coordinates could directly match the UVs as laid out in a given object.

Enlighten instead packs object UV clusters as best it can into as few lightmaps as possible. This is useful if you’re not relying on absolute UV coordinate to pack several objects into a lightmap as efficiently as possible.

Additionally, in early versions of Unity 5, Enlighten’s UV packing algorithm created a lot of problems for UV clusters that weren’t square, causing UVs to squash or stretch accordingly. This would lead to distorted or inaccurate lightmaps at runtime.

Luckily, this issue was addressed and fixed by the Unity development team in Unity 5.2.

 

Light Probes

Another issue encountered during the upgrade was light probes. In Unity 4, Beast generated a light probe file that could be pulled from an asset bundle and read. This allowed us to swap out light probe information on the fly.

Light probe information is now stored in a Lighting Data file, which, unfortunately, cannot be accessed from an asset bundle. We were ultimately able to circumvent the issue by utilizing a new feature in Unity 5 that allows us to append scenes, and pull in different Lighting Data attached to those scenes.

On top of this, there were some initial issues with using light probes in Gamma color space being much brighter than the lights that generated them indicated they ought to be. Simply switching to Linear to bypass the issue simply introduced more issues with some shaders no longer behaving as expected.

Fortunately, the issue with over-brightened Light probes in Gamma color space was fixed in Unity 5.3.

 

Shaders

Carrying over Unity 4’s legacy shaders presented an additional challenge in that some shaders no longer functioned as they used to after being updated to Unity 5. For example, materials using the Diffuse shader no longer appeared to interact properly with light maps, causing blowout.

 In this case, the only solution seems to be simply avoiding the use of these problem shaders, until the possibility of a fix at some point in the future. The image below shows the difference.

So stay tuned to find out what we have learned, what we did to address the issues identified, and where we are in the process. Our story continues with Egowall and WebGL (Part 3): Code-Related Issues.

WebGL and the WebGL logo are trademarks of the Khronos Group Inc.