# ModuleInstance

<figure><picture><source srcset="https://content.gitbook.com/content/sszhq0oU5VbBUcBr6f13/blobs/oVyz6X5qIy5d9mP2MiKw/d_ModuleInstance%20Icon.png" media="(prefers-color-scheme: dark)"><img src="https://content.gitbook.com/content/sszhq0oU5VbBUcBr6f13/blobs/dKIk882wJMWst3a8wexq/ModuleInstance%20Icon.png" alt="" width="188"></picture><figcaption></figcaption></figure>

### Description

[ModuleInstances](https://maraudical.gitbook.io/status-effect-framework/type-specifics/scriptable-objects/moduleinstance) can be attached to [Modules](https://maraudical.gitbook.io/status-effect-framework/type-specifics/scriptable-objects/module) so that unique data can be selected per [StatusEffectData](https://maraudical.gitbook.io/status-effect-framework/type-specifics/scriptable-objects/statuseffectdata). Create one by simply inheriting from the [ModuleInstance](https://maraudical.gitbook.io/status-effect-framework/type-specifics/scriptable-objects/moduleinstance) 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](https://maraudical.gitbook.io/status-effect-framework/type-specifics/scriptable-objects/module) and [ModuleInstances](https://maraudical.gitbook.io/status-effect-framework/type-specifics/scriptable-objects/moduleinstance).
{% endhint %}

{% hint style="warning" %}
You do not need to add these to the create menu! As long as it is attached to a [Module](https://maraudical.gitbook.io/status-effect-framework/type-specifics/scriptable-objects/module) 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](https://maraudical.gitbook.io/status-effect-framework/type-specifics/scriptable-objects/module) for each prefab that you need, just add the variables you need in the [ModuleInstance](https://maraudical.gitbook.io/status-effect-framework/type-specifics/scriptable-objects/moduleinstance) and attach it to the [Module](https://maraudical.gitbook.io/status-effect-framework/type-specifics/scriptable-objects/module) using the `[AttachModuleInstance]` attribute.

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

<figure><img src="https://365310699-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fsszhq0oU5VbBUcBr6f13%2Fuploads%2Ff1Kd1rjxoliUiMVk6Hre%2FModules-4.0.0.gif?alt=media&#x26;token=e0c09223-00f7-47e9-b443-150e1a0f2b52" 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 %}
