Unity - 我的数组没有更新它的元素

Unity - my array is not updating its elements

我正在 Unity 中制作我的第一个应用程序来学习英语单词,但我遇到了困难。 我创建了这样的数组:

public string[] words = {
    "apple",
    "banana",
    "big",
    "blue",
    "book",
    "one",
    "two"
};

我正在使用 PlayerPrefs 来保存我正在学习的数组元素。 问题是我不能从这个数组中添加或删除元素。无论我做什么,它总是显示这 7 个元素。 你能告诉我为什么吗?

问题是我不想动态地或在脚本中添加元素。我只想通过添加更多元素手动扩展我的数组,如下所示:

public string[] words = {
    "apple",
    "banana",
    "big",
    "blue",
    "book",
    "one",
    "two",
    "colours",
    "green",
    "orange",
    "pencil",
    "yellow",
    "four",
    "five",
    "six",
    "small",
};

问题是,在将数组从我的第一个 post 更改为这个后,更改无效。程序仍然只看到 7 个元素。 我尝试删除一些元素,结果是一样的。看起来程序将我的数组保存在内存中或其他东西中......

这是我的完整代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GameManager : MonoBehaviour {

    public static GameManager instance;
    public bool isLearnOn;
    public bool isFrontMenuActive;
    public GameObject frontMenuEmpty;
    Animator frontMenu;
    Animator finishPanel;

    //Tasks Elements
    Image taskImage;
    GameObject taskImageEmpty;
    GameObject taskAllElementsEmpty;
    GameObject taskTextEmpty;
    Text taskText;
    InputField taskInputField;
    AudioSource taskAudio;
    int randomWord;
    int wordCount;
    int allWordsCount;
    int collectPoint;
    Text pointsBoard;
    Text hint;
    public bool isHintShown;
    GameObject hintTextEmpty;
    int innerTaskCount;
    public bool isFinishPanelOn;



    void Awake(){
        if (instance == null) {
            instance = this;
        }
    }

    void Start () {
        collectPoint = (PlayerPrefs.GetInt ("points"));
        isLearnOn = false;
        //Variable assignment
            //Tasks Elements 
        taskAllElementsEmpty = GameObject.Find ("TaskAllElementsEmpty");
        taskImage = GameObject.Find ("TaskImage").GetComponent <Image>();
        taskTextEmpty = GameObject.Find ("TaskTextEmpty");
        taskText = GameObject.Find ("TaskText").GetComponent <Text>();
        taskInputField = GameObject.Find ("TaskInputField").GetComponent <InputField>();
        taskAudio = GameObject.Find ("GameManager").GetComponent <AudioSource>();
        pointsBoard = GameObject.Find ("PointsBoard").GetComponent <Text>();
        hint = GameObject.Find ("Hint").GetComponent <Text>();
        hintTextEmpty = GameObject.Find ("HintTextEmpty");
        finishPanel = GameObject.Find ("FinishPanel").GetComponent <Animator>();
        taskImageEmpty = GameObject.Find ("TaskImageEmpty");

        frontMenuEmpty = GameObject.Find ("FrontMenuEmpty");
        frontMenu = GameObject.Find ("FrontMenuEmpty").GetComponent <Animator>();

        pointsBoard.text = collectPoint.ToString ();

        allWordsCount = words.Length;
        Debug.Log (allWordsCount);

        isFrontMenuActive = false;

        FrontMenuShowHide ();
        taskAllElementsEmpty.SetActive (false);
        isHintShown = false;
        hint.text = "";
        innerTaskCount = 0;
        isFinishPanelOn = false;
        //TODO  Disable finisih panel


    }


    void Update () {
        if (isLearnOn == true) {
            if (wordCount < allWordsCount) {
                if  ((taskInputField.text == words [wordCount]) && innerTaskCount == 0) {
                    Task1 ();
                    taskText.text = "";
                    taskInputField.placeholder.GetComponent<Text>().text = "What is it?";
                    innerTaskCount = 1;

                } 
                else if  ((taskInputField.text == words [wordCount]) && innerTaskCount == 1) {
                    Task1 ();
                    taskText.text = "";
                    taskInputField.placeholder.GetComponent<Text>().text = "Listen and type the word down";
                    taskImageEmpty.SetActive (false);
                    innerTaskCount = 2;
                }

                else if ((taskInputField.text == words [wordCount]) && innerTaskCount == 2){
                    if (isHintShown == false) {
                        CollectPoints ();
                        NextTask ();
                        Debug.Log (wordCount);
                        innerTaskCount = 0;
                    } else {
                        NextTask ();
                        innerTaskCount = 0;
                    }
                }
            } else {

                if(isFinishPanelOn == false){
                    HideFinishPanel ();
                    wordCount = 0;
                }


            }

        } else {
            if (taskInputField.text == words [randomWord]) {

                if (isHintShown == false) {
                    CollectPoints ();
                    RandomTask ();
                } else {
                    RandomTask ();
                }
            }
        }

    }

    public void FrontMenuShowHide(){
        if (isFrontMenuActive == true) {
            frontMenu.Play ("FrontMenuOut");
            isFrontMenuActive = false;
        } else {
            frontMenu.Play ("FrontMenu");
            isFrontMenuActive = true;

        }
    }



    public void Task1(){
        isHintShown = false;
        wordCount = (PlayerPrefs.GetInt ("wordCountPrefs"));
        taskAllElementsEmpty.SetActive (true);
        taskText.text = words[wordCount];
        taskInputField.text = "";
        taskInputField.ActivateInputField ();
        //SoundPlay ();
        LoadPicture ();
        taskTextEmpty.SetActive (true);
        hint.text = "";
        taskInputField.placeholder.GetComponent<Text>().text = "Copy the word, please...";
        string path = "audio/" + words [wordCount];
        taskAudio.clip = (AudioClip)Resources.Load(path, typeof(AudioClip));
        taskAudio.Play ();
        taskImageEmpty.SetActive (true);
    }

    public void RandomTask(){
        isHintShown = false;
        randomWord = Random.Range (0, allWordsCount);
        taskAllElementsEmpty.SetActive (true);
        taskText.text = words[randomWord];
        taskInputField.text = "";
        taskInputField.ActivateInputField ();
        //SoundPlay ();
        LoadRandomPicture ();
        taskTextEmpty.SetActive (false);
        hint.text = "";
        taskImageEmpty.SetActive (true);
        taskInputField.placeholder.GetComponent<Text>().text = "What is it?";
        string path = "audio/" + words [randomWord];
        taskAudio.clip = (AudioClip)Resources.Load(path, typeof(AudioClip));
        taskAudio.Play ();
    }


    public void SoundPlay(){
        if (isLearnOn == true) {
            string path = "audio/" + words [wordCount];
            taskAudio.clip = (AudioClip)Resources.Load(path, typeof(AudioClip));
            taskAudio.Play ();
        } else {
            string path = "audio/" + words [randomWord];
            taskAudio.clip = (AudioClip)Resources.Load(path, typeof(AudioClip));
            taskAudio.Play ();
        }

    }

    public void LoadPicture(){
        string path = "img/" + words [wordCount];
        taskImage.sprite = (Sprite)Resources.Load(path, typeof(Sprite));
    }


    public void LoadRandomPicture(){
        string path = "img/" + words [randomWord];
        taskImage.sprite = (Sprite)Resources.Load(path, typeof(Sprite));
    }

    public void NextTask(){
        wordCount++;
        PlayerPrefs.SetInt ("wordCountPrefs", wordCount);
        Task1 ();
    }


    public void LearnIsOn(){
        isLearnOn = true;
    }
    public void LearnIsOff(){
        isLearnOn = false;
    }

    public void CollectPoints(){
            collectPoint++;
            PlayerPrefs.SetInt ("points", collectPoint);
            pointsBoard.text = collectPoint.ToString ();
    }

    public void ShowHint(){

        if (isLearnOn == true ) {
            if (innerTaskCount != 0){
                hint.text = words [wordCount];
                isHintShown = true;
            }

        } else {
            hint.text = words [randomWord];
            isHintShown = true;

        }
    }

    public void HideFinishPanel(){
        if (isFinishPanelOn == true) {
            finishPanel.Play ("FinishPanelOut");
            isFinishPanelOn = false;
        } else {
            finishPanel.Play ("FinishPanel");
            isFinishPanelOn = true;
        }


    }



    public string[] words = {
        "apple",
        "banana",
        "big",
        "blue",
        "book",
        "one",
        "two",
        "colours",
        "green",
        "orange",
        "pencil",
        "yellow",
        "four",
        "five",
        "six",
        "small",
    };

}

