Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Status effects and immunity

Discussion in 'Scripting' started by FanOfLearning, Jul 15, 2022.

  1. FanOfLearning

    FanOfLearning

    Joined:
    Oct 22, 2021
    Posts:
    5
    Hello.
    I'm trying to make status effect system. Here's my simplified code:
    Code (CSharp):
    1. public abstract class StatusEffect : MonoBehaviour
    2. {
    3.     private IEffectable target = null;
    4.     private float duration = 0.0f;
    5.     ...
    6. }
    Code (CSharp):
    1. public enum StatusEffectTypes { Poison, Stun, Regeneration, ... }
    Code (CSharp):
    1. public interface IEffectable
    2. {
    3.     void ApplyStatusEffect(StatusEffectTypes effectType);
    4.     void RemoveStatusEffect(StatusEffectTypes effectType);
    5. }
    For example, poison status effect looks like this:
    Code (CSharp):
    1. public class Poison : StatusEffect
    2. {
    3.     private void Update()
    4.     {
    5.         // if target has health, do damage over time to target  <---- problem
    6.     }
    7. }
    Now, to my unit prefabs I add component:
    Code (CSharp):
    1.  public class StatusEffectSystem : IEffectable
    2. {
    3.     private Dictionary<StatusEffectTypes, StatusEffect> effects;
    4.  
    5.     void ApplyStatusEffect(StatusEffectTypes effectType)
    6.     {
    7.         GameObject prefab = dataManager.GetStatusEffectPrefab(effectType);
    8.         Instantiate(prefab, ...);
    9.         ...
    10.     }
    11.     ...
    12. }
    13.  
    Everything works fine, but I have a problem with some units having immunity to some status effects. For example, some my units can't walk, so they shouldn't be affected by Slow or Haste status effects. For now, if target is effectable, I create status effect prefab, and in it's code check if it should work. If not, it just do nothing and is removed after duration. But I want to not instantiate it if target can't be affected. I don't understand where to put requirements check. Status effects have different requirements to work (does target have health, can move, can shoot etc). But how can I check it without instantiating status effect prefab first?
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Well firstly, what's the reasoning behind making every status effect a MonoBehaviour?

    Secondly, you can actually run code on prefabs before instantiating them, so if you created a CanAffectTarget() boolean check inside your StatusEffect MB, you could evaluate if it'll work on a target before cloning it:

    Code (csharp):
    1.  
    2. void ApplyStatusEffect(StatusEffectTypes effectType)
    3. {
    4.    StatusEffect effectPrefab = dataManager.GetStatusEffectPrefab(effectType);
    5.  
    6.    if(effectPrefab.CanAffectTarget(this.gameObject) == true)
    7.    {
    8.        StatusEffect effectClone = Instantiate<StatusEffect>(effectPrefab);
    9.  
    10.        // attach it or whatever
    11.        effectClone.Attach(this.gameObject);
    12.    }
    13. }
    14.  
     
    FanOfLearning and Kurt-Dekker like this.
  3. FanOfLearning

    FanOfLearning

    Joined:
    Oct 22, 2021
    Posts:
    5
    Every status effect in my game has visual representation (sprites or particles, like green cloud on unit if he is poisoned). So I thought:
    1. It would be better to have everything in one place, since when applying status effect I have to create objects anyway.
    2. It would be easier to test in editor, as I can pause game and check status effects and values of variables at any moment.
    3. This way I can easily add StatusEffectData (scriptable objects, which contains info like name and description of status effects) to prefabs. Actually, I often use scriptable objects as data containers, but I don't know a good way to reference them from non-MonoBehaviour class.

    Do you think these reasons are enough? I don't have much experiance in game programming, so i appreciate any advice.

    Oh, I didn't know that. Thank you, it solves my problem.
     
    Last edited: Jul 19, 2022
    GroZZleR likes this.