# 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-effect-framework/type-specifics/scriptable-objects/moduleinstance.md) can be attached to [Modules](/status-effect-framework/type-specifics/scriptable-objects/module.md) so that unique data can be selected per [StatusEffectData](/status-effect-framework/type-specifics/scriptable-objects/statuseffectdata.md). Create one by simply inheriting from the [ModuleInstance](/status-effect-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-effect-framework/type-specifics/scriptable-objects/module.md) and [ModuleInstances](/status-effect-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-effect-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-effect-framework/type-specifics/scriptable-objects/module.md) for each prefab that you need, just add the variables you need in the [ModuleInstance](/status-effect-framework/type-specifics/scriptable-objects/moduleinstance.md) and attach it to the [Module](/status-effect-framework/type-specifics/scriptable-objects/module.md) using the `[AttachModuleInstance]` attribute.

Now, every time you add a module to a [StatusEffectData](/status-effect-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-effect-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-effect-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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://maraudical.gitbook.io/status-effect-framework/type-specifics/scriptable-objects/moduleinstance.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
