I am not that smart coder but maybe this can give you some hint for your system, this is just a simple example on how you could approach it
first a file that handle some data
// classe type
public enum Guild
{
Shaman,
Brute,
Assassin,
Archer,
Mage
}
// action
public enum Action
{
Attack,
Defend,
RunAway,
DanceSamba
}
public struct CharacterData
{
public Guild charGuild;
public Action charAction;
public CharacterData(Guild charGuild, Action charAction)
{
this.charGuild = charGuild;
this.charAction = charAction;
}
}
then have a base component to handle your characters ( be it one or many )
using UnityEngine;
using System.Collections;
public class CharacterBase : MonoBehaviour
{
// just for test purpose
public Guild currentGuild;
public Action currentAction;
public delegate void UseSkillEventHandler(CharacterData data);
public event UseSkillEventHandler OnUseSkillEvent;
private CharacterData characterData;
void Awake()
{
ChangeData(currentGuild, currentAction);
}
//just for test
void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
ChangeData(currentGuild, currentAction);
UseSkill();
}
}
//call this from some logic script
public void ChangeData(Guild guild, Action action)
{
characterData = new CharacterData(guild, action);
}
public void UseSkill()
{
if(OnUseSkillEvent != null)
OnUseSkillEvent(characterData);
}
}
then your skill action , be it all in one script or separate it doesn’t matter
using UnityEngine;
using System.Collections;
public class ShamanAction : MonoBehaviour
{
private Guild thisGuild = Guild.Shaman;
void Start()
{
// considering character base in on the same GameObject
GetComponent<CharacterBase>().OnUseSkillEvent += UseSkill;
}
void OnDisable()
{
GetComponent<CharacterBase>().OnUseSkillEvent -= UseSkill;
}
void UseSkill(CharacterData data)
{
if(thisGuild != data.charGuild)
return;
switch(data.charAction)
{
case Action.Attack:
Attack();
break;
case Action.Defend:
Defend();
break;
case Action.RunAway:
RunAway();
break;
case Action.DanceSamba:
DanceSamba();
break;
}
}
void Attack()
{
Debug.Log(GetType().ToString() + " Attack");
}
void Defend()
{
Debug.Log(GetType().ToString() + " Defend");
}
void RunAway()
{
Debug.Log(GetType().ToString() + " RunAway");
}
void DanceSamba()
{
Debug.Log(GetType().ToString() + " DanceSamba");
}
}
same you can define a class archer too
using UnityEngine;
using System.Collections;
public class ArcherAction : MonoBehaviour
{
private Guild thisGuild = Guild.Archer;
void Start()
{
// considering character base in on the same GameObject
GetComponent<CharacterBase>().OnUseSkillEvent += UseSkill;
}
void OnDisable()
{
GetComponent<CharacterBase>().OnUseSkillEvent -= UseSkill;
}
void UseSkill(CharacterData data)
{
if(thisGuild != data.charGuild)
return;
switch(data.charAction)
{
case Action.Attack:
Attack();
break;
case Action.Defend:
Defend();
break;
case Action.RunAway:
RunAway();
break;
case Action.DanceSamba:
DanceSamba();
break;
}
}
void Attack()
{
Debug.Log(GetType().ToString() + " Attack");
}
void Defend()
{
Debug.Log(GetType().ToString() + " Defend");
}
void RunAway()
{
Debug.Log(GetType().ToString() + " RunAway");
}
void DanceSamba()
{
Debug.Log(GetType().ToString() + " DanceSamba");
}
}
well that just an example how you could go about it using event in C# , that way you don’t care about get listing of your class , but do care about what you send to who
as i say that just something you can tinker with…
hope that help 
try it put the character base and archer , shaman on same GO and test out…
after regarding how you want architecture your stuff and how you want call that well it may be more or less appropriate…