Finishing the Remaining Menu Tasks
- Fixing the Audio Mixer initialization problem
- Add music to the Main Menu
- Make the Main Menu the starting scene
- Fix some scaling issues on a couple menus
Fixing the Audio Mixer
Before moving on to adding more music, I figured it would be best to determine why the Audio Mixer channel volumes weren't being initialized properly, even though the sliders in the settings menu were.
This led me down a long, arduous debugging hole that was mostly inconclusive. I added a lot of debug statements and could see that when I loaded my PlayerPrefs the Mixer was being set correctly but when you open the settings menu the Mixer channels were suddenly back to their defaults.

The log entry highlighted in blue is the final value after we load the PlayerPrefs in. As you can see, it has the correct volume level (60%) but when the settings menu goes to retrieve that same value (the next log down) it is returning back 100%. Obviously, something was happening between when I was loading the settings and when the settings menu was being initialized. However, none of the code I had to set the value was being called, so that led me to believe that something outside my direct control was resetting those values.
I searched the web but did not really find anything on it. I may have not had the right keywords or something but most of the posts were about them trying to set the value and nothing happened, which was the opposite of my problem!
After trying a couple of things, I found that I was initializing the Mixer in the Awake method. I try to follow a general rule of "Awake = Initializing internal stuff, Start = Initializing external stuff". That has served me pretty well in the past but I must have missed it trying to get this done. You can even see that I have it designated as an "external" dependency, so I should have clued in quicker!

After moving the initialization to Start, everything suddenly started working. Great!
Adding Music to Main Menu
Now that the volume controls were good, I could focus on getting music to play in the Main Menu. It is hard to tell if your volume sliders work if you have no sounds playing!
This was pretty straight forward. Andrew did a good job of making the Audio Manager easy to use, with good methods being exposed for playing the various types of sounds. I just had to add a new value to the MusicTrack enum, wire up the associated music file in the Inspector, and call PlayMusic on the Audio Manager.
While that worked in theory, I quickly came across an issue. There was no Audio Manager in the Main Menu scene. It only existed in the Main Game scene. I had nothing in the Inspector to assign the music file to. I thought about making the Audio Manager into a prefab and putting it on both scenes but I didn't like that because when we changed scenes it would lose whatever it was doing.
Instead, I converted it to what I am calling a "persistent manager". Basically, the same thing but we call DontDestroyOnLoad when we initialize it. You can see that in my earlier screenshot at the end of the Awake method. This allows the game object to persist between scene changes, so it will keep playing music uninterrupted while the main game scene loads. I did couple this with my other idea and made it part of a prefab (with the DataPersistentManager as well) that could be dropped on any scene. This gave me the best of both worlds: an Audio Manager available on any scene I want that would persist even if I changed scenes. The other code in the Awake method above prevents having multiple instances if there is a persistent Audio Manager in memory and a new one in the scene we are loading.
As far as the actual music went, Andrew had a couple of awesome tracks that weren't being used in the project and I really liked the alternative version he had of the main theme that plays during the main game. It was close to it but still distinct enough and it felt good for a main menu scene.
Setting the Main Menu as the Starting Scene
Getting the Main Menu to be the starting scene turned out to be really easy. Apparently whatever scene is first in the Scene List in the Build Profile is the starting scene. I just had to drag and drop the Main Menu scene to the top and it worked. I love simple solutions!

Making the UI Responsive
Speaking of simple, getting the game over screen to be responsive (and fit the "new" 16:9 resolution) was not. I'm still learning the Unity UI system, with its anchors and pivot points, but I got it mostly scaling correctly with the screen size. Everything was looking pretty good except for this vertical separator right here.

When the screen scaled, it would just scale into nothing instead of scaling and moving like everything else. I tried setting the anchors to different places and even setting the pivot (though I didn't think that would do anything). I even had Terra look at it but we couldn't figure out why just that one UI element was misbehaving.
It turns out, if you rotate an RectTransform/Image the anchors do not rotate with it. I guess that makes sense but I was definitely not expecting it! That divider is the same sprite as the horizontal one above it, just rotated 90 degrees. So, the "right" side of the vertical divider was being treated like the top side of the horizontal one, which made it scale weird. The anchors were all wrong for it to scale "correctly". I ended up taking the divider sprite and just making a vertical version of it to use there instead. Worked like a charm!
A New Challenger Approaches...No Particles!
While I was testing the game out to ensure everything was scaling properly and the PlayerPrefs worked in the WebGL build (as I was assured they would) I ran across a problem. I didn't notice it at first but the spell VFX that I had put in weren't showing up in the web build. I tried all of the spells and even watched the Glimmerstalker pop into and out of existence. No spell VFX, no snow puff, nothing!
Apparently, WebGL doesn't support Unity's VFX Graph, since they use compute shaders and run on the GPU. While WebGL doesn't support it, WebGPU does but Unity 6.0 doesn't support WebGPU. However, Unity 6.1 (experimentally) supports WebGPU.
I didn't know that VFX Graph wasn't supported when I built the VFX or I would have avoided the VFX Graph altogether for this project. I felt like I had two options: Rebuild all of the VFX in the older Particle System or upgrade our project to use Unity 6.1 and enable an experimental feature to make it work.
I was hesitant to upgrade the project this close to the deadline, since I don't know if things would behave differently in 6.0 vs 6.1. It isn't a big version leap but still. I also didn't know if that experimental feature would actually work for us. Talking with Terra, she brought up that there could be other issues that we encounter and if we did we would have wasted a bunch of time upgrading the project and still probably would have needed to rebuild the VFX in the Particle System.
The unknowns, combined with a generally lack of support for WebGPU on older browsers, led me to pursue the first option of just rebuilding everything. This process was decently simple. Most of the fields I used in the VFX Graph were present in the Particle System or at least close enough. Luckily, I had kept the VFX pretty simple and it only took a couple of hours to get them both remade.
In some ways they look better than the others (like the spell VFX actually follow the player instead of flying off if they are moving) and others look worse (like the snow puff being a bit more solid/homogenous than the previous one). Overall, they are good enough!

Now, I just need to catch up with the team to see what still needs to be done!