Проверка значения в строке соответствует элементу в массиве C # unity, - PullRequest
0 голосов
/ 22 февраля 2019

Я пытаюсь проверить, соответствует ли значение в строковом слове из одного класса какому-либо элементу в массиве stringAnswers в другом, и если это так, я хочу увеличить счет на 1. По какой-то причине код, который я использую ниже, увеличивает счетна 1,2 и 3, в зависимости от отображаемого слова, любая справка будет отличной аплодисментами.

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;
    }
}

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Полагаю, проблема в том, что вы генерируете новое случайное слово внутри цикла foreach, которое проверяет само слово.Кроме того, я предлагаю вам не использовать цикл foreach, потому что элементов внутри массива может быть больше, чем 3 элемента, поэтому это может замедлить метод.Я предлагаю вам использовать contains вместо этого, вот так:

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();
0 голосов
/ 22 февраля 2019

Как правило, вы должны вызывать FindObjectOfType<GameController>() только один раз, например, при запуске

private GameController _gameController;

private void Start()
{
    _gameController= FindObjectOfType<GameController>();
}

и затем использовать эту ссылку _gameController везде вместо FindObjectOfType<GameController>().

То же самое для 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;
}

было бы лучше, если бы вы уже ссылались на них в Инспекторе в Unity с помощью перетаскивания, чем вообще не нужно использовать Find


Чем ваша проблема: Вы устанавливаете новое значение для word в каждой итерации цикла

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++;
    }
}

Так что может случиться так, что слово не соответствуетпоэтому вы вызываете Score++;, но в то же время вы делаете FindObjectOfType<GameController>().RandText(); каждый раз, поэтому новое случайное слово генерируется / выбирается для каждой итерации.

Таким образом, в следующей итерации цикла foreach вы проверяете новоеслучайное слово, которое может совпадать или не совпадать со следующей строкой ответа в списке.


Вместо этого вы должны генерировать только новое случайное слово после цикл выполняется, например, как

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();

Обратите внимание, что это все равно добавит 1-3 очков в зависимости от hтеперь многие из приведенных stringAnswer соответствуют слову.Поэтому вы должны добавить break; после увеличения Score один раз, если хотите добавить только 1.


Используя Linq, вы также можете сделать это только в одной строке вместо цикла:

if(StringAns.Any(answer => string.Equals(answer, _gameController.word)))) Score++;

_gameController.RandText();

или для кнопки No

if(!StringAns.Any(answer => string.Equals(answer, _gameController.word)))) Score++;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...