class FootSteps : ScriptObject
{
    void Start()
    {
        // Subscribe to animation triggers, which are sent by the AnimatedModel's node (same as our node)
        SubscribeToEvent(node, "AnimationTrigger", "HandleAnimationTrigger");
    }

    void HandleAnimationTrigger(StringHash eventType, VariantMap& eventData)
    {
        AnimatedModel@ model = node.GetComponent("AnimatedModel");
        AnimationState@ state = model.animationStates[eventData["Name"].GetString()];
        if (state is null)
            return;

        // If the animation is blended with sufficient weight, instantiate a local particle effect for the footstep.
        // The trigger data (string) tells the bone scenenode to use. Note: called on both client and server
        if (state.weight > 0.5f)
        {
            Node@ bone = node.GetChild(eventData["Data"].GetString(), true);
            if (bone !is null)
                SpawnParticleEffect(bone.worldPosition, "Particle/SnowExplosionFade.xml", 1, LOCAL);
        }
    }
}