This is a game i made for a solo school assignment in 2018. I made all the code and assets by myself and this was also the first time I made my own 3d models.
I made this with C# and Unity.
Gameplay
This is a two player, turn-based strategy game. The goal is to defeat the opponents Ruler, which can be done by purchasing units.
Both players get 500 gold with which they can purchase troops.
You can purchase different Rarities of units; Normal, Magic and Rare.
Magic and Rare units will receive Traits which will put them apart from the Normal units. Magic units receive a single trait while Rare units receive two.
A random unit is chosen when purchasing one.
The game has 5 different units.
- Ruler: Weak unit, if he dies it’s game over.
- Acolyte: Magical unit, can cast fireball. Has high INT and RES.
- Rogue: Precision unit. Has high PRC and AGI. Makes him very hard to hit.
- Esquire: Footsoldier unit. Has decent stats all around.
- Brute: Rampage unit. Has high STR and HP, but is very easy to hit.
The game will keep going until either of the Rulers is defeated.
Because of a lack of time I wasn’t able to implement damage numbers or misses and such, which is why you can’t see when the units keep missing the Rogues
Code
During this project I made a few generator classes for units, maps and traits. Making and testing those generators was a lot of fun.
Generator Code
public class CharacterGenerator : MonoBehaviour {
public TurnManager TurnManager;
public UnitUIManager UnitUiManager;
public GameObject[] RedCharaPrefabs; //0 Acolyte || 1 Esquire || 2 Brute || 3 Rogue || 4 Ruler
public GameObject[] BlueCharaPrefabs; //0 Acolyte || 1 Esquire || 2 Brute || 3 Rogue || 4 Ruler
public GameObject[] BasePrefabs; //0 Normal || 1 Magic || 2 Rare
public GameObject[] AttackPrefabs; //0 STR || 1 INT || 2 PRC
private NameGenerator _nameGen;
private TraitGenerator _traitGen;
private StatsGenerator _statsGen;
private SkillGenerator _skillGen;
private Character _character;
public void Start() {
_nameGen = GetComponent();
_traitGen = GetComponent();
_statsGen = GetComponent();
_skillGen = GetComponent();
}
public GameObject Generate(Rarity rarity, Transform parent) {
GameObject go = new GameObject();
go.transform.SetParent(parent, false);
go.AddComponent();
SetupCharacter(rarity, go);
Instantiate(BasePrefabs[(int) _character.Rarity], go.transform);
for (int i = 0; i < (int) _character.Rarity; i++) {
_character.Traits.Add(_traitGen.GetTrait(go.transform));
}
InstantiateModel(go, TurnManager.CurrentTeam);
AddAttack(go);
_character.Stats = _statsGen.AlterWithTraits(_statsGen.GetStats(_character.Type), _character);
go.name = string.Format("[{0}] {1} {2}", _character.Rarity, _character.Name, _character.Type);
return go;
}
public GameObject Generate(CharacterType type, Rarity rarity, Player owner, Transform parent) {
GameObject go = new GameObject();
go.transform.SetParent(parent, false);
go.AddComponent();
SetupCharacter(rarity, go, owner);
Instantiate(BasePrefabs[(int) _character.Rarity], go.transform);
for (int i = 0; i < (int) _character.Rarity; i++) {
_character.Traits.Add(_traitGen.GetTrait(go.transform));
}
InstantiateModel(go, owner.Color, type);
AddAttack(go);
_character.Stats = _statsGen.AlterWithTraits(_statsGen.GetStats(_character.Type), _character);
go.name = string.Format("[{0}] {1} {2}", _character.Rarity, _character.Name, _character.Type);
return go;
}
private void SetupCharacter(Rarity rarity, GameObject go, Player owner) {
_character = go.GetComponent();
_character.Name = _nameGen.GetName();
_character.Rarity = rarity;
_character.MoveType = MovementType.Straight;
_character.Ownable = go.AddComponent();
if (owner == null) {
_character.Ownable.Initialize(TurnManager.CurrentPlayer);
}
else {
_character.Ownable.Initialize(owner);
}
_character.UnitUI = UnitUiManager;
_character.TurnManager = TurnManager;
}
private void SetupCharacter(Rarity rarity, GameObject go) {
SetupCharacter(rarity, go, null);
}
private void InstantiateModel(GameObject go, Player.TeamColor color) {
int charaRoll = Random.Range(0, RedCharaPrefabs.Length - 1);
_character.Type = (CharacterType) charaRoll;
_character.Skills = _skillGen.GetSkills(_character.Type);
if (color == Player.TeamColor.Red) {
Instantiate(RedCharaPrefabs[charaRoll], go.transform);
}
else if (color == Player.TeamColor.Blue) {
Instantiate(BlueCharaPrefabs[charaRoll], go.transform);
}
}
private void InstantiateModel(GameObject go, Player.TeamColor color, CharacterType type) {
_character.Type = type;
_character.Skills = _skillGen.GetSkills(_character.Type);
if (color == Player.TeamColor.Red) {
Instantiate(RedCharaPrefabs[(int) type], go.transform);
}
else if (color == Player.TeamColor.Blue) {
Instantiate(BlueCharaPrefabs[(int) type], go.transform);
}
}
private void AddAttack(GameObject go) {
GameObject attack = null;
switch (_character.Type) {
case CharacterType.Acolyte:
attack = Instantiate(AttackPrefabs[1]);
break;
case CharacterType.Esquire:
attack = Instantiate(AttackPrefabs[0]);
break;
case CharacterType.Brute:
attack = Instantiate(AttackPrefabs[0]);
break;
case CharacterType.Rogue:
attack = Instantiate(AttackPrefabs[2]);
break;
case CharacterType.Ruler:
attack = Instantiate(AttackPrefabs[0]);
break;
}
if (attack == null) throw new Exception("Failed to generate attack");
attack.transform.SetParent(go.transform, false);
_character.Attack = attack.GetComponent();
}
}
Research Design
Documenting your choices was important during this assignment. You can download this research here