Why doesn't my "else" statement fire?
Going by standard Rock-Paper-Scissors rules, what would make all of my "if" statements fire but not my else statement? Code on attached txt file.link text
edit (copied and reformatted from attachment):
//When the player collides with the target, determine if it is rock, paper, or scissors, and react accordingly
private void OnTriggerEnter2D(Collider2D target)
{
//If the other game object is the enemy
if (target.CompareTag("Enemy"))
{
EnemySprite = target.GetComponent<Enemy>().GetEnemySprite();
Sprite eRock = target.GetComponent<Enemy>().GeteRock();
Sprite ePaper = target.GetComponent<Enemy>().GetePaper();
Sprite eScissors = target.GetComponent<Enemy>().GeteScissors();
//If the player is rock, but the enemy is rock or paper
if ((PlayerSprite == pRock) && (EnemySprite == eRock || ePaper))
{
Debug.Log("PLAYER IS ROCK");
GameOver();
}
//If the player is paper, but the enemy is paper or scissors
else if ((PlayerSprite == pPaper) && (EnemySprite == ePaper || eScissors))
{
Debug.Log("PLAYER IS PAPER");
GameOver();
}
//If the player is scissors, but the enemy is scissors or rock
else if ((PlayerSprite == pScissors) && (EnemySprite == eScissors || eRock))
{
Debug.Log("PLAYER IS SCISSORS");
GameOver();
}
else
{
Debug.Log("PLAYER WINS");
AudioSource.PlayClipAtPoint(VictorySound, Camera.main.transform.position);
//Destroy target enemy
Destroy(target);
}
Upload your code to a site like https://pastebin.com/ if you don't want to put it here.
FAQ :
Some reasons for getting a post rejected:
Badly formated question: code needs to be formatted using the 101/010 button, break your post up into several parts so it's understandable what you are asking, and make sure there is a question in your post
He posted code, however UA now interprets every attachment as image which makes it impossible to view the code online. You can only download the attachment and view it offline. So technically not his fault. Anyways this question belongs to the help room anyways
I copied your code into your question and removed most useless comments. You had way too many comments. Too many comments make the code less readable and you can easily left behind an outdated comment. Wrong comments are much much worse than no comment at all. Code should be self explanatory. Calling a method named "GameOver" doesn't need a comment that says "End of game". When you add a comment it should add new information that isn't already obvious from the code itself.
Also long lines and adding comments far behind code lines is a horrible comment style. It blows up your file size, makes it difficult to actually see which comment belongs to which line and makes any kind of refactoring and code editing a nightmare.
Finally I should note that this line:
Destroy(target);
will not destroy your enemy. You just destroy the Collider2D component of the object you hit. If you want to destroy the whole gameobject, use
Destroy(target.gameObject);
Answer by Bunny83 · Aug 11, 2019 at 11:02 AM
This condition:
(EnemySprite == eRock || ePaper)
just makes no sense and will always be true. || is the logical or operator which connects boolean expressions with "or". So it actually reads as
((EnemySprite == eRock) || (ePaper))
Since "ePaper" is a UnityEngine.Object derived class it will automatically be converted into a boolean expression which tells you if the object is still alive. Since it most likely is still alive the whole expression evaluates to true.
I would generally recommend a different approach. First of all you shouldn't use different objects to represent the state of the enemy / player. It makes any kind of logic much more difficult. Usually one would use an enum for the 3 different things and both, the player and the enemy would use the same enum. That way you can directly check for a draw If both "players" pick the same object.
However if you want to stick with your current approach you would have to do:
// Enemy wins since Paper > Rock or it's a draw
if (PlayerSprite == pRock && (EnemySprite == ePaper || EnemySprite == eRock))
{
Debug.Log("PLAYER IS ROCK");
GameOver();
}
// Enemy wins since Scissors > Paper or it's a draw
else if (PlayerSprite == pPaper && (EnemySprite == eScissors || EnemySprite == ePaper))
{
Debug.Log("PLAYER IS PAPER");
GameOver();
}
// Enemy wins since Rock > Scissors or it's a draw
else if (PlayerSprite == pScissors && (EnemySprite == eRock || EnemySprite == eScissors))
{
Debug.Log("PLAYER IS SCISSORS");
GameOver();
}
// in all other cases the player wins
else
{
Debug.Log("PLAYER WINS");
AudioSource.PlayClipAtPoint(VictorySound, Camera.main.transform.position);
Destroy(target);
}
The game has exact 9 possible combinations. You check 6 of them with the first 3 if statements (the 3 enemy win and the 3 draw outcomes) and finally your else handles the 3 player win cases.
When using an enum the whole thing can be simplified and you have more information to work with. So when using an enum like this:
public enum EState
{
Rock, Paper, Scissors
}
You can directly check for a draw
if (playerPick == enemyPick)
{
Debug.Log("Draw! both players picked " + playerPick);
}
else if ((playerPick == EState.Rock && enemyPick == EState.Scissors) ||
(playerPick == EState.Paper && enemyPick == EState.Rock) ||
(playerPick == EState.Scissors && enemyPick == EState.Paper) )
{
Debug.Log("Player wins! " + playerPick + " beats " + enemyPick);
)
else
{
Debug.Log("Enemy wins! " + enemyPick + " beats " + playerPick);
)
Since we don't know how your actually choose the different objects we can't go more into details.
ps: Like @Temseii said do not use the attachment function here on UA as it now interprets everything as images. Either include your script / snippet directly inside your question in a code block (select all code text and press the 101/010 button) or use a site like pastebin. However externally hosted code should generally be avoided if possible since external references can break in the future which will render most posts useless for others.