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
以从脚本中导入数组。
我正在 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
以从脚本中导入数组。