Virtual Exhibition
Freelance @ SCALE
TECHNOLOGIES: Unity3D, C#, Git LFS, Blender, GIMP, JavaScript
TARGET PLATFORM(s): WebGL
Virtual Exhibtion is a highly-customizable, immersive, 3D job fair that runs flawlessly on WebGl.
This is a freelance software development project done by a team of 2 developers; a fullstack web developer and me as a game developer.
Note: the frame rate of the videos below do NOT reflect the actual frame rate of the game.
Since I wanted to learn as much as possible from this project, only two assets from the Unity Assets Store were used (for 3D Characters and sounds),
everything else was built from scratch; Character Movement, UI, AI System, 3D Models, Camera Collision Avoidance, Lighting, Animations, etc...
Challenges
- WebGl is single-threaded. CPU optimization is extremely important
- Highly coupled and unmaintainable code base
- Animations took alot of CPU time
- Customizable textures have to be requested during runtime
- High numbers of draw calls and high number of vertices
- Indoor realtime lighting heavily impacted game's performance
Solutions
- Reduced the number of materials by sharing materials across numerous 3D models. Heavy use of static batching to reduce state changes.
- ScriptableObjects as intermediate layers. For instance, a ScriptableObject was used as an intermediate layer between the Input Manager and the objects that required input functionalities. Another ScriptableObject was also used as a Scene Management intermediate layer. I've also relied heavily on using Manager Singletons. For instance, we had a UIManager, CustomizationManager, TextureRequestManager, etc... All of these were put into a seperate, persistent Scene that holds all persistent GameObjects. This has greatly improved the structure of the project.
- Use environment to properly set up Occlusion Culling to completely cull NPC characters and set a maximum distance after which they won't be rendered.
- Built a TextureRequestManager that receives texture requests and executes them when possible. Since, for each scene, we have hundreds of texture requests, this manager solved a lot of issues by limiting how many texture requests can be served at a time.
- Manually merge models that share the same material together, this was done for all the roof's 3D models.
- Lightmapping resulted in better visuals with much better performance. Thanks to proper setup of light probes, runtime-instantiated objects had acceptable visual quality.
We've learned that
- Modern principles of software development are extremely important. Not following these results in an unmaintainable project.
- Singletons come with a lot of disadvantages in Unity development environment. Using ScriptableObjects when possible proved to be a better design choice.
- We should optimize for the target platform. WebGl is single-threaded, most performance issues are caused by CPU-bottleneck, thus reducing vertex-count of 3D objects wasn't very helpful in improving the performance.
- Using a CI\CD pipeline could've saved us a lot of time. Many times we had to rebuild the whole project because of an error that could had been easily detected in the integration phase.
- Using the Unity Profiler in development builds helped us identify numerous performance issues.
For project management, we followed the SCRUM agile development methodology where a sprint lasted four weeks. At the end of each sprint the customer reviewed the outcome and gave us feedback. We have heavily relied on using Trello to organize our sprints.