Modules are a way to add additional functionality to each StatusEffectData. Create one by simply inheriting from the Module class and implementing the necessary methods or using Create > Status Effect Framework > Module Script.
You NEED to use the StatusEffects.Modules namespace like in the example below for both Modules and ModuleInstances.
Truthfully anything can be done with them as they are just an inheritable abstract class that calls a method. It is highly recommended to take a look at the samples for an idea of how to use them.
Note that if you have UniTask in your project then the Module will use UniTasks over Awaitable. This is also included in the samples.
Legacy Support
Note that if you are using an ealier version than Unity 2023.1 then the Module will use Coroutines over Awaitable (as it doesn't exist in previous versions). Like UniTask it is also included in the samples and the DisableModule abstract method is can be used used.
(pre 2023.1 only) A method that is invoked when the StatusEffect is stopped.
Example
using System.Threading;
using UnityEngine;
using StatusEffects.Example;
// Use StatusEffects.Modules namespace for organization.
namespace StatusEffects.Modules
{
// Setup scriptable object in create menu.
[CreateAssetMenu(fileName = "Damage Over Time Module", menuName = "Status Effect Framework/Modules/Damage Over Time", order = 1)]
// This attribute will attach the module instance so
// that the interval time can be unique to each effect.
[AttachModuleInstance(typeof(DamageOverTimeInstance))]
public class DamageOverTimeModule : Module
{
public override async Awaitable EnableModule(StatusManager manager, StatusEffect statusEffect, ModuleInstance moduleInstance, CancellationToken token)
{
// Note that for this module it uses a ModuleInstance
// to store a unique interval rate.
DamageOverTimeInstance damageOverTimeInstance = moduleInstance as DamageOverTimeInstance;
// IExamplePlayer is apart of the samples
if (manager.TryGetComponent(out IExamplePlayer player))
// Infinite loop will be cancelled when effect is stopped.
while (!token.IsCancellationRequested)
{
// Reduce health based on the Statu Effect base value
player.Health -= statusEffect.Data.BaseValue * statusEffect.Stacks;
// Wait for the interval before applying the damage again
await Awaitable.WaitForSecondsAsync(damageOverTimeInstance.IntervalSeconds);
}
}
}
}
using Cysharp.Threading.Tasks;
using System.Threading;
using UnityEngine;
using StatusEffects.Example;
// Use StatusEffects.Modules namespace for organization.
namespace StatusEffects.Modules
{
// Setup scriptable object in create menu.
[CreateAssetMenu(fileName = "Damage Over Time Module", menuName = "Status Effect Framework/Modules/Damage Over Time", order = 1)]
// This attribute will attach the module instance so
// that the interval time can be unique to each effect.
[AttachModuleInstance(typeof(DamageOverTimeInstance))]
public class DamageOverTimeModule : Module
{
public override async UniTaskVoid EnableModule(StatusManager manager, StatusEffect statusEffect, ModuleInstance moduleInstance, CancellationToken token)
{
// Note that for this module it uses a ModuleInstance
// to store a unique interval rate.
DamageOverTimeInstance damageOverTimeInstance = moduleInstance as DamageOverTimeInstance;
// IExamplePlayer is apart of the samples
if (manager.TryGetComponent(out IExamplePlayer player))
// Infinite loop will be cancelled when effect is stopped.
while (!token.IsCancellationRequested)
{
// Reduce health based on the Statu Effect base value
player.Health -= statusEffect.Data.BaseValue * statusEffect.Stacks;
// Wait for the interval before applying the damage again
await UniTask.WaitForSeconds(damageOverTimeInstance.IntervalSeconds);
}
}
}
}
using System.Collections;
using UnityEngine;
using StatusEffects.Example;
// Use StatusEffects.Modules namespace for organization.
namespace StatusEffects.Modules
{
// Setup scriptable object in create menu.
[CreateAssetMenu(fileName = "Damage Over Time Module", menuName = "Status Effect Framework/Modules/Damage Over Time", order = 1)]
// This attribute will attach the module instance so
// that the interval time can be unique to each effect.
[AttachModuleInstance(typeof(DamageOverTimeInstance))]
public class DamageOverTimeModule : Module
{
public override IEnumerator EnableModule(StatusManager manager, StatusEffect statusEffect, ModuleInstance moduleInstance)
{
// Note that for this module it uses a ModuleInstance
// to store a unique interval rate.
DamageOverTimeInstance damageOverTimeInstance = moduleInstance as DamageOverTimeInstance;
if (manager.TryGetComponent(out IExamplePlayer player))
// Infinite loop will be cancelled when effect is stopped.
for (; ; )
{
// Reduce health based on the Statu Effect base value
player.Health -= statusEffect.Data.BaseValue * statusEffect.Stacks;
// Wait for the interval before applying the damage again
yield return new WaitForSeconds(damageOverTimeInstance.IntervalSeconds);
}
}
}
}