I wouldn’t say that’s the common approach, that’s state data, I’d want that under pretty tight control and I’d also want to decouple how that data is handled to keep as much flexibility as possible - somewhat paradoxically opposing views I know but meh, this has worked well for me in the past.
First I’d abstract the handler methods as Actions (anon delegates) so you don’t have to update that ungodly switch every time you add a new feature, and with systems like this you often want to change how something is handled at runtime - this makes catering for edge cases in your game design sooooo much easier.
I’d also not want to expose a public list of state sensitive values like that, you’re just asking for debugging nightmare. Instead use an indexer property so you at least have some control over how those values are accessed and changed.
Her’s how I’d do this in C#, don’t think this is possible with UnityScript (it always seemed really limited to me)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class TestScript : MonoBehaviour {
public enum Effect {damage, armor, heal, poison, curse, end}
private Dictionary<Effect, int> effects;
private Dictionary<Effect, System.Action<int>> effectHandlers = new Dictionary<Effect, System.Action<int>>();
public int this[Effect effect] {
get { return effects[effect]; }
set { effects[effect] = value; }
}
public void Awake()
{
effects = new Dictionary<Effect, int>();
effectHandlers = new Dictionary<Effect, System.Action<int>>();
foreach (Effect effect in System.Enum.GetValues(typeof(Effect)))
{
effects[effect] = 0;
effectHandlers[effect] = DefaultHandler;
}
SetEffectHandler(Effect.damage, OnDamageExample);
this[Effect.damage] = 10;
UpdateState();
}
public void SetEffectHandler(Effect effect, System.Action<int> handler)
{
// No null checks, I like to maintain option of setting null handlers, null case accounted for by
// UpdateState - or you could use an extention invoke method or something.
effectHandlers[effect] = handler;
}
private void DefaultHandler(int value)
{
throw new System.NotImplementedException("No handler has been implimented for this effect!");
}
public void UpdateState()
{
foreach (var effectKVP in effects)
{
if (effectKVP.Value > 0)
{
System.Action<int> handler;
if (effectHandlers.TryGetValue(effectKVP.Key, out handler))
{
if (handler != null)
{
handler(effectKVP.Value);
}
else
{
Debug.LogWarning(effectKVP.Key.ToString() + " has a null Handler");
}
}
else
{
Debug.LogError(effectKVP.Key.ToString() + " has no Handler");
}
}
}
}
private void OnDamageExample(int value)
{
Debug.Log("Applying " + value + " damage to self....");
// apply damage to health or something...
// Set damage to 0...
effects[Effect.damage] = 0;
}
}
Should be fairly trivial to write a filter for UpdateState, I’d probably try using bitflags for the enum as that would produce cleaner code using the filter version of UpdateState:
Or just use strings Linq and not use an enum at all, but I hate using strings to do any kind of data access - you’re basically throwing away the main benefit of type safety for (usually) no good reason.