> For the complete documentation index, see [llms.txt](https://maraudical.gitbook.io/status-effects-framework/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://maraudical.gitbook.io/status-effects-framework/type-specifics/scriptable-objects/moduleinstance.md).

# ModuleInstance

<figure><picture><source srcset="/files/ltKZZuOEh6ekCoEG5ooO" media="(prefers-color-scheme: dark)"><img src="/files/F9bN9p5fTylodGPGMagG" alt="" width="188"></picture><figcaption></figcaption></figure>

### Description

[ModuleInstances](/status-effects-framework/type-specifics/scriptable-objects/moduleinstance.md) can be attached to [Modules](/status-effects-framework/type-specifics/scriptable-objects/module.md) so that unique data can be selected per [StatusEffectData](/status-effects-framework/type-specifics/scriptable-objects/statuseffectdata.md). Create one by simply inheriting from the [ModuleInstance](/status-effects-framework/type-specifics/scriptable-objects/moduleinstance.md) class or using <kbd>Create > Status Effect Framework > Module Instance Script</kbd>.

{% hint style="danger" %}
You **NEED** to use the `StatusEffects.Modules` namespace like in the example below for both [Modules](/status-effects-framework/type-specifics/scriptable-objects/module.md) and [ModuleInstances](/status-effects-framework/type-specifics/scriptable-objects/moduleinstance.md).
{% endhint %}

{% hint style="warning" %}
You do not need to add these to the create menu! As long as it is attached to a [Module](/status-effects-framework/type-specifics/scriptable-objects/module.md) using the attribute it will be created automatically.
{% endhint %}

As an example, say you need a VFX prefab to be instantiated on each effect. Instead of having to create a unique [Module](/status-effects-framework/type-specifics/scriptable-objects/module.md) for each prefab that you need, just add the variables you need in the [ModuleInstance](/status-effects-framework/type-specifics/scriptable-objects/moduleinstance.md) and attach it to the [Module](/status-effects-framework/type-specifics/scriptable-objects/module.md) using the `[AttachModuleInstance]` attribute.

Now, every time you add a module to a [StatusEffectData](/status-effects-framework/type-specifics/scriptable-objects/statuseffectdata.md), it will instantiate those values for that effect making it so you only need to create one [Module](/status-effects-framework/type-specifics/scriptable-objects/module.md) scriptable object with any constant values and then unique instance values will be displayed in each specific [StatusEffectData](/status-effects-framework/type-specifics/scriptable-objects/statuseffectdata.md).

<figure><img src="/files/0Myqpf9S3ibuzE3V6drg" alt=""><figcaption></figcaption></figure>

### Example

{% code overflow="wrap" fullWidth="true" %}

```csharp
using UnityEngine;
// Use StatusEffects.Modules namespace for organization.
namespace StatusEffects.Modules
{
    public class VFXInstance : ModuleInstance
    {
        public GameObject prefab;  
    }
}
```

{% endcode %}

{% tabs fullWidth="true" %}
{% tab title="Default" %}
{% code overflow="wrap" fullWidth="false" %}

```csharp
using System.Threading;
using UnityEngine;

// Use StatusEffects.Modules namespace for organization.
namespace StatusEffects.Modules
{
    // Setup scriptable object in create menu.
    [CreateAssetMenu(fileName = "Vfx Module", menuName = "Status Effect Framework/Modules/Vfx", order = 1)]
    // This attribute will attach the module instance so 
    // that the vfx can be unique to each effect.
    [AttachModuleInstance(typeof(VfxInstance))]
    public class VfxModule: Module
    {
        public override async Awaitable EnableModule(StatusManager manager, StatusEffect statusEffect, ModuleInstance moduleInstance, CancellationToken token)
        {
            VfxInstance vfxInstance = moduleInstance as VfxInstance;
            // Make sure the particle system stop action is set to destroy so it
            // automatically destroys itself when all particles die.
            GameObject vfxGameObject = Instantiate(vfxInstance.Prefab, manager.transform);
            // If we want this effect to be added everytime more are stacks
            // added we just immediately begin destruction on the current 
            // particle.
            if (vfxInstance.InstantiateAgainWhenAddingStacks)
                statusEffect.OnStackUpdate += (previous, stack) => OnStackUpdate(vfxInstance.Prefab, manager, statusEffect, previous, stack);
            else
                while (!token.IsCancellationRequested)
                    await Awaitable.NextFrameAsync();
            // Attempt to stop the particle system.
            if (!vfxInstance.InstantiateAgainWhenAddingStacks)
            {
                // Note that you need to check if the effect is null in case 
                // the cancellation was invoked from the destruction of 
                // the MonoBehaviour.
                if (!vfxGameObject)
                    return;
            
                vfxGameObject.GetComponent<ParticleSystem>().Stop();
            }
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="UniTask" %}
{% code overflow="wrap" %}

```csharp
using Cysharp.Threading.Tasks;
using System.Threading;
using UnityEngine;

// Use StatusEffects.Modules namespace for organization.
namespace StatusEffects.Modules
{
    // Setup scriptable object in create menu.
    [CreateAssetMenu(fileName = "Vfx Module", menuName = "Status Effect Framework/Modules/Vfx", order = 1)]
    // This attribute will attach the module instance so 
    // that the vfx can be unique to each effect.
    [AttachModuleInstance(typeof(VfxInstance))]
    public class VfxModule: Module
    {
        public override async UniTaskVoid EnableModule(StatusManager manager, StatusEffect statusEffect, ModuleInstance moduleInstance, CancellationToken token)
        {
            VfxInstance vfxInstance = moduleInstance as VfxInstance;
            // Make sure the particle system stop action is set to destroy so it
            // automatically destroys itself when all particles die.
            GameObject vfxGameObject = Instantiate(vfxInstance.Prefab, manager.transform);
            // If we want this effect to be added everytime more are stacks
            // added we just immediately begin destruction on the current 
            // particle.
            if (vfxInstance.InstantiateAgainWhenAddingStacks)
                statusEffect.OnStackUpdate += (previous, stack) => OnStackUpdate(vfxInstance.Prefab, manager, statusEffect, previous, stack);
            else
                await UniTask.WaitUntilCanceled(token);
            // Attempt to stop the particle system.
            if (!vfxInstance.InstantiateAgainWhenAddingStacks)
            {
                // Note that you need to check if the effect is null in case 
                // the cancellation was invoked from the destruction of 
                // the MonoBehaviour.
                if (!vfxGameObject)
                    return;
            
                vfxGameObject.GetComponent<ParticleSystem>().Stop();
            }
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Legacy" %}
{% code overflow="wrap" %}

```csharp
using System.Collections;
using UnityEngine;

// Use StatusEffects.Modules namespace for organization.
namespace StatusEffects.Modules
{
    // Setup scriptable object in create menu.
    [CreateAssetMenu(fileName = "Vfx Module", menuName = "Status Effect Framework/Modules/Vfx", order = 1)]
    // This attribute will attach the module instance so 
    // that the vfx can be unique to each effect.
    [AttachModuleInstance(typeof(VfxInstance))]
    public class VfxModule: Module
    {
        public override IEnumerator EnableModule(StatusManager manager, StatusEffect statusEffect, ModuleInstance moduleInstance)
        {
            VfxInstance vfxInstance = moduleInstance as VfxInstance;
            // Make sure the particle system stop action is set to destroy so it
            // automatically destroys itself when all particles die.
            // Give the vfx the name of the prefab so it can be queried later.
            GameObject vfxGameObject = Instantiate(vfxInstance.Prefab, manager.transform);
            vfxGameObject.name = vfxInstance.Prefab.name;
        
            if (vfxInstance.InstantiateAgainWhenAddingStacks)
                statusEffect.OnStackUpdate += (previous, stack) => OnStackUpdate(vfxInstance.Prefab, manager, statusEffect, previous, stack);
        
            yield break;
        }
        
        public override void DisableModule(StatusManager manager, StatusEffect statusEffect, ModuleInstance moduleInstance) 
        {
            VfxInstance vfxInstance = moduleInstance as VfxInstance;
            // If we are instantiating when adding stacks it has already been destroyed.
            if (vfxInstance.InstantiateAgainWhenAddingStacks)
                return;
            // This magic name finding system is horrible but it works. 
            // Unitask would do the enabling and disabling so much better 
            // since the reference to the GameObject can be kept as 
            // DisableModule is just when cancellation is called.
            Transform vfxTransform = manager.transform.Find(vfxInstance.Prefab.name);
            
            if (!vfxTransform)
                return;
            
            GameObject vfxGameObject = vfxTransform.gameObject;
            // Attempt to stop the particle system.
            vfxGameObject.GetComponent<ParticleSystem>().Stop();
            // Unset the parent so that if multiple effects are being removed 
            // it doesn't grab the same VFX twice.
            vfxTransform.SetParent(null);
        }
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}
