I’m just trying to have the text wait a second before the enemy does it’s action because right now it doesn’t show the text Player attacked because the Enemy attacked text happen so quickly.
2843703–207604–Battle.cs (2.81 KB)
I’m just trying to have the text wait a second before the enemy does it’s action because right now it doesn’t show the text Player attacked because the Enemy attacked text happen so quickly.
2843703–207604–Battle.cs (2.81 KB)
I do not understand your code, a bit messy, please try not to code that way. and do not call Update() yourself. you have code that call TimeInvoke in Update and in have code to call Update in TimeInvoke, thats infinite loop. VERY DANGEROUS.
I am suggesting you to learn coroutine.
StartCoroutine(fct_EnemyTurn());
IEnumerator fct_EnemyTurn() {
//show the text you want
yield return new WaitForSeconds(1);
strTurn = "Enemy";
}
or maybe u can try to explain a bit how your game supposed to work.
I’ve tried that too. I was messing with Coroutine yesterday with no avail. Sorry about the messyness. my first program ever written.
2843741–207612–Battle.cs (2.63 KB)
updated script ^
How I’d like it to work would be
void Update(){
if ( playerTurn == false) // enemy's turn
{
// move action down to Vector3(4.5, 6.1, 0)
StartCoroutine(Pause());
// pause for number of seconds before the rest is exicuted so it flows a little better.
number = Random.Range(1,100);
if (number >= 100) //so the enemy always attacks
{
player.HP = player.HP- (enemy.str - player.def); // take damage
PHP.text = "" + player.HP; // reads now HP number
playerTurn = true; //goes back to player's turn
IEnumerator Pause(){
yield return new WaitForSeconds(3);
}
I think you have misunderstood the usage of the coroutine. Its not like a function. If you start a coroutine, it will perform the coroutine until a yield, then it will return back to your main code, but your main code will transfer the execution back to the coroutine later until the coroutine finish.
Example:
Awake (){
StartCoroutine(fct_StartRoundTimer());
}
Update() {
//other code
}
IEnumerator fct_StartRoundTimer(){
int intDuration = 60;
while (intDuration > 0) {
yield return new WaitForSeconds(1f);
Debug.Log(intDuration);
intDuration -= 1;
}
fct_RoundFinish();
}
Coroutine is like threading, but the different is it does not start another thread, but u have to tell the coroutine when to return back to the main code, code execution will pass back into the coroutine every frame, but the waitforsecond will instantly give the control back to the main code until 1 second has expired.
I think you should explain what your game do.
The game works like the old earthbound game. action text in the corner will say what just happened i.e. “player attacked, Enemy attacked ect…”) the HP text lowers as the Enemy generates a random number that allows it to attack (for now that’s it got to try to do more advance stuff later). Then enemy object disappears once it’s HP get’s <= 0. the action text in the corner starts off by reading Fight, and when you press A (attack) then the enemy’s health goes down, and the action bar reads “player attacked” then the Random number between 1 and 100 happens and the enemy attack. The action bar then reads “enemy attacked” but the action happens so quickly you don’t get a chance to ever read that you( the player) have attacked.
The following is the full functioning code, copy paste this code into another c# script, dont dump all your codes, just temporary disable them, then drag the script into 1 game object. Its not perfectly what you want, but it should help you understand the logic.
using UnityEngine;
using System.Collections;
public class TestCo : MonoBehaviour {
Coroutine coPlayer;
Coroutine coEnemy;
int intEnemyHP = 10;
int intPlayerHP = 5;
string strPlayerAction = "";
void Start () {
coPlayer = StartCoroutine(fct_PlayerTurn());
}
IEnumerator fct_PlayerTurn() {
Debug.Log("Player Turn");
strPlayerAction = "";
while (strPlayerAction == "") {
yield return null;
}
yield return new WaitForSeconds(1);
if (fct_CheckVictory() == false ) coEnemy = StartCoroutine(fct_EnemyTurn());
}
IEnumerator fct_EnemyTurn() {
Debug.Log("Enemy Turn");
intPlayerHP -= 2;
yield return new WaitForSeconds(1);
if (fct_CheckVictory() == false) coPlayer = StartCoroutine(fct_PlayerTurn());
}
IEnumerator fct_PlayerLose() {
Debug.Log("You LOSE.");
yield return new WaitForSeconds(1);
Debug.Log("wahhahahaha.");
yield return new WaitForSeconds(1);
Debug.Log("GAME OVER");
yield return new WaitForSeconds(1);
//go back to menu
}
IEnumerator fct_PlayerWon() {
Debug.Log("You Won.");
//play music
yield return new WaitForSeconds(1);
//load next scene
}
bool fct_CheckVictory() {
if (intPlayerHP <= 0) {
fct_StopGame();
StartCoroutine(fct_PlayerLose());
return true;
} else if (intEnemyHP <= 0) {
fct_StopGame();
StartCoroutine(fct_PlayerWon());
return true;
}
return false;
}
void fct_StopGame() {
StopCoroutine(coPlayer);
StopCoroutine(coEnemy);
}
void Update() {
//display their hp
}
void OnGUI () {
GUI.Label(new Rect(0, 0, 100, 100), "Player HP :" + intPlayerHP.ToString());
GUI.Label(new Rect(0, 50, 100, 100), "Enemy HP :" + intEnemyHP.ToString());
if (strPlayerAction == "") { //required action
if (GUI.Button(new Rect(0, 100, 100, 100), "Heal")) {
strPlayerAction = "Heal";
intPlayerHP += 5;
if (intPlayerHP > 10) intPlayerHP = 10;
}
if (GUI.Button(new Rect(100, 100, 100, 100), "Attack")) {
strPlayerAction = "Attack";
intEnemyHP -= 1;
}
}
}
}
FIXED IT THANK YOU SOOOOOO MUCH!!! YOU’RE HELP WAS AWESOME!!!
Yes, I didn’t under stand that I was going to have to make it itself the enemy’s turn (if that make’s since) I was think I could call it and then it would just wait the seconds and then move one. Thank you so much for all your help
No problem, didn’t took much time, just wanted to point out don’t rely on just the update itself, code will be very messy, hard to understand, and use more cpu as lots of code there, minimize the code that need to run per frame if possible.