Show / Hide Table of Contents

Behaviour and the Resolving Assets

Modular Footstep is heavy on the asset-based workflow. These assets connects together via asset reference (GUID), there is absolutely no string or enum labels, no magic numbers or index, etc.

Each type of asset here is a subclass of ScriptableObject, a class which can instantiate an asset file to exist in the project, serializing values.

FootstepBehaviour

This type of asset is the final destination, representing how the sound would behave.

If an eleplant repeatedly steps on wet grass, the "audio would behave" in one FootstepBehaviour way. If using the same floor but change the stepper to human wearing sandals, we get one different FootstepBehavior. If we lock it to a human still, but change sandals to boots, again, a different FootstepBehaviour.

Each FootstepBehaviour has a "program" inside to account for variations or sequence of sound that it can produce. You can ask any FootstepBehaviour to sound in interval, or one-shot (once or repeatedly).

You may think of an API to look like this :

footstepSource.Play(footstepBehaviour);

Similar to the familliar audioSource.Play(audioClip). But this approach has one big problem : Footstep often have shared "traits" or "hierarchy" between them.

By using only FootstepBehaviour, we are forced to linearize all those connections. And the workload of choosing the right FootstepBehaviour from a mountain of assets falls into the programmer.

Imagine this collection of FootstepBehaviour all represent different occassions, even though only parts of them are different :

Walk-Grass-Greaves.asset
Run-Grass-Greaves.asset
TipToe-Grass-Greaves.asset
Walk-Grass-Boots.asset
Run-Grass-Boots.asset
...(100+ more?)...

This character wearing other footwear, this character on an another kind of surface such as soil or stone floor, or a new kind of action, all add combinations to the whole thing.

I play Overwatch often, and it is amazing that you can identify which character is approaching you by listening to the footsteps, which are intentionally unique and volume boosted more than your ally. Each character has an equally identifiable walk, jump, and landing sound on many kind of surfaces in the game. This game has 32 characters. Imagine how many FootstepBehaviour would these exploded into. There are even more AudioClip that are needed, because one FootstepBehaviour would need to randomly pick from several clips for variety. Props to the sound engineer that managed to design gorilla step sound onto all required surfaces and actions...

Footstep package need to step in and provide hierarchical feature to combat this management nightmare!

The 4 resolving assets

Modular Footstep uses 4 asset types to represent different combinations that would resolve into a single FootstepBehaviour. They are named :

  • Surface : Intended to represent different surfaces.
  • SurfaceModifer : Intended to represent different conditions of the surface.
  • Stepper : Intended to represent footwears, or actor that is stepping (such as what kind of animal).
  • StepperModifier : Intended to represent different actions performed on the surface, wears and tears level of the footwear, or even different kind of switchable footwears if you used Stepper as something else such as character's name.

I say intended all over, because you can think of these in completely abstract way, as A, B, C, and D without any meaning. (Though, it would help if your interpretation is not too far from these names.)

Providing 4 assets at the same time (null on one of these is also considered a unique combination) gets you back 1 FootstepBehaviour.

You can setup a "menu" to program which combination resolves into which FootstepBehaviour, explained in a bit.

The plugin performs the FootstepBehaviour resolving step for you, then immediately play the returned FootstepBehaviour. Therefore an actual API looks more like this (not exactly) :

footstepSource.Play(surface, surfaceModifier, stepper, stepperModifer);

You are not allowed to input FootstepBehaviour directly into any of the API. Input are always Surface + SurfaceModifier + Stepper + StepperModifier. It resolves inside the package into FootstepBehaviour automatically, according to your "menu". In practice, this allows you to switch only some part of the API call dynamically so it resolves into a different FootstepBehaviour.

Where is this "menu"?

Surface is the menu!

4 resolving assets are almost equal, only the Surface has a bit more going on inside.

When you inspect on Surface asset, the Inspector allows programming the resolver how it takes in 3 remaining asset types : SurfaceModifier, Stepper, and StepperModifier, that would resolves into which FootstepBehaviour you would like. (More about this in Getting Started/Setup Resolvers in the Surface.)

Inspecting Surface

Look at this prototype API call again :

footstepSource.Play(surface, surfaceModifier, stepper, stepperModifer);

From your perspective, it looks like 4 assets are combined into one FootstepBehaviour. But actually, the plugin takes 3 latter assets : SurfaceModifier, Stepper, StepperModifier, to resolve with the logic that is stored in the first argument Surface, producing FootstepBehaviour.

And this also means Surface cannot be null among the 4 assets. Inversely, just Surface and without SurfaceModifier, without Stepper, without StepperModifier is enough to resolve a FootstepBehaviour.

Imagine a simple game that step sound does not change no matter which character you use, has only walk sound, and change according to surface. You only need a collection of Surface and equal amount of FootstepBehaviour for this game. The resolver is then a simple 1-to-1 mapping from Surface to FootstepBehaviour.

Tip

Notice that only Surface's icon has no little red tag, unlike the others (, , ).

This is a reminder that other assets are mere "tags" and have less data, unlike Surface which has big settings inside it.

Implied hierarchy ordering

The resolver being inside Surface implies that it is "the first" among 4 assets that combine into FootstepBehavior. You can of course look at all 4 assets equally, fusing together into FootstepBehaviour. But Footstep Behaviour is opinionated that the resolving hierarchy is according to the following :

Surface > SurfaceModifier > Stepper > StepperModifer ---> FootstepBehaviour

This opinion is reflected in the "menu" you can program into the Surface. Footstep Behaviour give you a tree-like UI that let you program the resolver in this order SurfaceModifier > Stepper > StepperModifer, saving you repetitive work. (And also a more generic, linear SurfaceModifier + Stepper + StepperModifier UI without the tree structure.)

You are ready to create these assets!

Go to Getting Started/Installing to get Modular Footstep inside your game, then start creating the resolver inside Surface in Getting Started/Setup Resolvers in the Surface.

In This Article
Back to top
A Unity plugin by 5argon from Exceed7 Experiments. Problems/suggestions/contact : 5argon@exceed7.com Discord Unity Forum