- Home /
Switch() problem [C#]
Hey everybody ! I'm making a game with an enemy spawner and a GameManager who work with a Switch statement. I would like to disable my player and my enemy spawner in "case 2:" but my spawner and my player aren't disabled ... this is my script :
void StateMachine()
{
switch (State)
{
case 0: // INTRO
endCanvas.SetActive(false);
playerShip.SetActive(true);
break;
case 1: // GAME
mobSpawner.GetComponent<MobSpawner>().enabled = true;
playerShip.SetActive(true);
break;
case 2: // END GAME
Debug.Log("End game");
mobSpawner.GetComponent<MobSpawner>().enabled = false;
Debug.Log("MobSpawner disabled");
playerShip.SetActive(false);
Debug.Log("PlayerShip disabled");
endCanvas.SetActive(true);
text_Kills.text = "You killed " + kills + " enemies !";
break;
}
The canvas appear, the console say : "End Game"
"MobSpawner disabled"
"PlayerShip disabled"
Someone can help me ?
Thank you,
Bye, xyHeat
EDIT :
the entire script :
public class GameManager : MonoBehaviour {
public GameObject playerShip;
public GameObject mobSpawner;
public GameObject endCanvas;
public Text text_Kills;
public int State;
public int kills;
void Start()
{
State = 1;
StateMachine();
}
void StateMachine()
{
switch (State)
{
case 0: // INTRO
endCanvas.SetActive(false);
playerShip.SetActive(true);
break;
case 1: // GAME
mobSpawner.GetComponent<MobSpawner>().enabled = true;
playerShip.SetActive(true);
break;
case 2: // END GAME
Debug.Log("End game");
mobSpawner.GetComponent<MobSpawner>().enabled = false;
Debug.Log("MobSpawner disabled");
playerShip.SetActive(false);
Debug.Log("PlayerShip disabled");
endCanvas.SetActive(true);
text_Kills.text = "You killed " + kills + " enemies !";
break;
}
}
public void ToIntro()
{
State = 0;
StateMachine();
}
public void ToGame()
{
State = 1;
StateMachine();
}
public void ToEndGame()
{
State = 2;
StateMachine();
}
}
If you attach print statements to the other cases, do they print after the case2 debug lines? You might be reactivating them somewhere?
The others debugs are print. The active the case 2, i use that : public void ToEndGame() { State = 2; State$$anonymous$$achine(); }
who is called when the player get 0 lives
The ones from case2 print, but if you put debug.print statements in case1, do they fire after case2?
Have you verified that the object you expect to be the player is the actual object you're giving your script in the playerShip variable?
Yes, player isn't disabled and enemies still spawn...
Answer by Raresh · Jun 01, 2016 at 06:15 PM
Make sure there aren't any objects calling your methods. From your code, a way to quickly determine that would be to look at the endCanvas. If that gets enabled, but the others stay disabled, it means that something else is re-enabling your scripts.
Also i would make the StateMachine method have an int or enum as a parameter, so you don't have a global variable. Just call StateMachine (2) or if you use enums StateMachine(GameStates.Intro) or something similar.
Hi! I follow your instruction and i make that :
void Start()
{
State$$anonymous$$achine(1);
}
void State$$anonymous$$achine(int State)
{
switch (State)
{
case 0: // INTRO
endCanvas.SetActive(false);
playerShip.SetActive(true);
break;
case 1: // GA$$anonymous$$E
mobSpawner.GetComponent<$$anonymous$$obSpawner>().enabled = true;
playerShip.SetActive(true);
break;
case 2: // END GA$$anonymous$$E
Debug.Log("End game");
mobSpawner.GetComponent<$$anonymous$$obSpawner>().enabled = false;
Debug.Log("$$anonymous$$obSpawner disabled");
playerShip.SetActive(false);
Debug.Log("PlayerShip disabled");
endCanvas.SetActive(true);
text_$$anonymous$$ills.text = "You killed " + kills + " enemies !";
break;
}
}
public void ToIntro()
{
State$$anonymous$$achine(0);
}
public void ToGame()
{
State$$anonymous$$achine(1);
}
public void ToEndGame()
{
State$$anonymous$$achine(2);
}
}
then the canvas appear, the player disapear but the enemy still spawn.
I check if something call it, but nothing do it...
This is my spawn script : public GameObject enemy; public GameObject enemy2;
float maxSpawnRateInSeconds = 5f;
void Start()
{
Invoke("SpawnEnemy", maxSpawnRateInSeconds);
InvokeRepeating("IncreaseSpawnRate", 0f, 15f);
}
void SpawnEnemy()
{
Vector2 $$anonymous$$ = Camera.main.ViewportToWorldPoint(new Vector2(0, 0));
Vector2 max = Camera.main.ViewportToWorldPoint(new Vector2(1, 1));
float i = Random.Range(1.0f, 2.0f);
if(i <= 1.5f)
{
GameObject anEnemy = (GameObject)Instantiate(enemy);
anEnemy.transform.position = new Vector2(Random.Range($$anonymous$$.x, max.x), max.y);
} else
{
GameObject anEnemy = (GameObject)Instantiate(enemy2);
anEnemy.transform.position = new Vector2(Random.Range($$anonymous$$.x, max.x), max.y);
}
ScheduleNextEnemySpawn();
}
void ScheduleNextEnemySpawn()
{
float spawnInNSeconds;
if (maxSpawnRateInSeconds > 1f)
{
spawnInNSeconds = Random.Range(1f, maxSpawnRateInSeconds);
}
else
{
spawnInNSeconds = 1f;
}
Invoke("SpawnEnemy", spawnInNSeconds);
}
void IncreaseSpawnRate()
{
if (maxSpawnRateInSeconds > 1f)
{
maxSpawnRateInSeconds--;
}
if (maxSpawnRateInSeconds == 1f)
{
CancelInvoke("IncreaseSpawnRate");
}
}
See now it makes sense. You schedule to spawn a new wave but aren't actually checking when spawning the wave if the game ended.
void SpawnEnemy()
{
if( State!=2)
{
// do stuff
}
}
You still need to have a public variable for the game state, and you can set it's value in
public int State;
State$$anonymous$$achine(int State)
{
this.State = State;
}
I think @Raresh is right in his last comment, and his solution should work. But in this comment I intent to explain more on the why your code doesn't stop.
Are you sure that your spawner isn't disabled? (in the inspector the checkbox next to the scripts name) Because reading this answer, you can read that Invoke and InvokeRepeating don't actually care about whether you object is enabled or not and will hapilly continue to execute your code even when disabled.
In either way, I think using coroutines for this is a better option for performance if you care about that :p. Stopping your code from being executed can either be done by polling your State (or this.enabled) in the SpawnEnemy method as explained above, or by calling CancelInvoke()/StopAllCoroutines() (depending on whether you use Invoke or coroutines) in the OnDisable of your spawn script.
Thank you, it work ! I didn't know that Invoke and InvokeRepeating weren't affected by disable or enable an object ! I'll look for the coroutines, I never pay attention to them.
Thank you again ! Bye, xyHeat
Your answer
Follow this Question
Related Questions
How to make my enemies spawn at spawn point, but not randomly? 1 Answer
Unity how to make different enemy spawn one at a time 1 Answer
How to spawn enemy? (Enemies) 1 Answer
Why does only one object respond, while more objects have exact same script? 0 Answers
Wave Spawner not working |Does not detect if an object is destroyed 1 Answer