- Home /
Update not behaving like it should with enum states
Hi! I'm making a turn-based RPG and there is this script of the action choices where the char options should be. My problem is: if the player choose one action, the next one should have the first one as the pre-selected choice in the box, but this is not happening. For example, if the char called "X" selects the third option, which is use potion, the next char, let's call "Y", should have the first option as the pre-selected choice, "Attack", regardless of what happened in the previous turn. Just works when the previous turn comes from an enemy. Anyway, a - not so - little bit of my codes: First, I have these states of the battle enumerated by an enum:
//States of the Battle
[HideInInspector]
public enum ActionBoxStates
{
BEGINTURN,
MAIN,
BLOCKED,
INFO
}
[HideInInspector] public static ActionBoxStates currentState;
The "BEGINTURN" state is basically where the choice '1' will be pre-selected. "MAIN" is where the player will navigate through choices, like attack, use skills, use potion, etc. So, my Update function is like that:
void Update () {
Debug.Log("ActionBox: " + currentState);
//The start point in every new turn
if(currentState == ActionBoxStates.BEGINTURN)
{
currentState = ActionBoxStates.MAIN;
selectedOption = 1;
}
if (BattleManagerScript.BattleStates.PLAYERCHOICE == BattleManagerScript.currentState)
{
if(ActionBoxStates.MAIN == currentState)
{
//SELECT SOMETHING
if (Input.GetKeyDown(KeyCode.Return))
{
if (selectedOption == 1)
{
//I did a lot of stuff here not related to the enum, so I'm cleaning these codes for the question purpose.
currentState = ActionBoxStates.BLOCKED;
BattleManagerScript.currentState = BattleManagerScript.BattleStates.ENDTURNCONFIRMATION;
BattleManagerScript.NextTurn();
}
if (selectedOption == 3)
{
//All the same here =)
currentState = ActionBoxStates.BLOCKED;
BattleManagerScript.currentState = BattleManagerScript.BattleStates.ENDTURNCONFIRMATION;
BattleManagerScript.NextTurn();
}
}
}
//END TURN
if (Input.GetKeyDown(KeyCode.Space))
{
currentState = ActionBoxStates.BLOCKED;
BattleManagerScript.currentState = BattleManagerScript.BattleStates.ENDTURNCONFIRMATION;
confirmationBox.SetActive(true);
}
}
if (ActionBoxStates.BLOCKED == currentState)
{
fade = true;
}
else
{
fade = false;
VerifyMovement();
}
FadePanel(fade);
}
The "BattleManagerScript" is where the turns are organized and it's "NextTurn" function simple does that:
public static void NextTurn(){
ReOrderList();
NextBattleState();
ActionBoxManagerScript.ResetActions();
TimelineManagerScript.ArrangeTimeline();
}
"Next Battle State" simple organize the BattleManager's enum by "PLAYERCHOICE" and "ENEMYCHOICE" by their tags. I guess there's nothing wrong with it, so I won't post the code here. The "ResetActions" of my main script here is doing this:
public static void ResetActions()
{
if(BattleManagerScript.BattleStates.PLAYERCHOICE == BattleManagerScript.currentState)
{
currentState = ActionBoxStates.BEGINTURN;
anim.Rebind(); //will put the chosen option's arrow in the first choice
//I'm using the Debug function here and is showing the state BEGINTURN in currentState, so this code is running and the enum state is changing
Debug.Log("Restart turn with the state: " + currentState);
}
else
{
currentState = ActionBoxStates.BLOCKED;
//When it's an enemy turn, the ActionBox will be blocked, and this is also running properly because in enemy's turn the actions are locked.
}
}
Well, if the enum state is changing in ResetActions(), and it absolutely is, why on Update it doesn't Debug located in Update clearly shows that it doesn't change, it's already in "MAIN" state. Everything occurs as it should when the turn changes from one enemy to a player's char. The "currentTurn" goes to "BEGINTURN" state like it should when the enemy finishes it's turn, but when it changes to one char to another char, the problem appears.
PS: I tend to overexplain, sorry for it and for my rusty english, it' not my mother tongue.
Answer by Liaram · Jul 24, 2018 at 03:09 AM
I'm not sure anyone can debug the code based on the snippets here. But since it's a turn-based game I wouldn't change the states inside the update loop since it's not the kind of thing that has to happen 60 times a second. It's more of a risk than a benefit doing it in update since one typo could send the state flip flopping at an alarming rate. Also not sure if you assign the states using integers at some point. If you do I'd recommend declaring the enum like this to make sure the values never change:
public enum ActionBoxStates
{
BEGINTURN = 0,
MAIN = 1,
BLOCKED = 2,
INFO = 3,
}
Unity stores the enum values as integers for every public variable so moving them around could mess things up. By adding the numbers the stored values will keep on matching. Using [HideInInspector] would not change that. Only [NonSerialized] clears the stored values. Sorry I couldn't be of more help. Happy debugging :-)
Hi, thanks for the reply! I didn't used integers to assign the states and I guess I won't need to change their values, so I guess I won't need to use your example of declaration. I liked what you said about not changing the states inside the update (I really don't need things changing 60x per second), but I'm not really sure how could I change my code to a less risky version. Anyway, I'll try, if I find a solution I'll share here! =)
Just updating: I solved the mystery! I removed the "BEGINTURN":
//States of the Battle
[HideInInspector]
public enum ActionBoxStates
{
$$anonymous$$AIN,
BLOC$$anonymous$$ED,
INFO
}
[HideInInspector] public static ActionBoxStates currentState;
And I made the "selectedOption" a static variable. Doing this, I could change it directly on the function "ResetActions" like this, eli$$anonymous$$ating the need of changing stuff on update (which now only listen if the player pressed something and if is his turn:
public static void ResetActions()
{
if(Battle$$anonymous$$anagerScript.BattleStates.PLAYERCHOICE == Battle$$anonymous$$anagerScript.currentState)
{
currentState = ActionBoxStates.$$anonymous$$AIN;
anim.Rebind();
selectedOption = 1;
else
{
currentState = ActionBoxStates.BLOC$$anonymous$$ED;
}
}
Well, it looks like a simple change, but doing this I had to change a lot in my code, since "selectedOption" was used in many non-static functions. Either way, I achieved the solution and I can feel that my code is more clean now. I'm marking your answer as the acceptable one since you opened the doors for me to get in the answer and was very helpful. I believe it will help other if they get themselves in the same difficult. BTW, it was a happy debugging hehe. Cheers! :D