02 Mar 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.
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.
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.
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.”
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.