`

您需要使用列表代替数组。列表允许您添加或删除任何项目。

 List <string> names = new List<string>();

 Void Start()
    {
          names.Add(“apple”); 

  }

发生这种情况是因为 Unity 初始化序列化 public 对象本身。当您第一次在脚本中定义您的变量时,如果您手动初始化它,Unity 会用您的值序列化它。否则 Unity 使用默认值序列化它。

例如。当您第一次创建下面的脚本时,例如;

public class GameManager : MonoBehaviour {

public string[] words = {
        "one",
        "two",
        "three",
        "four",
        "five",
        "six",
    };
}

Unity 使用此值序列化单词。在那之后,即使您从脚本更改初始值,下次您 运行,它实际上也不会改变。

为此,有两种选择。第一的;使用 [System.NonSerialized] 属性在脚本中定义变量。

[System.NonSerialized] public string[] words = {};

第二个选择,select 层次结构中的游戏对象。在检查器上,选择您的脚本组件并在更改初始变量时重置它。

如果您希望能够同时执行这两项操作,在编辑器中和通过脚本添加元素,您应该使用 List<string> words 并在将其添加到脚本之前检查该值是否已存在于列表中:

[SerializeField]
private List<string> words = new List<string>();

private void Start(){
    if(!words.Contains("apple")){
        words.Add("apple")
    }

    if(!words.Contains("banana")){
        words.Add("banana")
    }
}

独立于此,如果您还想在编辑器中更新 List/Array,我建议您使用 [ContextMenu] 标签:

例如对于您的阵列:

public string[] words; // you don't set it here but expect it to be set in the editor

[ContextMenu("Import scripted array")]
private void ImportScriptedArray(){
    // Note in this case I simply overwrite any setting within the editor
    // There are multiple ways to prevent this like before using List or other methods
    words = new [] {
        "bla",
        "bli",
        "blub"
    };
}

这会将方法 ImportScriptedArray 添加到编辑器中该组件的上下文菜单中。所以首先你有这个未设置的数组:

在您的 script/component 上,您现在可以单击设置图标打开上下文菜单。

然后在上下文菜单中单击刚刚生成的 Import Scripted Array 以从脚本中导入数组。