Revision Difference
AnimEvents,_AnimGraph_Tags,_and_Attachments#563087
<title>AnimEvents, AnimGraph Tags, Attachments</title>
<cat>Model.Animation</cat>
##What are AnimEvents?
[AnimEvents](AnimEvents,_AnimGraph_Tags,_and_Attachments#animevents) are used in **ModelDoc** as a way to make something happen during a specific frame of a **Simple Animation**, most commonly used to:
* [Play **Sounds**](AnimEvents,_AnimGraph_Tags,_and_Attachments#soundevents)
* [Create **Particles**](AnimEvents,_AnimGraph_Tags,_and_Attachments#particleevents)
* [Switch **Bodygroups**](AnimEvents,_AnimGraph_Tags,_and_Attachments#bodygroupevents)
* [Add dynamic **Foot Steps**](AnimEvents,_AnimGraph_Tags,_and_Attachments#footstepevents)
* [Run **Code** in your game](AnimEvents,_AnimGraph_Tags,_and_Attachments#runcodewithgenericevents)
##What are AnimGraph Tags?
[Animgraph Tags](AnimEvents,_AnimGraph_Tags,_and_Attachments#animgraphtags) are used inside an **AnimGraph** to communicate with itself.
You can specify the *start* and *end* of when a Tag is active inside individual **Animation Clips**, most commonly used to:
* [Be a **Condition** in State Machines](AnimEvents,_AnimGraph_Tags,_and_Attachments#tagconditioninastatemachine)
* [Run **Code** in your game](AnimEvents,_AnimGraph_Tags,_and_Attachments#runcodewithtags)
#Attachments
An **Attachment** is a point, similar to bones, but created in ModelDoc, and is required for many functions that need a position, like most AnimEvents.
###Creating Attachments in ModelDoc:
1. Press <key>✙Add</key>, add an `Attachment` and name it.
2. Select which **Bone** will be its parent, this is the bone it will follow.
<note>You can select "*None*", this will instead use the origin of the model.</note>
3. Position the attachment *(you can use the various gizmos in the top left to aid you).*
<upload src="a4aaf/8dad9599234e029.png" size="5436" name="image.png" />
This should be the final result *(**mouth** is the attachment)*:
<upload src="a4aaf/8dad959bd99e5e1.png" size="393942" name="image.png" />
<note>The `RED` arrow indicates forward, while the **BLUE** arrow is up, make sure they are correct by rotating the attachment in the node itself.</note>
#AnimEvents
To add an AnimEvent *Right Click* a **Simple Animation** node, and select `Add AnimEvent...`
<upload src="a4aaf/8dad95ae2a41f94.png" size="10534" name="image.png" />
Once you selected an AnimEvent, you can choose the frame it will activate either in the **Timeline**, by dragging the AnimEvent, or in the Event's node by typing the frame.
<upload src="a4aaf/8dad95c17bb6b3d.png" size="10543" name="image.png" />
##Sound Events
To play a sound, select:
* **AE_CL_PLAYSOUND**: Play a sound **Clientside** from the model's origin.
* **AE_CL_PLAYSOUND_ATTACHMENT**: Play a sound *ClientSide* from an **Attachment**.
* **AE_SV_PLAYSOUND**: Play a sound **Serverside** from the model's origin.
Then select a sound, after compiling, you can preview the AnimEvent:
<upload src="a4aaf/8dad95f1e288bae.mp4" size="455634" name="soundevent.mp4" />
##Particle Events
<deprecated>This uses the legacy particle system. For the component based particles, create them with a generic anim event.</deprecated>⤶
<warning>⤶
This uses the legacy particle system. For the component based particles, create them with a generic anim event.⤶
</warning>⤶
To create particles, select:
* **AE_CL_CREATE_PARTICLE_EFFECT**: Create a particle from an **Attachment**.
* **AE_CL_ADD_PARTICLE_EFFECT_CP**: Add a **Control Point** for a *Particle* from an *Attachment*.
Then select a particle, and leave the default attachment type as is, as it should be fine for most cases.
After compiling, you can preview the AnimEvent:
<upload src="a4aaf/8dad96310b58a8b.mp4" size="205392" name="Particles.mp4" />
##BodyGroup Events
To switch bodygroups, select:
* **AE_CL_BODYGROUP_SET_VALUE**: Set the **Value** of a *bodygroup*, *clientside*.
* **AE_SV_BODYGROUP_SET_VALUE**: Set the *Value* of a *bodygroup*, **Serverside**.
* **AE_CL_ENABLE_BODYGROUP**: *Enable* a *bodygroup*
* **AE_CL_DISABLE_BODYGROUP**: *Disable* a *bodygroup*
Then Select a bodygroup, and the desired value *(equivalent to their "Choice" number, starting from 0)*.
After compiling, you can preview the AnimEvent:
<upload src="a4aaf/8dad9663b70d0fe.mp4" size="456501" name="bodygroups.mp4" />
##FootStep Events
To add dynamic footsteps, select:
* **AE_FOOTSTEP**: Play a dynamic **Footstep** sound from an *Attachment*
You may set the **Volume** of the footstep, and whether it's **LEFT** or **RIGHT** *(Even if your character has more than 2 feet)*.
```csharp
SkinnedModelRenderer ModelRenderer { get; set; }
protected override void OnStart()
{
ModelRenderer.OnFootstepEvent += HandleFootstepEvent;
}
private void HandleFootstepEvent( SceneModel.FootstepEvent step )
{
var position = step.Transform.Position;
var trace = Scene.Trace.Ray( position, position + Vector3.Down * 10f )
.IgnoreGameObjectHierarchy( GameObject )
.Run();
var surface = trace.Surface;
var sound = surface.Sounds.FootLand;
var stepSound = Sound.Play( sound, trace.HitPosition );
stepSound.Volume = step.Volume;
}
```
This example code is used for footsteps by checking the surface type below.
##Run code with Generic Events
You may also add **Generic Events** that do nothing, but signal your game when the animation has an event.
**AE_GENERIC_EVENT** can include:
* **Integer** data
* **Float** data
* **Vector** data
* **String** data
* Type Name
```csharp
SkinnedModelRenderer ModelRenderer { get; set; }
protected override void OnStart()
{
ModelRenderer.OnGenericEvent += HandleGenericEvent;
}
private void HandleGenericEvent(SceneModel.GenericEvent eventData)
{
if (eventData.Type == "ExampleEvent")
{
// Do something
}
}
```
#AnimGraph Tags
To add a Tag in your Animgraph:
1. In the **Tags** widget, press <key>✙</key> and select `Internal Tag`, name it accordingly.
Then, to set the Tag inside your Animation Clips:
2. Double Click an **Animation Clip** to enter it.
3. Press <key>✙</key> and select your **Tag**
4. Slide the Tag's start and end for the desired duration
<upload src="a4aaf/8dad9717d3aab38.png" size="477051" name="image.png" />
`In this example, the "Invincibility Frames" tag lasts from 0.5s to 1.0s`
##Tag Condition in a State Machine
Inside a state machine, you can select **Internal Tags** as **Tag Condition**
<upload src="a4aaf/8dad9726e8884fc.png" size="80857" name="image.png" />
`In this example, the "Disable LookAt" tag is used to disable a LookAt chain at the start of either "Growl" or "Howl" animations, until they finish their respective action.`
##Run Code with Tags
You can also use Tags to run code:
```csharp
SkinnedModelRenderer ModelRenderer { get; set; }
protected override void OnStart()
{
ModelRenderer.OnAnimTagEvent += HandleAnimTagEvent;
}
protected override void HandleAnimTagEvent( SceneModel.AnimTagEvent tagEvent )
{
if ( tagEvent.Name == "Invincibility Frames" )
{
if ( tagEvent.Status == SceneModel.AnimTagStatus.Start )
{
// Enable invincibility
Log.Info( "I am now invincible!" );
}
else if ( tagEvent.Status == SceneModel.AnimTagStatus.End )
{
// Disable invincibility
Log.Info( "I am not invincible anymore..." );
}
}
}
```
This example code will make a character invincible during the **`Invincibility Frames`** tag, useful for features such as a Dark Souls-Styled Roll mechanic.