going mad with this, i habe decided to make my first rpg so i am using 3 states machines, one for the player, one for the enemy and one for the battle state
thing is my enemy will never debug an attack or do damage, no idea why but it looks like hes always waiting
here is my battle state machine:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class BattleState : MonoBehaviour {
public enum performAction
{
WAIT,
TAKEACTION,
PERFORMACTION
}
public performAction battleStates;
public List<HandleTurn> PerformList = new List<HandleTurn>();//lista de actores
public List<GameObject> HeroInGame = new List<GameObject>();//heroes en la escena
public List<GameObject> EnemiesInBattle = new List<GameObject>();//enemigos en la escena
public enum HeroGUi//acciones posibles del heroe
{
ACTIVATE,
WAITING,
INPUT1,
INPUT2,
DONE
}
public HeroGUi HeroInput;
public List<GameObject> HeroesToManage = new List<GameObject>();
private HandleTurn HeroChoice;
public GameObject enemyButton;
public Transform Spacer;
public GameObject AttackPanel;
public GameObject EnemySelectPanel;
public GameObject StatusPanel;
// Use this for initialization
void Start ()
{
battleStates = performAction.WAIT;
EnemiesInBattle.AddRange(GameObject.FindGameObjectsWithTag("Enemy"));
HeroInGame.AddRange(GameObject.FindGameObjectsWithTag("Hero"));
HeroInput = HeroGUi.ACTIVATE;
AttackPanel.SetActive(false);
EnemySelectPanel.SetActive(false);
StatusPanel.SetActive(false);
CreateEnemyButtons();
}
// Update is called once per frame
void Update ()
{
if (HeroSM.inBattle == true)
{
StatusPanel.SetActive(true);
switch (battleStates)
{
case (performAction.WAIT):
if (PerformList.Count > 0)//revisa la lista
{
battleStates = performAction.TAKEACTION;
}
break;
case (performAction.TAKEACTION):
GameObject performer = GameObject.Find(PerformList[0].Attacker);
if (PerformList[0].Side == "Enemy")
{
EnemySM ESM = performer.GetComponent<EnemySM>();
ESM.HeroToAttack = PerformList[0].TargetGO;
EnemySM.currentEnemyTurn = EnemySM.enemyTurn.ACTION;
HeroSM.currentHeroTurn = HeroSM.heroTurn.WAITING;
}
if (PerformList[0].Side == "Hero")
{
HeroSM HSM = performer.GetComponent<HeroSM>();
HSM.EnemyToAttack = PerformList[0].TargetGO;
HeroSM.currentHeroTurn = HeroSM.heroTurn.ACTION;
EnemySM.currentEnemyTurn = EnemySM.enemyTurn.WAITING;
}
battleStates = performAction.PERFORMACTION;
break;
case (performAction.PERFORMACTION):
//iddle
break;
}
//switch para el estado del heroe
switch (HeroInput)
{
case (HeroGUi.ACTIVATE):
if (HeroesToManage.Count > 0)
{
print("im active yo!");
HeroesToManage[0].transform.FindChild("Selector").gameObject.SetActive(true);//tomamos al primer heroe de la lista, hallamos el padre, pasamos al hijo llamado selector y seteamos el booleano
HeroChoice = new HandleTurn();
AttackPanel.SetActive(true);
HeroInput = HeroGUi.WAITING;
}
break;
case (HeroGUi.WAITING):
//iddle
break;
case (HeroGUi.DONE):
HeroInputDone();
break;
}
}
}
public void CollectActions(HandleTurn handleInput)
{
PerformList.Add(handleInput);
}
void CreateEnemyButtons ()
{
foreach(GameObject Enemy in EnemiesInBattle)
{
GameObject newButton = Instantiate(enemyButton) as GameObject;
EnemySelectButton button = newButton.GetComponent<EnemySelectButton>();
EnemySM curEnemy = Enemy.GetComponent<EnemySM>();
Text buttonText = newButton.transform.FindChild("Text").gameObject.GetComponent<Text>();
buttonText.text = curEnemy.Enemy.baseName;
button.EnemyPrefab = Enemy;
newButton.transform.SetParent(Spacer, false);
}
}
public void Input1()//attack button
{
HeroChoice.Attacker = HeroesToManage[0].name;
HeroChoice.AttackerGO = HeroesToManage[0]; // ya es un gameobject asi que no lo especificamos
HeroChoice.Side = "Hero";
AttackPanel.SetActive(false);
EnemySelectPanel.SetActive(true);
}
public void InputEnemySelection(GameObject choosenEnemy)//enemy selection
{
HeroChoice.TargetGO = choosenEnemy;
HeroInput = HeroGUi.DONE;
}
void HeroInputDone()
{
PerformList.Add(HeroChoice);
EnemySelectPanel.SetActive(false);
AttackPanel.SetActive(true);
HeroesToManage[0].transform.FindChild("Selector").gameObject.SetActive(false);
HeroesToManage.RemoveAt(0);
HeroInput = HeroGUi.ACTIVATE;
}
}
this is my enemy state machine:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class EnemySM : MonoBehaviour {
public EnemyStats Enemy;//creamos a enemigo desde la plantilla
private BattleState BS;
public bool actionStarted = false;
public GameObject Description;
public enum enemyTurn
{
PROCESSING,
CHOOSEACTION,
WAITING,
ACTION,
DEAD
}
public static enemyTurn currentEnemyTurn;
//para cambiar las barras
private float curHealth;
public GameObject HeroToAttack;
// Use this for initialization
void Start()
{
currentEnemyTurn = enemyTurn.WAITING;
BS = GameObject.Find("BM").GetComponent<BattleState>();
}
// Update is called once per frame
void Update()
{
/* if (HeroSM.currentHeroTurn != HeroSM.heroTurn.WAITING)
{
currentEnemyTurn = enemyTurn.WAITING;
}*/
if (GMScript.InBattle == true)
{
curHealth = Enemy.CurrentHp;
switch (currentEnemyTurn)
{
case (enemyTurn.PROCESSING):
print("enemy processing");
currentEnemyTurn = enemyTurn.CHOOSEACTION;
break;
case (enemyTurn.CHOOSEACTION):
print("enemy chooseaction");
ChooseAction();
currentEnemyTurn = enemyTurn.WAITING;
break;
case (enemyTurn.WAITING):
//idle state
/*if (HeroSM.currentHeroTurn == HeroSM.heroTurn.WAITING)
{
currentEnemyTurn = enemyTurn.PROCESSING;
}*/
break;
case (enemyTurn.ACTION):
print("enemy action");
StartCoroutine(TimeForAction());
break;
case (enemyTurn.DEAD):
break;
}
}
}
void ChooseAction()
{
HandleTurn myAttack = new HandleTurn();
myAttack.Attacker = Enemy.baseName;
myAttack.Side = "Enemy";
myAttack.AttackerGO = this.gameObject;
myAttack.TargetGO = BS.HeroInGame[Random.Range(0, BS.HeroInGame.Count)];
int num = Random.Range(0,Enemy.Attacks.Count);//se genra un numero aleatorio entre 0 y la cantidad de ataques
myAttack.chooseAttack = Enemy.Attacks[num];//usamos el numero para escoger el ataque
Debug.Log(this.gameObject.name + " has choosen " + myAttack.chooseAttack.attackName + " and did " +myAttack.chooseAttack.attackDamage + " damage!!!");
BS.CollectActions(myAttack);
}
private IEnumerator TimeForAction ()//controla variables atraves del tiempo
{
if(actionStarted == true)
{
yield break;
}
actionStarted = true;
//wait
//do damage
DoDamage();
//remove from bs list
BS.PerformList.RemoveAt(0);//remueve al objeto en 0, el siguiente sube transformando el 1 en 0
//continua removiendo hasta desaparecer todo
//reset bs to wait
BS.battleStates = BattleState.performAction.WAIT;
//al pasar a wait y saltar a takeaction los objetos vuelven a crearse repitiendo el ciclo
//end coroutine
actionStarted = false;
currentEnemyTurn = enemyTurn.PROCESSING;
}
void DoDamage()
{
float calcDamage = Enemy.Fue * BS.PerformList[0].chooseAttack.attackDamage;
HeroToAttack.GetComponent<HeroSM>().TakeDamage(calcDamage);
}
}
this is my hero state machine:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class HeroSM : MonoBehaviour {
private BattleState BS;
public static bool inBattle;
public partyStat hero;//creamos a hero desde la plantilla
public enum heroTurn
{
START,
PROCESSING,
ADDTOLIST,
WAITING,
SELECTING,
ACTION,
DEAD
}
public static heroTurn currentHeroTurn;
//para cambiar las barras
private float curHealth;
public Image healthB;
public Image chamaB;
public GameObject selector;
public GameObject EnemyToAttack;
//ienumerator
private bool actionStarted;
// Use this for initialization
void Start ()
{
selector.SetActive(false);
BS = GameObject.Find("BM").GetComponent<BattleState>();
currentHeroTurn = heroTurn.START;
}
// Update is called once per frame
void Update ()
{
/*if (EnemySM.currentEnemyTurn != EnemySM.enemyTurn.WAITING)
{
currentHeroTurn = heroTurn.WAITING;
}*/
//creamos el movimiento de las barras de hp y chama
chamaB.transform.localScale = new Vector3(hero.CurrentChama / 100, this.transform.localScale.y, this.transform.localScale.z);
healthB.transform.localScale = new Vector3(hero.CurrentHp / 100, this.transform.localScale.y, this.transform.localScale.z);
curHealth = hero.CurrentHp;
if (GMScript.InBattle == true)
{
switch (currentHeroTurn)
{
case (heroTurn.START):
currentHeroTurn = heroTurn.PROCESSING;
break;
case (heroTurn.PROCESSING):
//inBattle = true;
//print("hero processing");
UpgradeBar();
break;
case (heroTurn.ADDTOLIST):
//print("hero addtolist");
BS.HeroesToManage.Add(this.gameObject);
currentHeroTurn = heroTurn.WAITING;
break;
case (heroTurn.WAITING):
//print("hero waiting");
/* if (EnemySM.currentEnemyTurn == EnemySM.enemyTurn.WAITING)
{
currentHeroTurn = heroTurn.START;
}*/
//idle
break;
case (heroTurn.ACTION):
//print("hero action");
StartCoroutine(TimeForAction());
break;
case (heroTurn.DEAD):
break;
}
}
}
void UpgradeBar()
{
currentHeroTurn = heroTurn.ADDTOLIST;
}
private IEnumerator TimeForAction()//controla variables atraves del tiempo
{
if (actionStarted == true)
{
yield break;
}
actionStarted = true;
//wait
//do damage
//remove from bs list
BS.PerformList.RemoveAt(0);//remueve al objeto en 0, el siguiente sube transformando el 1 en 0
//continua removiendo hasta desaparecer todo
//reset bs to wait
BS.battleStates = BattleState.performAction.WAIT;
//al pasar a wait y saltar a takeaction los objetos vuelven a crearse repitiendo el ciclo
//end coroutine
actionStarted = false;
currentHeroTurn = heroTurn.PROCESSING;
}
public void TakeDamage(float getDamageAmount)
{
hero.CurrentHp -= getDamageAmount;
if (hero.CurrentHp <= 0)
{
currentHeroTurn = heroTurn.DEAD;
}
}
}
habe been with this for 2 days now, would love any help