Jump to content
Unity Insider Forum

Maurice94

Members
  • Gesamte Inhalte

    22
  • Benutzer seit

  • Letzter Besuch

  • Tagessiege

    3

Alle erstellten Inhalte von Maurice94

  1. @ShV Erstell dir eine Zählervariable die du ShotsFired nennst. Schreib deine Attackfunktion in einen If-Block der prüft, ob ShotsFired kleiner als maximaleMunition ist und erhöhe am Ende jeder Ausführung des Attack-Blocks die Variable ShotesFired um 1. Im Else-Teil returnst du einfach, sodass nichts passiert, sofern der Zähler gleich oder größer als die Anzahl der maximalen Munition ist. Wenn du dann z.B nachladen möchtest, könntest du eine neue Funktion schreiben, die den Zähler wieder auf 0 zurücksetzt. private readonly int maximaleMunition = 3; private int ShotsFired; void Attack() { if(ShotesFired < maximaleMunition) { clone = Instantiate(bulletPrefap, Bulletspawn.position, Bulletspawn.rotation); clone.AddForce(Bulletspawn.transform.right * bulletSpeed); ShotsFired ++; } else return; }
  2. Wo übst du denn Force auf die Kugeln aus? Alles was ich aus dem Code oben entnehmen kann ist, dass du Kugeln an der Position deines Spielers erzeugst. Danach passiert aber nichts mehr. Wie würde, bzw. wie hat dein Code denn ausgesehen als du versucht hast, Force auf die Kugeln auszuüben? @elson
  3. Guten Morgen @Kevin28 - direkt zu Beginn: ICH BIN KEIN EXPERTE! Aber ich kann dich in die richtige Bahn lenken. Du musst dann jedoch selbst recherchieren Ich denke, dass man hier mit dem System.IO Namespace an die Lösung kommen kann. System.IO gibt dir Zugriff auf verschiedene Klassen wie z.B File, DirectoryInfo, usw. die in C# Dateien, Ordner und Pfade auf dem Computer repräsentieren. Mein Lösungsansatz würde wie folgt aussehen: Wenn du dein Spiel schließt (oder von mir aus auch direkt nach der Erstellung der besagten Objekte) erstellst du im persistentDataPath (das ist der Ordner des Programms im Verzeichnis %AppData%) z.B einen Ordner der "Objekte" heißt. Das wäre der erste Schritt, um zu garantieren, dass auch alle Objekte von einem Typen ihr eigenes Verzeichnis besitzen. Dann könntest du über die Childs von deinem "Panel1" drüber loopen und für jedes Objekt eine individuelle Datei mit einer von dir gewählten Endung (z.B .Objekt1.txt oder Objekt1.dat) in diesem Verzeichnis erstellen. All das ist Teil vom System.IO Namespace. // Um ein Verzeichnis zu erstellen, benutz einfach die CreateDirectory-Funktion, die Teil der Klasse "Directory" ist. Directory.CreateDirectory(Application.persistentDataPath + "/deinOrdnerName"); // Und schon hast du einen Ordner erstellt. // Angenommen, wir haben deine gewünschten Speicherobjekte in einem GameObject[] (Array) liegen. GameObject[] alleObjekte = new GameObject[]{10}; // 10 Objekte for(int i = 0; i < alleObjekte.Length ; i++) // erstelle 10 Dateien { string dateiPfad = Application.persistentDataPath + "/deinOrdnerName/"; // in diesem Ordner FileStream neueDatei = File.Create(dateiPfad + alleObjekte[i].GetComponent<ObjektInfo>().objektName); // mit diesem Namen // setzt aber voraus, dass das Objekt irgendwo ein public Field / eine Property namens "objektName" hat, das/die wir uns holen können, um die Datei im Order zu benennen. } Jetzt haben wir das Verzeichnis erstellt und für jedes Objekt eine eigene externe Datei angelegt. Problem ist nur, dass wir jetzt noch die Werte des Objektes in diese Datei schreiben müssen, da es ansonsten ja nur leere Dateien wären. Sprich wir springen nochmal zurück in den Loop. Da du offensichtlich nur mit Strings / Ints / Floats arbeitest, sollten wir in der Lage sein die Werte über einen sogenannten StreamWriter in die Datei zu schreiben, ohne einen BinaryFormatter oder ähnliches zu benutzen. Ein StreamWriter ist gewissermaßen ein Modul, dass wie eine (Achtung: Abstraktion) "Schreibmaschine" funktioniert. Alles, was der StreamWriter von dir verlangt ist ein FileStream. Und ein FileStream ist im Grunde nicht mehr, als eine Repräsentation der Datei, in die der Writer etwas hinein schreiben soll. Wobei genauer gesagt: das FileInfo Objekt ist eher die GENAUE Repräsentation der Datei, wo hingegen der Stream lediglich eine Art "Verbindungsstück" / "Überbrückung" ist, das die Daten empfängt und sie in kleinen Päckchen an den Writer / Reader weiterleitet. Schwierig zu beschreiben, sollte aber ausreichen Jede Instanz vom StreamWriter hat Methoden, auf die du zugreifen kannst. Mit writer.WriteLine(string deinText) kannst du jetzt den von dir gewünschten Inhalt in die externe Datei schreiben, die wir davor noch erstellt haben. Das machst du dann für alle Werte des Objektes, die du später wieder laden möchtest. Müsste dann irgendwie so aussehen: // wir sind wieder im Loop von eben! for(int i = 0; i < alleObjekte.Length ; i++) // erstelle 10 Dateien { string dateiPfad = Application.persistentDataPath + "/deinOrdnerName/"; // in diesem Ordner FileStream neueDatei = File.Create(dateiPfad + alleObjekte[i].GetComponent<ObjektInfo>().objektName); // mit diesem Namen // das ist der Stream, in den wir nun was schreiben wollen... lass uns also einen StreamWriter erstellen StreamWriter writer = new StreamWriter(neueDatei); // neueDatei geben wir als Stream an den Writer writer.WriteLine("Dies ist ein Testtext, den ich in meine Datei schreibe."); // Jetzt haben wir in die Datei geschrieben. writer.Close(); // Und am Ende schließen wir den Writer noch. Gehört zur Prozedur dazu! } Nachdem wir all das gemacht haben, existieren nun mehrere Dateien im Verzeichnis - losgelöst von deiner Anwendung. Wir haben jetzt 10 Dateien erstellt und in jede Datei etwas hinein geschrieben. Wenn du nun dein Spiel beendest und das Spiel neu lädst, werden die Daten jedoch nach wie vor verschwinden. Das ist dann der Punkt, an dem du vom StreamWriter zum StreamReader überspringen musst. Der StreamReader ermöglicht dir nämlich wie der Name schon sagt, Text aus Dateien auszulesen. Wichtig ist also, dass du nun in irgendeiner Start-Funktion in deinem Programm eine Funktion hast, die zunächst einmal prüft, ob das Verzeichnis für die Objekte existiert und ob innerhalb dieses Verzeichnisses auch Dateien (Objekte) liegen. Ich glaube in C# kannst du die Dateien in einem Ordner in einem FileInfo[] (Array) speichern. Folgendes Beispiel: private void ErstelleGameobjekte() { // Referenz zum Pfad string meinOrdner = Application.persistentDataPath + "/deinOrdnerName"; // Prüfen, ob ein Ordner überhaupt existiert machst du so: if(Directory.Exists(meinOrder) { DirectoryInfo ordnerInfo = new DirectoryInfo(meinOrdner); // hier nun ein Array mit allen Files in diesem Ordner... beachte, dass wir eine Funktion vom DirectoryObject benutzen, die einen FileInfo Array returned. FileInfo[] alleDateien = ordnerInfo.GetFiles(); } } Nachdem du das gemacht hast, hast du nun alle Dateien in diesem Ordner in deinem Array liegen. Sprich, wir loopen nun über diesen Array und erstellen für jede Datei in diesem Array eine Instanz deines Prefabs und synchronisieren die Daten von diesem Prefab (die wir uns mit GetComponent greifen) dann mit den Daten aus der externen Datei. Das machst du mit dem eben von mir erwähnten StreamReader, der dich nun die Zeilen aus der Datei lesen lässt. Ich glaube, dass wie beim Writer die Funktion dafür einfach Reader.ReadLine(); / Reader.ReadToEnd(); oder so ähnlich sein sollte. Das ist die Richtung in die du gehen kannst. // Gleicher Code wie eben, nur weiter ausgeführt. public GameObject deinPrefab; public Transform irgendeinParent; private void ErstelleGameobjekte() { // Referenz zum Pfad - dieses Mal als String string meinOrdner = Application.persistentDataPath + "/deinOrdnerName"; // Prüfen, ob ein Ordner überhaupt existiert machst du so: if(Directory.Exists(meinOrder) { // hier nun ein Array mit allen Files in diesem Ordner... beachte, dass wir eine Funktion vom DirectoryObject benutzen, die einen FileInfo Array returned. DirectoryInfo ordnerInfo = new DirectoryInfo(meinOrdner); FileInfo[] alleDateien = ordnerInfo.GetFiles(); foreach(FileInfo info in alleDateien) { GameObject obj = Instantiate(deinPrefab, irgendeinParent); ObjektInfo data = obj.GetComponent<ObjektInfo>(); FileStream stream = info.Open(FileMode.Open); // Du musst nun einen FileStream auf diese Art und Weise erstellen. StreamReader reader = new StreamReader(stream); // ...und ihn auf diese Art und Weise an den Reader weitergeben! data.Name = reader.ReadToEnd(); reader.Close(); // Auch hier wieder den Reader schließen! } } Und im Grunde solltest du an dieser Stelle Informationen vom Computer in dein Spiel geladen haben. Solltest du mit Datentypen arbeiten, die nicht primitiv sind, wird es komplizierter, da du dann BinaryFormatter benutzen musst, um Daten zu serializen, usw. Ein wichtiger Punkt, den ich nicht angemerkt habe ist: JSONUtility. Schau dir auf jeden Fall auch mal Beiträge zu JSON an, da du höchstwahrscheinlich früher oder später Sachen zu JSON konvertieren musst um von dort aus dann weiter zu arbeiten. Ich selbst arbeite z.B größtenteils nur mit Scriptable Objects, demnach weiß ich nicht wie du speziellen Zugriff auf Zeile 3 oder so in einer externen Datei kriegst, um irgendeiner Variable genau diesen Wert zuzuweisen. Aber auch das kannst du durch Recherche easy lösen! Beim Scriptable Object kann ich mir die Werte dann nämlich immer direkt aus den jeweiligen Feldern holen. Nochmals: ich bin kein Experte und wollte dir lediglich die Richtung vorgeben! Sorry, dass ich am Ende etwas schlampig geworden bin. Ich hoffe, ich konnte dir dennoch etwas helfen! LG, Maurice 🙂
  4. Du musst genauer beschreiben, was nicht funktioniert. Rein von der Logik her, sollte der Code funktionieren. Ich würde dir jedoch raten, deinen Variablen und Funktionen aussagekräftige Namen zu geben. Wieso gibst du einer OnClick()-Function die du an den Button weitergibst den Namen OnClick2? Wähle stattdessen einen Namen, der beschreibt, was die Funktion macht. Die Funktion erhöht offensichtlich einen Zähler, bzw. einen Wert. Also gib ihr einen Namen wie z.B IncreaseValue() oder DecreaseValue() - mach es dir nicht unnötig kompliziert. Das gleiche gilt für die Variable. Wieso x1? Was ist die Variable? Ist die Variable ein x1 oder ist die Variable ein Punktestand/Display für einen Wert? Namensgebung ist extrem wichtig. Wähle logische und lesbare Namen, die etwas aussagen. Um zurück auf deine Frage zu kommen: was genau funktioniert denn nicht? Denk daran, dass du dir in deinem Script die Referenz zum Text vom gleichen Objekt holst, auf dem DIESER Script liegt, da du mit GetComponent<Type> danach greifst. Das setzt voraus, dass der Text eine Komponente von dem Objekt ist, auf dem dieser Script liegt. Der Script sollte außerdem nicht auf zwei Objekten liegen, da er permanent einen Wert updatet und jeder Script eine eigene Instanz ist - sprich jede Instanz wird versuchen, den Text für sich zu beanspruchen. Es gibt außerdem eine praktische Funktion für das, was du da manuell zusammen gebaut hast. Versuch mal: Laserleft.text = string.Format("Der Wert ist: {0}", x1);
×
×
  • Neu erstellen...