-
Notifications
You must be signed in to change notification settings - Fork 4
Adding Extra Events
As mentioned in the character barks overview, there are a number of AnimationBarks that are not used by the vanilla PC soundsets. The ones most likely to be of interest/use to most people are those related to spell casting. Specifically:
- Cast
- CastDirect
- CastLong
- CastShort
- CastTouch
- CastYourself
- Omnicast
- Precast
There are two animation components when casting a normal spell. The first occurs during the "wind-up", where the character will perform some wavy hand movements, typically with some VFX attached. This is the Precast
. The length of this animation is variable depending on the nature of the spell being cast. The second occurs when the spell itself actually fires. This will be whatever particular category that spell belongs to. CastLong
, CastTouch
, etc.
Note that anything that removes the casting animation, like Quickened metamagic, will naturally also remove the AnimationBark/s.
In the case of casting chants, the template's Asks blueprint in Main.cs already has placeholder AnimationBarks. However, they have empty Entries
fields, so they don't do anything by default. In order to add custom chants, we need to do two things. The first is to populate the Entries lists of those AnimationBarks we want to fire, and the second is to prevent vanilla generic chants from playing when the user of our soundbanks casts. You will have noticed that all player/mercenary characters use shared chanting audio for spell casting, and that these are not specified in the vanilla blueprints. They are controlled separately.
There's a series of checks that the engine does to determine whether or not a chant should play, and what chant sound to use. For our purposes the only relevant part is that one of the checks run is SilentCaster
. This determines whether or not the unit in question can vocalise, which is either flagged in their unit blueprint or inflicted by a status condition like polymorph. We can use this to our advantage by patching this check and forcing it to return true when it is run on a unit with our soundbank, thereby preventing the vanilla chants from playing. To do that we'll need to make some code additions.
Open the project solution in Visual Studio. Open Main.cs and near the to find the following section:
[HarmonyPatch]
public static class Soundbanks
Right above that, add a new blank line and then paste in the following:
public class NoCastChants : BlueprintComponent { }
Now scroll down to until you find static void AddAsksListBlueprint()
and select the following section:
blueprint.ComponentsArray =
[
new UnitAsksComponent()
{
OwnerBlueprint = blueprint,
Replace it with the following:
blueprint.ComponentsArray =
[
new NoCastChants() { },
new UnitAsksComponent()
{
OwnerBlueprint = blueprint,
What we're doing is creating a custom, empty component in this blueprint called NoChantCasts
. This will be unique to units that are using our soundset. Now we have a way to identify said units when the SilentCaster
check is run.
Scroll right down to the bottom of the file, select this line:
ResourcesLibrary.BlueprintsCache.AddCachedBlueprint(blueprint.AssetGuid, blueprint);
and replace it with this:
ResourcesLibrary.BlueprintsCache.AddCachedBlueprint(blueprint.AssetGuid, blueprint);
blueprint.OnEnable();
Then select this section below it:
.Append(blueprint.ToReference<BlueprintUnitAsksListReference>())
.ToArray();
}
}
and replace it with this:
.Append(blueprint.ToReference<BlueprintUnitAsksListReference>())
.ToArray();
}
[HarmonyPatch(typeof(UnitEntityData), nameof(UnitEntityData.SilentCaster), MethodType.Getter)]
[HarmonyPostfix]
static void Patch(ref bool __result, UnitEntityData __instance)
{
if (__instance.Descriptor.Asks.GetComponent<NoCastChants>() is not null)
{
__result = true;
}
}
}
This patches the SilentCaster
check to make it look for the presence of the NoCastChants
component on the unit being passed to it. If the component is present, then SilentCaster
will return true (i.e. that the unit does not vocalise) regardless of any regular circumstances, thereby disabling the vanilla chants.
At this point you can save Main.cs and Build your project to test the patch is working. Load up a save that has a unit with your soundset and have it cast some spells. Remember these need to be regular spells, not Quickened ones. If all went to plan then you should be getting the regular casting animations but no chanting sounds.
Now that we've disabled the vanilla chants, we can have the game play our custom ones. In Main.cs, scroll through the blueprint until you find AnimationEvent = MappedAnimationEventType.Cast
. This is the first of the chants. You'll see it's Entries
list is empty:
Entries = [],
We need to add a custom Event to it that we can link in Wwise. Like so:
Entries =
[
new()
{
Text = null,
AkEvent = "<ProjectName>_Cast",
RandomWeight = 0.0f,
ExcludeTime = 0,
m_RequiredFlags = [],
m_ExcludedFlags = [],
m_RequiredEtudes = null,
m_ExcludedEtudes = null
}
],
You can name <ProjectName>_Cast
whatever you like, but it must match the Event name in Wwise. The pre-existing Events in the template follow the <ProjectName>_xxx
format, so sticking with that means less work.
The subsequent chants are all the same, the only difference is their AkEvent names. <ProjectName>_CastLong
, <ProjectName>_CastShort
, etc. As mentioned previously, it's advisable to leave Precast
's Entries list blank unless you have some extremely short sounds for it. But feel free to experiment.
Assuming you have populated the chant containers in Wwise, linked them to their Events, added the Events to the soundbank, and generated it, then save Main.cs and Build. Load up a save to check out your custom spell casting chants in action.
As usual, if you are having problems first confirm everything is set up as it should be. Sounds are attached to Events, Events are added to the soundbank, the soundbank is freshly generated, the Event names match the AkEvent names exactly. If the issues persist, please make a post in the #mod-dev-technical
channel of the Owlcat Discord. You will definitely need to supply source code if using added AnimationBarks, so consider uploading your source to Github if you haven't already.
Casting chants should be the hardest example. The other types of AnimationBarks and the unused weather Barks should only require blueprint editing and matching Events in Wwise, no custom code. Have a look at the barks blueprints of animal companions and various monster units for some ideas.
Getting Started
[Wrath] Game Structure
- Abilities
- Blueprints
- Blueprint Components