Footsteps on different ground materials are a classic example of switch usage in Wwise: You have a single "Footstep" event that plays a Switch Container that will play the appropriate sounds based on the current "GroundMaterial" switch. A more complex version of this would have additional levels of switches for character type, character health, etc. Another example is a gun shot Switch Container hierarchy that switches on gun type, level of ammo, etc.
Another way of achieving the same results is to have multiple events, for example: "Footstep_Soldier_Snow", "Footstep_Soldier_Water", "Foostep_Robot_Snow", etc, and have the game post the appropriate event instead of setting switches before posting the single "Footstep" event.
Which way is better? It varies from game to game and even from case to case in the same game, so only you can answer that question. Let's discuss a few things that will help you decide.
One thing to keep in mind when using switches is that by default, everything in the Switch Container will be loaded in memory when you load the soundbank that contains it. For example let's say you have one Switch Container named "GunShot" with a single Play event that is called in all cases in the game. This Switch Container switches on the gun type (let's say you have 5 types of guns), and contains another level of Switch Containers that switch on fire mode (2 modes), and then another level for ammo level (2 levels). At that point let's say you have random containers with 5 different sounds in each of them. You have a total of 100 sounds. If this container is simply loaded from a soundbank in your game, the whole structure, including all the 100 sounds, will be loaded in memory, even if you know that only one type of gun will actually be used for the next little while.
To improve on this, instead of loading the whole bank, use the AK::SoundEngine::PrepareEvent() mechanism along with AK::SoundEngine::PrepareGameSyncs() to tell the sound engine which switches will actually be used. This will ensure that only what is really needed will be loaded in memory, while still keeping the simplicity of a single event and switches deciding what to play.
Note that if some sounds are used in more than one switch (for example if some sounds are reused for several gun types), you might want to prepare new switches with PrepareGameSyncs() before unpreparing other switches, so sounds that are shared between several switches are not unloaded/reloaded unnecessarily. Also note that preparing/unpreparing events and game syncs is similar to loading/unloading banks: It takes some CPU and disk I/O to perform these operations. Depending on what else is happening in the game at the same time, it may or may not cause problems. You can prepare events/gamesyncs in advance, even asynchronously, so you have a lot of freedom to tweak things the way you want.
Of course you can always "cut" the hierarchy of switch containers at any point and replace some of them with separate events. For example you could remove the first level of Switch Container (the one that switches on gun type) and replace it with separate fire events for each type of gun, keeping switches for the other levels of variation. In this case you could either have separate soundbanks for each guntype, or use PrepareEvent() to load the appropriate objects when needed.
If you decide to have multiple events (either "only" events, without any switches, or a hybrid system with events and switches), it helps to have a clear naming convention, for example "GunFire_<GUN-TYPE-GOES-HERE>". It can make things easier in the code (the event name can be built at runtime instead of being completely hardcoded), and collaboration between the dev and the sound designer will be simplified.
As you can see, you can go with switches all the way, or with separate events all the way, or somewhere in between. Which approach is better depends on exactly what you are trying to do, how your game engine works, etc. The best thing is to try one way, see how it works, and then adapt. You can also try different approaches for different cases early in the development and see what works best. This way you will find your own Best Practices that work well in your particular case.