Interface

MethodDescription
Execute(ExecutionContext context)Called every time the owning character executes an instruction step. Use it to trigger animations, sounds, projectiles, or any side-effect that should accompany the action.

How registration works

You do not need to register subscribers manually. Both PlayerController and EnemyController call GetComponentsInChildren<IExecutionSuscriber>() during Initialize() and wire every result into their internal OnExecute event:

// same pattern in both PlayerController.Initialize() and EnemyController.Initialize()
IExecutionSuscriber[] suscribers = GetComponentsInChildren<IExecutionSuscriber>();
foreach (IExecutionSuscriber s in suscribers)
    OnExecute += s.Execute;

Each time the character executes an instruction, the controller invokes OnExecute, which calls Execute() on every registered subscriber in order.

To add a subscriber: attach a MonoBehaviour that implements IExecutionSuscriber to the player's or enemy's root GameObject or any of its children. No other wiring is required.

IExecutionSuscriber vs ITaskReceiver

IExecutionSuscriberITaskReceiver
OwnershipReacts to the player's or enemy's own instruction executionSchedules an independent parallel task
TimingSynchronous — fires inline during instruction executionAsynchronous — runs concurrently alongside player instructions
Use whenYou need a fire-and-forget side-effect (sound, VFX, projectile) tied to the character's actionThe object needs its own coroutine that runs in parallel every turn
RegistrationAuto-discovered via GetComponentsInChildren on both player and enemyMust be registered with the runner explicitly

Example

A subscriber that plays a sound clip each time the character executes an action — works on both the player and enemies:

using UnityEngine;

namespace LoopAdventure
{
    public class ActionSoundSubscriber : MonoBehaviour, IExecutionSuscriber
    {
        [SerializeField] AudioClip actionClip;
        AudioSource audioSource;

        void Start()
        {
            audioSource = GetComponentInParent<AudioSource>();
        }

        public void Execute(ExecutionContext context)
        {
            if (actionClip != null)
                audioSource.PlayOneShot(actionClip);
        }
    }
}

Attach this to the player's or enemy's root GameObject or any child. Both controllers will pick it up automatically — no further wiring needed.

Built-in implementations

ClassBehaviour
ShootSuscriberFires a Projectile prefab in the character's current direction from the subscriber's world position each time an instruction executes. Assign the projectile prefab in the Inspector. Can be placed on the player or an enemy.