Jaimi93 Geschrieben 8. Juni 2022 Melden Share Geschrieben 8. Juni 2022 Hallo 😄 Momentan arbeite ich an einem Lernspiel, welches Vokabeln spielerisch abfragen soll. Das Spiel besteht aus Jump´n´Run- und Frageteilen. Der Jump´n´Runteil funktioniert prima und die Menüs auch. Jetzt muss ich nur noch den schwierigsten Teil des Spiel programmieren: den Fragenteil. Ich habe mir überlegt, dass ich das Skript "ImportQuestions" für die Einbindung und Verarbeitung der externen XML-Datei und das Skript "QuestionInteraction" sich um die Darstellung und Interaktion mit dem Gamer kümmern soll. Bin trotzdem aber noch etwas ratlos, wie ich das in C# und Unity umsetzen kann. Mein bisheriger Code in ImportQuestions: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System.IO; public class ImportQuestions : MonoBehaviour { //Import the txt file and save it in array //Path string sPath = "Assets/Questions/English.txt"; //Array public int iQuestions; string[,] QuestionArray = new string[iQuestions, 4]; void Start() { SetArrayQuestions(); } public void SetArrayQuestions() { //Fill the array with the questions and answers //Read the file StreamReader reader = new StreamReader(sPath); //Save in arrays reader.Close(); } public void GetArrayQuestions() { //Get the questions and anwers for the text field } Das ich das Array nach der Anzahl der Fragen beliebig erweitern möchte, habe ich die Variable iQuestions eingeführt. Jedoch meckert Unity darüber. Geplant ist, dass Fragen und Antworten wie folgt in der XML-Datei deklariert werden: <Questions> <Q> <Word>Hello</Word> <Correct>Hallo</Correct> <Wrong1>Nein</Wrong1> <Wrong2>Hase</Wrong2> </Q> </Questions> Ich hoffe, dass ihr mir bei diesem Problem weiterhelfen könnt 😅 Vielen Dank im Voraus 😁 Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 9. Juni 2022 Melden Share Geschrieben 9. Juni 2022 vor 13 Stunden schrieb Jaimi93: Jedoch meckert Unity darüber. Bitte immer mitposten, was denn genau da steht. Das, was da steht, steht da ja nicht zum Spaß. Warum hast du ein zweidimensionales Array? Ich hab das Gefühl, du willst eher ein zweites Array haben. Oder dein ursprüngliches Array größer machen. Im Moment machst du aber ein Array mit 4*iQuestion Elementen. Und das Problem, weswegen du Fehlermeldungen hast, ist: Du kannst ein Feld nicht mit einer anderen Variable direkt initialisieren. Sprich: Statt public int iQuestions; string[,] QuestionArray = new string[iQuestions, 4]; void Start() { SetArrayQuestions(); } musst du das Array in Start() initialisieren, weil dann erst der Wert von iQuestions mit Sicherheit feststeht. public int iQuestions; string[,] QuestionArray; void Start() { QuestionArray = new string[iQuestions, 4]; SetArrayQuestions(); } Aber wie gesagt, du willst vermutlich sowieso kein zweidimensionales Array haben. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Jaimi93 Geschrieben 20. Juni 2022 Autor Melden Share Geschrieben 20. Juni 2022 @Sascha Danke für Deine Antwort 😄 Am 9.6.2022 um 09:27 schrieb Sascha: Bitte immer mitposten, was denn genau da steht. Ok, werd ich beim nächsten Mal beachten 🙈 Am 9.6.2022 um 09:27 schrieb Sascha: Warum hast du ein zweidimensionales Array? Weil ich dachte, dass ich ein Array wie eine Tabelle mache, wo die Frage, richtige Antwort und beiden falschen Antworten drinstehen. Darum sollte es n-Zeilen haben und 4 Spalten. Die Anzahl der Zeilen sollten anhand der Länge des Fragenkataloges definiert werden. Zumindes habe ich mir das so gedacht. Zuerst hab ich mir auch gedacht, dass eine gute Idee wäre, wenn ich eine externe txt-Datei verwende. Hab dann aber festgestellt, dass es mit XML vielleicht einfacher geht. Aber ich glaub, ich denk wieder zu kompliziert... war würdest du anstatt einem Array verwenden? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 20. Juni 2022 Melden Share Geschrieben 20. Juni 2022 vor 23 Minuten schrieb Jaimi93: Weil ich dachte, dass ich ein Array wie eine Tabelle mache, wo die Frage, richtige Antwort und beiden falschen Antworten drinstehen. Verstehe, ist nachvollziehbar Theoretisch geht das auch, aber du machst es dir damit schwerer als es sein muss. Arrays sind eher für gleichartige Elemente da. Also auch semantisch. Obwohl du da vier Strings hast, sind das ja eine Frage und drei Antworten. vor 26 Minuten schrieb Jaimi93: war würdest du anstatt einem Array verwenden? Nene, ein Array ist schon gut, aber ein eindimensionales. Da packst du dann z.B. Structs rein. public struct Question { public string word; public string correct; public string wrong1; public string wrong2; } public Question[] questions; Ist jetzt nur ein ganz stumpfes Beispiel, aber du siehst, wie es deinen XML-Code genau wiederspiegelt. Statt einer Tabelle ohne Überschriften hast du jetzt eine Liste von Fragen (wobei jede "Frage" aus deinen vier Strings besteht). vor 31 Minuten schrieb Jaimi93: Zuerst hab ich mir auch gedacht, dass eine gute Idee wäre, wenn ich eine externe txt-Datei verwende. Hab dann aber festgestellt, dass es mit XML vielleicht einfacher geht. Geht alles. Letztenedes sind auch XML- (oder Json- oder Yaml-)Dateien nur Textdateien mit einem bestimmten Format drin. Ob du dieses Format selber erstellst oder ein Standardformat wie diese drei nimmst, gibt sich nicht viel. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Jaimi93 Geschrieben 22. Juni 2022 Autor Melden Share Geschrieben 22. Juni 2022 @Sascha Danke für deine Antwort. Sie hat mir sehr geholfen Ein paar Fragen habe ich dann aber noch. Ich hab im Internet einen Code gefunden der ein XML Dokument ausliest und frage mich, ob ich es mit deiner Lösung kombinieren kann: using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using System.Xml; using System.Xml.Serialization; [XmlRoot(ElementName = "Questions")] public class ImportQuestions : MonoBehaviour { //Import the XML File public TextAsset TxmlRawFile; [XmlType(TypeName = "Q")] public class CXmlItem { [XmlElement(ElementName = "Word")] public string sWord; [XmlElement(ElementName = "Correct")] public string sCorrect; [XmlElement(ElementName = "Wrong1")] public string sWrong1; [XmlElement(ElementName = "Wrong2")] public string sWrong2; } ... } Wenn ich anstatt der Klasse in der Klasse das Struct verwende und dann ein Array erzeuge, würde es doch dann funktionieren, oder? ... [XmlType(TypeName = "Q")] public struct CXmlItem { [XmlElement(ElementName = "Word")] public string sWord; [XmlElement(ElementName = "Correct")] public string sCorrect; [XmlElement(ElementName = "Wrong1")] public string sWrong1; [XmlElement(ElementName = "Wrong2")] public string sWrong2; } public CXmlItem [] XmlItem; ... Oder erzeugt es automatisch dann ein Array oder Liste, wo alle Elemente gespeichert werden? Da ich diese Art der Deklaration davor noch nicht gesehen habe, verwirrt es mich etwas. (Außer bei der Defintion von einer Range. Aber das ist wahrscheinlich nicht das Gleiche...) Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 22. Juni 2022 Melden Share Geschrieben 22. Juni 2022 Öh, klar, generell geht das. Ob das jetzt so richtig wäre, weiß ich aus dem Kopf nicht. Du wirst aber vielleicht auch noch ein Attribut über das Array packen müssen. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Jaimi93 Geschrieben 23. Juni 2022 Autor Melden Share Geschrieben 23. Juni 2022 Also langsam verzweifel ich ein bisschen. Ich hab ein Attribut (index) hinzugefügt und den kompletten Code von einem Tutorial auf YT übernommen (siehe ganz unten). Trotzem beschwert sich Unty: "'ImportQuestions' does not contain a definition for 'Questions' and no accessible extension method 'Questions' accepting a first argument of type 'ImportQuestions' could be found (are you missing a using directive or an assembly reference?)" und "'QuestionsStructure' does not contain a definition for 'index' and no accessible extension method 'index' accepting a first argument of type 'QuestionsStructure' could be found (are you missing a using directive or an assembly reference?)" Ich hab keine Ahnung, warum Unity die beiden Klassen nicht erkennt. Mit der foreach-Schleife möchte ich eigentlich nur prüfen, ob das Einbinden der Datei funktioniert hat 😓 Der Code, wo Unity ein Probelm damit hat: public class QuestionInteraction : MonoBehaviour { ... //String for the XML document ele Q public const string sPath = "Questions"; // Start is called before the first frame update void Start() { ImportQuestions IQ = ImportQuestions.Load(sPath); foreach(QuestionsStructure Q in IQ.Questions) { UnityEngine.Debug.Log(Q.index); } } ... } Die Klassen ImportQuestions und QuestionStructure sind in jeweils seperaten Dateien definiert: [XmlRoot(ElementName = "QuestionCollector")] public class ImportQuestions { [XmlArray("Questions")] [XmlArrayItem("Q")] public List<QuestionsStructure> items = new List<QuestionsStructure>(); public static ImportQuestions Load(string sPath) { TextAsset _xmlFile = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/XML/Questions.xml"); XmlSerializer serializer = new XmlSerializer(typeof(ImportQuestions)); StringReader reader = new StringReader(_xmlFile.text); ImportQuestions item = serializer.Deserialize(reader) as ImportQuestions; reader.Close(); return item; } } public class QuestionsStructure { [XmlAttribute("index")] public int iIndexQuestion; [XmlElement("Word")] public string sWord; [XmlElement("Correct")] public string sCorrect; [XmlElement("Wrong1")] public string sWrong1; [XmlElement("Wrong2")] public string sWrong2; } Quelle des YT Videos: Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Jaimi93 Geschrieben 23. Juni 2022 Autor Melden Share Geschrieben 23. Juni 2022 Hab den Fehler gefunden. Weil im Tutorial viele Variablen, Datentypen und Dateinnamen gleich sind, hab ich ein paar Dinge verwechselt. Das Verküpfen und Einlesen der XML Datei funktionieren jetzt 🥳 void Start() { ImportQuestions IQ = ImportQuestions.Load(sPath); //For each item in the List "item" foreach(QuestionsStructure Q in IQ.items) { //UnityEngine.Debug.Log(Q.index); print(Q.iIndexQuestion); } } [XmlRoot("QuestionCollector")] public class ImportQuestions { [XmlArray("Questions")] [XmlArrayItem("Q")] public List<QuestionsStructure> items = new List<QuestionsStructure>(); public static ImportQuestions Load(string sPath) { TextAsset _xmlFile = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/XML/Questions.xml"); XmlSerializer serializer = new XmlSerializer(typeof(ImportQuestions)); StringReader reader = new StringReader(_xmlFile.text); ImportQuestions item = serializer.Deserialize(reader) as ImportQuestions; reader.Close(); return item; } } Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Archiviert
Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.