【问题标题】:Unity - my array is not updating its elementsUnity - 我的数组没有更新它的元素
【发布时间】:2018-01-24 16:51:41
【问题描述】:

我正在 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",
};

问题是,在将数组从我的第一篇文章更改为这篇文章后,更改无效。程序仍然只看到 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",
    };

}

`

【问题讨论】:

  • 显示你在做什么但不起作用。如果我们不知道您做了什么,我们就无法告诉您哪里出了问题。

标签: arrays unity3d elements updating


【解决方案1】:

这是因为 Unity 自己初始化了序列化的公共对象。当您第一次在脚本中定义变量时,如果您手动初始化它,Unity 会使用您的值对其进行序列化。否则 Unity 使用默认值对其进行序列化。

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

public class GameManager : MonoBehaviour {

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

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

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

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

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

【讨论】:

  • [System.NonSerialized] public string[] words = {};工作得很好!非常感谢!!!!!!
【解决方案2】:

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

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

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

  }

【讨论】:

  • @LewsTherin 但使用列表一也可以从中间删除元素
【解决方案3】:

如果您希望能够同时执行这两种操作,在编辑器中和通过脚本添加元素,您应该使用 List&lt;string&gt; 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")
    }
}

独立于此,如果您想在编辑器中更新列表/数组,我建议您使用[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 方法添加到编辑器中此组件的上下文菜单中。所以首先你有这个未设置的数组:

在您的脚本/组件上,您现在可以单击设置图标以打开上下文菜单。

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

【讨论】:

    猜你喜欢
    • 2016-12-26
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 2014-12-03
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多