// MIT License - Copyright (c) 2025 wallstop // Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE namespace WallstopStudios.UnityHelpers.Tags { using System; using System.Collections.Generic; using ProtoBuf; using UnityEngine; /// /// Authoring data for a periodic modifier bundle that executes on a cadence while an effect is active. /// /// /// /// The owning evaluates each periodic definition after /// , applies the configured /// , and repeats every /// seconds until /// is reached or the effect ends. /// /// /// Definitions are processed in list order and maintain independent runtime state per /// , enabling designers to mix damage-over-time, heal-over-time, /// or custom triggers alongside bespoke implementations. /// /// /// /// /// using System.Collections.Generic; /// using UnityEngine; /// using WallstopStudios.UnityHelpers.Tags; /// /// public sealed class BurnEffectAuthoring : MonoBehaviour /// { /// [SerializeField] /// private AttributeEffect burnEffect; /// /// [SerializeField] /// private EffectHandler effectHandler; /// /// public void ApplyBurn(GameObject target) /// { /// PeriodicEffectDefinition burnTick = new PeriodicEffectDefinition /// { /// name = "Burn Damage", /// initialDelay = 0.5f, /// interval = 1.0f, /// maxTicks = 5, /// modifications = new List<AttributeModification> /// { /// new AttributeModification("Health", ModificationAction.Addition, -5f), /// }, /// }; /// /// burnEffect.periodicEffects.Add(burnTick); /// /// if (effectHandler == null) /// { /// effectHandler = target.GetComponent<EffectHandler>(); /// } /// /// EffectHandle? handle = effectHandler.ApplyEffect(burnEffect); /// } /// } /// /// /// In the example above the handler waits for initialDelay, applies the /// every interval seconds, and stops after /// executions or as soon as the effect is removed. /// /// [Serializable] [ProtoContract] public sealed class PeriodicEffectDefinition { /// /// Optional label shown in tooling to help distinguish multiple periodic definitions. /// [ProtoMember(1)] public string name; /// /// Time (seconds) before the first tick fires after the effect is applied. /// [Min(0f)] [ProtoMember(2)] public float initialDelay; /// /// Interval (seconds) between ticks once the first tick has executed. /// [Min(0.01f)] [ProtoMember(3)] public float interval = 1f; /// /// Maximum number of ticks to execute. Zero or negative means unlimited ticks. /// [Min(0)] [ProtoMember(4)] public int maxTicks; /// /// Attribute modifications applied each time the tick fires. /// [ProtoMember(5)] public List modifications = new(); } }