我试图获取对话JSON的内容,并将其属性(存储到Dialogues类中)复制到另一个源自MonoBehaviour(DialogueManager)的类中。 无论如何,即使GetProperty返回正确的属性名称,GetValue方法也将返回null。 我不能只将Json读到DialogueManager,因为JSONUtility显然需要导出到非MonoBehaviour类。
using System.IO;
using UnityEngine;
public class DialogueManager : MonoBehaviour
{
//999 IS RETURN TO MENU
//1000 IS CLOSE GAME
public static DialogueManager instance = null;
Dialogues dial;
public string text1 { get; set; }
public string choices1 { get; set; }
public string consequences1 { get; set; }
public string text2 { get; set; }
public string choices2 { get; set; }
public string consequences2 { get; set; }
public string text3 { get; set; }
public string choices3 { get; set; }
public string consequences3 { get; set; }
public string text4 { get; set; }
public string choices4 { get; set; }
public string consequences4 { get; set; }
public string text5 { get; set; }
public string choices5 { get; set; }
public string consequences5 { get; set; }
public string text6 { get; set; }
public string choices6 { get; set; }
public string consequences6 { get; set; }
public string text7 { get; set; }
public string choices7 { get; set; }
public string consequences7 { get; set; }
public string text8 { get; set; }
public string choices8 { get; set; }
public string consequences8 { get; set; }
public string text9 { get; set; }
public string choices9 { get; set; }
public string consequences9 { get; set; }
public string text10 { get; set; }
public string choices10 { get; set; }
public string consequences10 { get; set; }
public string text11 { get; set; }
public string choices11 { get; set; }
public string consequences11 { get; set; }
public string text12 { get; set; }
public string choices12 { get; set; }
public string consequences12 { get; set; }
public string text13 { get; set; }
public string choices13 { get; set; }
public string consequences13 { get; set; }
public string text14 { get; set; }
public string choices14 { get; set; }
public string consequences14 { get; set; }
public string text15 { get; set; }
public string choices15 { get; set; }
public string consequences15 { get; set; }
public string text16 { get; set; }
public string choices16 { get; set; }
public string consequences16 { get; set; }
public string text17 { get; set; }
public string choices17 { get; set; }
public string consequences17 { get; set; }
public string text18 { get; set; }
public string choices18 { get; set; }
public string consequences18 { get; set; }
public string text19 { get; set; }
public string choices19 { get; set; }
public string consequences19 { get; set; }
public string text20 { get; set; }
public string choices20 { get; set; }
public string consequences20 { get; set; }
public string text21 { get; set; }
public string choices21 { get; set; }
public string consequences21 { get; set; }
public string text22 { get; set; }
public string choices22 { get; set; }
public string consequences22 { get; set; }
public string text23 { get; set; }
public string choices23 { get; set; }
public string consequences23 { get; set; }
string fixedName;
string[] splits;
string text;
int[] consequences;
private void Awake()
{
if(instance == null)
{
instance = this;
}
else
{
enabled = false;
}
dial = new Dialogues();
StreamReader sR = new StreamReader(Application.dataPath + "/GameData/dialogues.json");
string json = sR.ReadToEnd();
dial = JsonUtility.FromJson<Dialogues>(json);
Assign();
}
//This doesn't work for some reason
public void Assign()
{
foreach(var property in typeof(Dialogues).GetProperties())
{
typeof(DialogueManager).GetProperty(property.Name).SetValue(this, property.GetValue(dial));
}
}
public string GetText(int currentText)
{
fixedName = "text" + currentText;
string output = typeof(DialogueManager).GetProperty(fixedName).GetValue(this, null).ToString();
return output;
}
public string GetTextChoices(int textNum)
{
fixedName = "choices" + textNum;
string output = typeof(DialogueManager).GetProperty(fixedName).GetValue(this, null).ToString();
return output;
}
public int[] GetChoicesConsequences(int textNum)
{
fixedName = "consequences" + textNum;
string output = typeof(DialogueManager).GetProperty(fixedName).GetValue(this, null).ToString();
splits = output.Split('§');
consequences = new int[splits.Length];
for (int i = 0; i < splits.Length; i++)
{
consequences[i] = int.Parse(splits[i]);
}
return consequences;
}
private void DumbAssign()
{
text1 = dial.text1;
choices1 = dial.choices1;
consequences1 = dial.consequences1;
text2 = dial.text2;
choices2 = dial.choices2;
consequences2 = dial.consequences2;
text3 = dial.text3;
choices3 = dial.choices3;
consequences3 = dial.consequences3;
text4 = dial.text4;
choices4 = dial.choices4;
consequences4 = dial.consequences4;
text5 = dial.text5;
choices5 = dial.choices5;
consequences5 = dial.consequences5;
text6 = dial.text6;
choices6 = dial.choices6;
consequences6 = dial.consequences6;
text7 = dial.text7;
choices7 = dial.choices7;
consequences7 = dial.consequences7;
text8 = dial.text8;
choices8 = dial.choices8;
consequences8 = dial.consequences8;
text9 = dial.text9;
choices9 = dial.choices9;
consequences9 = dial.consequences9;
text10 = dial.text10;
choices10 = dial.choices10;
consequences10 = dial.consequences10;
text11 = dial.text11;
choices11 = dial.choices11;
consequences11 = dial.consequences11;
text12 = dial.text12;
choices12 = dial.choices12;
consequences12 = dial.consequences12;
text13 = dial.text13;
choices13 = dial.choices13;
consequences13 = dial.consequences13;
text14 = dial.text14;
choices14 = dial.choices14;
consequences14 = dial.consequences14;
text15 = dial.text15;
choices15 = dial.choices15;
consequences15 = dial.consequences15;
text16 = dial.text16;
choices16 = dial.choices16;
consequences16 = dial.consequences16;
text17 = dial.text17;
choices17 = dial.choices17;
consequences17 = dial.consequences17;
text18 = dial.text18;
choices18 = dial.choices18;
consequences18 = dial.consequences18;
text19 = dial.text19;
choices19 = dial.choices19;
consequences19 = dial.consequences19;
text20 = dial.text20;
choices20 = dial.choices20;
consequences20 = dial.consequences20;
text21 = dial.text21;
choices21 = dial.choices21;
consequences21 = dial.consequences21;
text22 = dial.text22;
choices22 = dial.choices22;
consequences22 = dial.consequences22;
}
}
[System.Serializable]
public class Dialogues
{
public string text1 { get; set; }
public string choices1 { get; set; }
public string consequences1 { get; set; }
public string text2 { get; set; }
public string choices2 { get; set; }
public string consequences2 { get; set; }
public string text3 { get; set; }
public string choices3 { get; set; }
public string consequences3 { get; set; }
public string text4 { get; set; }
public string choices4 { get; set; }
public string consequences4 { get; set; }
public string text5 { get; set; }
public string choices5 { get; set; }
public string consequences5 { get; set; }
public string text6 { get; set; }
public string choices6 { get; set; }
public string consequences6 { get; set; }
public string text7 { get; set; }
public string choices7 { get; set; }
public string consequences7 { get; set; }
public string text8 { get; set; }
public string choices8 { get; set; }
public string consequences8 { get; set; }
public string text9 { get; set; }
public string choices9 { get; set; }
public string consequences9 { get; set; }
public string text10 { get; set; }
public string choices10 { get; set; }
public string consequences10 { get; set; }
public string text11 { get; set; }
public string choices11 { get; set; }
public string consequences11 { get; set; }
public string text12 { get; set; }
public string choices12 { get; set; }
public string consequences12 { get; set; }
public string text13 { get; set; }
public string choices13 { get; set; }
public string consequences13 { get; set; }
public string text14 { get; set; }
public string choices14 { get; set; }
public string consequences14 { get; set; }
public string text15 { get; set; }
public string choices15 { get; set; }
public string consequences15 { get; set; }
public string text16 { get; set; }
public string choices16 { get; set; }
public string consequences16 { get; set; }
public string text17 { get; set; }
public string choices17 { get; set; }
public string consequences17 { get; set; }
public string text18 { get; set; }
public string choices18 { get; set; }
public string consequences18 { get; set; }
public string text19 { get; set; }
public string choices19 { get; set; }
public string consequences19 { get; set; }
public string text20 { get; set; }
public string choices20 { get; set; }
public string consequences20 { get; set; }
public string text21 { get; set; }
public string choices21 { get; set; }
public string consequences21 { get; set; }
public string text22 { get; set; }
public string choices22 { get; set; }
public string consequences22 { get; set; }
public string text23 { get; set; }
public string choices23 { get; set; }
public string consequences23 { get; set; }
}
编辑1:我现在已经编辑了脚本,仅对属性使用Dialogues类,但是我仍然不知道如何获取属性(我需要这样做,因为会有250多个文本)
using System.IO;
using UnityEngine;
public class DialogueManager : MonoBehaviour
{
//999 IS RETURN TO MENU
//1000 IS CLOSE GAME
public static DialogueManager instance = null;
string fixedName;
private Dialogues dial;
public Dialogues Dial { get { return dial; } }
string[] splits;
string text;
int[] consequences;
private void Awake()
{
if(instance == null)
{
instance = this;
}
else
{
enabled = false;
}
dial = new Dialogues();
StreamReader sR = new StreamReader(Application.dataPath + "/GameData/dialogues.json");
string json = sR.ReadToEnd();
dial = JsonUtility.FromJson<Dialogues>(json);
}
public string GetText(int currentText)
{
fixedName = "text" + currentText;
string output = instance.Dial.GetType().GetProperty(fixedName).GetValue(dial).ToString();
return output;
}
public string GetTextChoices(int textNum)
{
fixedName = "choices" + textNum;
string output = typeof(DialogueManager).GetProperty(fixedName).GetValue(this, null).ToString();
return output;
}
public int[] GetChoicesConsequences(int textNum)
{
fixedName = "consequences" + textNum;
string output = typeof(DialogueManager).GetProperty(fixedName).GetValue(this, null).ToString();
splits = output.Split('§');
consequences = new int[splits.Length];
for (int i = 0; i < splits.Length; i++)
{
consequences[i] = int.Parse(splits[i]);
}
return consequences;
}
}
[System.Serializable]
public class Dialogues
{
public string text1;
public string choices1;
public string consequences1;
public string text2;
public string choices2;
public string consequences2;
public string text3;
public string choices3;
public string consequences3;
public string text4;
public string choices4;
public string consequences4;
public string text5;
public string choices5;
public string consequences5;
public string text6;
public string choices6;
public string consequences6;
public string text7;
public string choices7;
public string consequences7;
public string text8;
public string choices8;
public string consequences8;
public string text9;
public string choices9;
public string consequences9;
public string text10;
public string choices10;
public string consequences10;
public string text11;
public string choices11;
public string consequences11;
public string text12;
public string choices12;
public string consequences12;
public string text13;
public string choices13;
public string consequences13;
public string text14;
public string choices14;
public string consequences14;
public string text15;
public string choices15;
public string consequences15;
public string text16;
public string choices16;
public string consequences16;
public string text17;
public string choices17;
public string consequences17;
public string text18;
public string choices18;
public string consequences18;
public string text19;
public string choices19;
public string consequences19;
public string text20;
public string choices20;
public string consequences20;
public string text21;
public string choices21;
public string consequences21;
public string text22;
public string choices22;
public string consequences22;
public string text23;
public string choices23;
public string consequences23;
}
答案 0 :(得分:2)
首先不要为Dialogues
类使用属性!属性(没有任何后备字段)永远不会(反)序列化。
这就是为什么您从未从null
获得GetValue
的原因,因为这些属性从未设置。
删除所有{get; set;}
,并将这些变量设置为简单字段
public string text1;
public string choices1;
....
您应该只在真正需要它们的地方使用属性-通常是只读的accesor属性,或者为了在从外部设置它们之前检查一些值。
这同样适用于DialogueManager
中的所有那些属性。
如果您确实想保留属性(在DialogueManager
中),则应该直接阅读并写入您在其中拥有的dial
参考,例如
public string text1
{
get { return dial.text1; }
set { dial.text1 = value; }
}
但是如果您只是简单地做一个
public Dialogues Dial;
或至少为其赋予只读属性
private Dialogues dial;
public Dialogues Dial
{
get { return dial; }
}
任何其他组件都可以简单地通过该字段intead访问这些值:
dialogueManagerReference.Dial.text1
,您无需复制任何值。
此外,如果使用
public Dialogues Dial;
或
[SerializeField] private Dialogues Dial;
您还可以直接在Unity Inspector中编辑/调试这些值。
最后,数据结构看起来有些奇怪,用数字重复所有这些名称和类型...我没有您的JSON文件,所以也许这是获取它们的方式,但是您确定其中不涉及列表/数组?我宁愿期望像这样的数据结构
[Serializable]
public class Dialogues
{
public Dialogue[] DialogueList;
}
[Serializable]
public class Dialogue
{
public string Text;
public string[] Choices;
public string[] Consequences;
}
和相应的JSON看起来像例如
{
"DialogueList" : [
{
"Text" : "some text",
"Choices" : [
"Option A" , "Option B", "Option C"
],
"Consequences" : [
"Good Boy!", "Oh No!", "Well maybe acceptable ..."
]
},
{
"Text" : "some other text",
"Choices" : [
"Option Left" , "Option Right"
],
"Consequences" : [
"Yeay :)", "Neyy :("
]
},
... and 21 more entries
]
}
答案 1 :(得分:0)
最后,我弄清楚了。 在JsonHelper的帮助下,我将代码更改为使用对象数组。
Dialogues.json:
{
"Items": [
{
"id": "1",
"text": "7:15 A.M. School starts at 8:05",
"choices": "",
"consequences": "2"
},
{
"id": "2",
"text": "What do you want to do?",
"choices": "1: Sleep for a while; 2: Get up",
"consequences": "3?5"
}
]
}
DialogueManager.cs:
using System.IO;
using UnityEngine;
using System;
using System.Security.Cryptography;
using System.Text;
public static class JsonHelper
{
public static T[] FromJson<T>(string json)
{
Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
return wrapper.Items;
}
public static string ToJson<T>(T[] array)
{
Wrapper<T> wrapper = new Wrapper<T>();
wrapper.Items = array;
return JsonUtility.ToJson(wrapper);
}
public static string ToJson<T>(T[] array, bool prettyPrint)
{
Wrapper<T> wrapper = new Wrapper<T>();
wrapper.Items = array;
return JsonUtility.ToJson(wrapper, prettyPrint);
}
[Serializable]
private class Wrapper<T>
{
public T[] Items;
}
}
public class DialogueManager : MonoBehaviour
{
[Serializable]
public class Dialogue
{
public int id;
public string text;
public string choices;
public string consequences;
public Dialogue(int id, string text, string choices, string consequences)
{
this.id = id;
this.text = text;
this.choices = choices;
this.consequences = consequences;
}
}
Dialogue[] dial;
public static DialogueManager instance = null;
string[] splits;
int[] consequences;
private void Awake()
{
if(instance == null)
{
instance = this;
}
else
{
enabled = false;
}
StreamReader sR = new StreamReader(Application.dataPath + "/GameData/dialogues.json");
//NON CRITTOGRAFIA
string json = sR.ReadToEnd();
//CRITTOGRAFIA
//string crypted = sR.ReadToEnd();
//string json = Encrypt.DecryptString(crypted, "think");
dial = JsonHelper.FromJson<Dialogue>(json);
}
public string GetText(int currentText)
{
return dial[currentText - 1].text;
}
public string GetTextChoices(int textNum)
{
return dial[textNum - 1].choices;
}
public int[] GetChoicesConsequences(int textNum)
{
string output = dial[textNum - 1].consequences;
splits = output.Split('?');
consequences = new int[splits.Length];
for (int i = 0; i < splits.Length; i++)
{
consequences[i] = int.Parse(splits[i]);
}
return consequences;
}
}