These are the relevant lines:
public IEnumerator BattleStart(string toucher, string touched, Unitdetails playerStatsScript, Unitdetails enemyStatsScript)
{
//Accumulating values
playerStats = playerStatsScript;
enemyStats = enemyStatsScript;
Debug.Log(playerStats.unitName + " vs " + enemyStats.unitName);
//setting up battle and GUI
battleState = whoseTurn.Start;
DialogueText.text = "You encountered " + enemyStats.unitName + ".";
World.SetActive(false);
Battle.SetActive(true);
//Adding the player and enemy, placed as UI.
GameObject playerPrefab = Instantiate(NametoObject[playerStatsScript.unitName], playerPos, Quaternion.identity);
GameObject enemyPrefab = Instantiate(NametoObject[enemyStatsScript.unitName], enemyPos, Quaternion.identity);
Debug.Log("This area of code reached. StartToPlayer: " + TimerManager.StartToPlayer);
yield return new WaitForSeconds(TimerManager.StartToPlayer);
//note that we need this WaitForSeconds to exist. We are making this a regular method to focus on other errors.
StartCoroutine(PlayerTurn());
Debug.Log("This area of code reached.");
}
Explanations: I am creating a (2D-based) turn-based combat game, and the lines of code written allows me to have multiple types of enemies, so, you will see that I have the parameters, the first two just to get the names of the player and the enemy - this script was designed as if there are many players, even though there is only one, don't change that please.
If you observed the code, I took a little bit of inspiration from Brackeys' tutorial, although I did not directly copy it, they have common elements.
Here is some useful information to know about this code:
- Unitdetails is a script, mostly contains only variables, but doesn't really have a function. It is held by entities in the world (by the way, the world and battle are in the same scene).
- World is a parent gameObject holding all the elements in the world.
- Battle is a parent gameObject holding all the elements in the battle.
- battleState - mostly irrelevant and was never really used, but I don't think anything is wrong with it.
- NametoObject is a dictionary, and is (string, gameObject). The player and enemies have unit names, which the battle system script translates into prefab gameObjects that will be spawned.
- TimerManager is a script that holds variables - and that's pretty much all it does. This is to keep my codes organized, and so that I can modify it in the Unity editor, so if I feel like the text dialogue is too long or too short, I can modify it accordingly.
TimerManager.StartToPlayer is a float, and I assigned the value "2" to it (The Debug.Log confirms that it is working as expected)
However, when I finally reach yield return new WaitForSeconds(TimerManager.StartToPlayer), it gets disastrous. The codes
don't get executed.
From what I know, all these codes are correct. There might be something wrong with the Unity editor. I have asked ChatGPT for help several times, and it wasn't so reliable, because it kept giving me "solutions" that I've already done.
When I removed yield return new, only then the codes started to run.
The reason why I added the wait is to give the player some time to read the dialogue, instead of hopping straight into the player's turn.
Important things to note: -The game didn't crash, and Time.timeScale was 1. If you think those two were the problem, then unfortunately you are wrong. -I created the project twice, having a similar script, and the problem was replicated - so definitely not an editor problem. -Definitely not the nested coroutine's fault. When I removed the StartCoroutine(PlayerTurn()); code, it still worked just like it should. -The gameObject that holds this script never gets deactivated or interrupted. Like I said, this coroutine just stops after yield return new WaitForSeconds(TimerManager.StartToPlayer); - confirmed with Debug.Log and others
And mysteriously, when I remove
Battle.SetActive(true);
//Adding the player and enemy, placed as UI.
GameObject playerPrefab = Instantiate(NametoObject[playerStatsScript.unitName], playerPos, Quaternion.identity);
GameObject enemyPrefab = Instantiate(NametoObject[enemyStatsScript.unitName], enemyPos, Quaternion.identity);```
NOTE THAT BATTLESYSTEM IS NOT PART OF THE DEACTIVATED GAMEOBJECTS
the WaitForSeconds works properly again.
BattleStartcalled with aStartCoroutine()?