I am trying to check if the value in string word from one class matches any element in the array stringAnswers in another and if it does i want the score to increment by 1. For some reason the code im using below increments the score by 1,2 and 3 depending on the word that is displayed any help would be awesome cheers.
public class Player : MonoBehaviour
{
public int Score = 0;
private string[] StringAns = {"steve", "grace", "lilly"};
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown(KeyCode.Space))
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit))
{
if (hit.transform.GetComponent<ButtonNo>() != null)
{
foreach (string stringAnsers in StringAns)
{
if (stringAnsers.Equals(FindObjectOfType<GameController>().word))
{
Debug.Log(" Button has been looked at");
FindObjectOfType<GameController>().RandText();
}
else
{
Debug.Log(" Button has been looked at");
FindObjectOfType<GameController>().RandText();
Score++;
}
}
}
}
if (Physics.Raycast(transform.position, transform.forward, out hit))
{
if (hit.transform.GetComponent<ButtonYes>() != null)
{
foreach (string stringAnsers in StringAns)
{
if (stringAnsers.Equals( FindObjectOfType<GameController>().word) )
{
Debug.Log(" Button has been looked at");
FindObjectOfType<GameController>().RandText();
Score++;
}
else
{
FindObjectOfType<GameController>().RandText();
}
}
}
}
}
}
}
GameController
public class GameController : MonoBehaviour
{
public TextMesh InfoText;
public TextMesh WallText;
public string word;
public Player player;
public string[] Strings = { "stev", "lilly", "grace" };
// Use this for initialization
void Start()
{
RandText();
}
// Update is called once per frame
void Update()
{
InfoText.text = "Is this Spelling Correct ?\n Score: " + player.Score;
}
public void RandText()
{
word = Strings[Random.Range(0, Strings.Length)];
WallText = GameObject.Find("WallText").GetComponent<TextMesh>();
WallText.text = word;
}
}
In general you should call FindObjectOfType<GameController>()
only once eg in Start
private GameController _gameController;
private void Start()
{
_gameController= FindObjectOfType<GameController>();
}
and than reuse that _gameController
reference everywhere instead of FindObjectOfType<GameController>()
.
The same for WallText
in GameController
:
public TextMesh WallText;
private void Start()
{
WallText = GameObject.Find("WallText").GetComponent<TextMesh>();
RandText();
}
public void RandText()
{
word = Strings[Random.Range(0, Strings.Length)];
WallText.text = word;
}
better would even be you already reference those in the Inspector in Unity via drag&drop than you don't have to use Find
at all
Than to your problem: You are setting a new value for word
in every iteration for the loop
foreach (string stringAnsers in StringAns)
{
if (stringAnsers.Equals(FindObjectOfType<GameController>().word))
{
Debug.Log("Button has been looked at");
FindObjectOfType<GameController>().RandText();
}
else
{
Debug.Log("Button has been looked at");
FindObjectOfType<GameController>().RandText();
Score++;
}
}
So it might happen that the word doesn't match so you call Score++;
but at the same time you do FindObjectOfType<GameController>().RandText();
everytime so a new random word is generated/selected for each iteration.
So in the next iteration of the foreach loop you check against a new random word which might or might not match the next answer string in the list.
Instead you should only generate a new random word after the loop is done eg like
foreach (string stringAnsers in StringAns)
{
if (stringAnsers.Equals(FindObjectOfType<GameController>().word))
{
Debug.Log("Button has been looked at-> matched");
Score++;
}
else
{
Debug.Log("Button has been looked at -> didn't match");
}
}
FindObjectOfType<GameController>().RandText();
Note this would still add 1-3
points depending how many of the given stringAnswer
match the word. So you should add a break;
after increasing Score
once if you want only 1
added.
Using Linq you could also do this in only one line instead a loop:
if(StringAns.Any(answer => string.Equals(answer, _gameController.word)))) Score++;
_gameController.RandText();
or for the No
button
if(!StringAns.Any(answer => string.Equals(answer, _gameController.word)))) Score++;
I guess the problem is that you are generating a new random word inside the foreach loop that check the word itself. Also, i suggest you not to use a foreach loop, because items inside the array could be more that 3 items, so it could slow the method. I suggest you to use contains
instead, like so:
if (StringAns.Contains(FindObjectOfType<GameController>().word))
{
Debug.Log(" Button has been looked at");
Score++;
}
else
Debug.Log(" Button has *not* been looked at");
FindObjectOfType<GameController>().RandText();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.