Jump to content
Unity Insider Forum

nordseekrabe

Members
  • Content count

    55
  • Joined

  • Last visited

Community Reputation

0 Neutral

About nordseekrabe

  • Rank
    Advanced Member

Recent Profile Visitors

499 profile views
  1. nordseekrabe

    Save/ Open Scene

    Moin, schon mal einen großen Dank an Poldi007. Werde mich morgen eingehend mit den Scripts beschäftigen. Auf den ersten, schnellen Blick hin fürchte ich, dass hierbei auch "nur" Objekte gespeichert werden können. Für mich wäre aber wichtig, abgelaufene Aktionen, gelöste Rätsel zu speichern. Vielleicht noch einmal ein Beispiel: Der Spieler sammelt verschiedene Objekte in verschiedenen Szenen und sammelt sie im Inventar. Wenn er diese Objekte (z.B. Teilcode) beisammen hat, kann er mit dem nun kompletten Code ein Zahlenschloss öffnen und eine neue Szene damit erreichen. Diesen Ablauf muss man nun speichern, damit nicht bei einem weiteren Besuch der Zahlenschlosstür das gleiche Procedere erforderlich ist, um in die Szene zu gelangen, denn diese wird ja als von Anfang an gespeicherte Szene beim Neustart wieder ausgewählt. Vielleicht gibt es ja eine Chance mit der Methode "IsDirty()", da muss ich aber noch einiges dazu in Erfahrung bringen. Eine gute Nacht wünscht Nordseekrabbe
  2. nordseekrabe

    Save/ Open Scene

    oh, besten Dank, Tarantel. Bin sehr gespannt. Aber ist schon klar, dass "F5" auch von jemandem mit Code (vermutlich C oder C++) ins Spiel gebracht wurde !! Gruß Nordseekrabbe
  3. nordseekrabe

    Save/ Open Scene

    Moin, und danke für die beiden Antworten. Ich glaube, dass ich da einen Gedankenfehler hatte, da die beiden Methoden (Save As und Open Scene) nicht "in game" funktionieren. Aber genau das benötige ich wohl. Bislang fehlt mir noch eine Idee, wie man Aktivitäten des Players, abgearbeitete Rätsel in einer Szene speichern könnte. Wen aus Game in Scene wechsele, sind ja alle Veränderungen weg. Inventar, Scores und Punktergebnisse oder ähnliches kann ich mir zur Speicherung mit PlayerPrefs oder Scriptableobjects einigermaßen vorstellen. Aber, z. B. in einer Szene hat der Player ein Rätsel gelöst und erhält dafür ein Objekt ins Inventar. Dieses Objekt zu speichern sollte mir noch gelingen. Aber wie sage ich dem Spiel, bzw. der Szene, das Rätsel ist jetzt gelöst, du musst nicht bei jedem neuen Besuch in dieser Szene dieses Problem nochmals lösen. z.B. im Kühlschrank ist ein Stück Torte, das der Player sich nimmt, jetzt sollte der Kühlschrank für das gesamte Spiel leer bleiben. z.B. der Player hat verschiedene Objekte gesammelt, mit deren Hilfe gelingt es ihm, eine abgesperrte Tür zu öffnen. Ist das einmal erledigt, darf er diese Aktion nicht bei jedem neuen Besuch in der Szene nochmals ausführen müssen. Speicherung von ausgeführten Aktionen, das ist , glaube ich, mein Problem. Es war doch immer so einfach, bei Indy oder Monkey Island oder all' den anderen Spielen, F5 gedrückt und das Spiel war gesichert, falls man beim nächsten Problem "in den Brunnen" fällt. Gruß Nordseekrabbe
  4. nordseekrabe

    Save/ Open Scene

    Moin, konnte bislang bei meiner Suche zum o.g. Thema nicht fündig werden. Meine Frage ist: wie kann ich per Script die Methoden Save Scene As und Open Scene aus dem Unity-Menue "File" einsetzen ? Dabei ist mein Gedanke, vor einem Szenenwechsel den aktuellen Stand der laufenden Szene per Scripting zu speichern, die dann unter neuem Namen auch jederzeit in diesem Stadium wieder geladen werden könnte (open scene). Geht das überhaupt ? Wie immer besten Dank für Eure Anregungen ! Gruß Nordseekrabbe
  5. nordseekrabe

    Gameobject im Szenenwechsel

    Moin, inzwischen bin ich mit der Entwicklung meines Projektes ein ganzes Stück weiter gekommen und habe nun auch das Inventar mit dem neuen UI-Design umgesetzt. Soweit klappt auch die Aufnahme eines Objektes in das Inventar, wird in die neuen Szenen mitgenommen, nur beim Zurückgehen in seine Ursprungs-Szene verschwindet das Objekt leider nicht nur aus der Szene (in der es ursprünglich war und wie gewünscht), sondern auch aus dem Inventar. Den Code von oben habe ich übernommen; es scheint also, dass if (itemScene.itemID == itemInventory.itemID) { print("Doppeltes Item '" + itemScene.gameObject + "' zerstört"); Destroy(itemScene.gameObject); } das Objekt komplett "zerstört". Das konnte ich bislang nicht unterbinden. Wo klemmt es, was mache ich falsch ? Für jede Anregung bin ich sehr dankbar. Gruß von der Ostseeküste Nordseekrabbe
  6. nordseekrabe

    Inventar und Objekte

    Guten Abend, Jolinah, besten Dank für Deine Antwort. Ich hatte es schon befürchtet, dass das mit dem "alten" OnGUI() zusammenhängen könnte. Das Auskommentieren von RemoveDublicats() hat leider keinen Erfolg gebracht. Mit dem neuen GUI habe ich schon heftige Kämpfe ausgefochten, es gibt ja eine Vielzahl von (vermeintlichen) Tutorials hierzu. Meine Unwissenheit und häufig die Kompliziertheit der Beispiele (eigentlich möchte ich doch nur einige Objekte in den Szenen sammeln und dann für irgendwelche Tasks einsetzen und nicht 'Stacken' und 'Typisieren' und und..) haben mich bisher (wieder einmal) scheitern lassen. Ein guter Tipp zu einem einfachen(!!!) Inventory wäre also eine sehr große Hilfe ! Euch allen wünsche ich eine gute neue Woche und grüße wie immer von der Ostseeküste Nordseekrabbe
  7. nordseekrabe

    Inventar und Objekte

    Da ich immer noch beim Inventory und den Objekten bin, bleibe ich mal in diesem Thread...ich hoffe, das ist okay ? Wenn ich die Szene mit 2 oder mehreren Objekten im Inventar verlasse, bleiben sie lediglich für einen Szenenwechsel vorhanden, beim nächsten Wechsel sind sie gelöscht, mit der Fehlermeldung: GUI Error: You are pushing more GUIClips than you are popping Was ist das denn ? Das Inventory-Script ist oben noch vorhanden, habe allerdings die if-Bedingung(nur!! das if) mit GUI.Button und die folgenden Befehle gelöscht (print und RestoreFrom....); hinzugefügt ist das Szenenwechsel-Script, was jedem Objekt, das mit aus der Szene mitgenommen werden soll, zugewiesen bekommt. using UnityEngine; using UnityEngine.SceneManagement; public class Szenenwechsel : MonoBehaviour { [HideInInspector] public Aktionsmanager aktionsManager; InteraktivesElement interaktivitaet; public Room zimmer; public enum Room { Arbeitszimmer, Badezimmer, Bibliothek, Diele, Kueche, Wohnzimmer } void Start() { aktionsManager = GameObject.Find("Aktionsmanager").GetComponent<Aktionsmanager>(); interaktivitaet = GetComponent<InteraktivesElement>(); } void OnMouseDown() { if (aktionsManager.aktuelleAktion == "Gehe zu" && interaktivitaet.begehbar) { // die Diele ist der Startraum if (zimmer == Room.Arbeitszimmer) SceneManager.LoadScene(7); if (zimmer == Room.Badezimmer) SceneManager.LoadScene(8); if (zimmer == Room.Bibliothek) SceneManager.LoadScene(9); if (zimmer == Room.Kueche) SceneManager.LoadScene(29); if (zimmer == Room.Wohnzimmer) SceneManager.LoadScene(38); } } } Inventar als empty GO mit zugewiesenem Inventory-Script und DontDestroyOnLoad(gameObject)-Script ist als Prefab in jeder Szene. Wie komme ich aus diesem Dilemma. Wie immer, jeder Tipp hilft lernen und weiterkommen; besten Dank und schönes Wochenende Gruß Nordseekrabbe
  8. nordseekrabe

    Objekt im Objekt finden

    eine prima verständliche Erläuterung zu meinem Problem mit den "Public Objekten, danke. Was mir besonders missfällt ist folgendes: z.B. im Script ObjektOeffnen werden 3 Objekte public deklariert und müssen dann in der Szene im Inspektor zugewiesen werden. Wenn ich nun aber die Szene wechsele und dort einem ganz anderen Objekt das ObjektOeffnen-Script zuweise, muss ich auch hier im Inspektor nicht nur das neue Objekt zuweisen , sondern auch die 3 anderen Objekte aus der vorherigen Szene, oder etwa nicht ? Zumindest erscheinen die 3 Slots auch im Inspektor in der neuen Szene. Oder können die dann einfach leer bleiben, wenn diese Objekte in der neuen Szene nicht benötigt werden ? Sonst wird das doch ein riesiger "Schwanz", wenn in meinetwegen 30 Szenen irgendwelche Objekte mit dem ObjektOeffnen-Script arbeiten. Ich hoffe, das mein Unbehagen ein Stück weit nachvollziehbar ist.
  9. nordseekrabe

    Inventar und Objekte

    Es war tatsächlich, wie Du vermutest hattest, ein Buchstabenverdreher im ItemScript-Slot. Nachdem behoben, hat alles, wie gewünscht, geklappt. Der Hinweis mit dem "neuen" Inventory war Gold wert; besten Dank dafür. Mit der Aktivierung der Components (enabled = true) oder des gesamten Objektes (SetActive(true)) über eine public Deklaration und dann einer (erzwungenermaßen) Zuweisung im Inspektor bin ich noch nicht glücklich. Versuche einmal, andere Lösungen in den zahlreichen Unity-Tuts zu finden. Aber jetzt bin ich erst einmal wieder einen kleinen Schritt weiter. Jetzt hat uns wohl der Herbst gefunden, heute regnet es seit langem wieder einmal in Kiel. Dennoch ein schöner Tag an alle wünscht Nordseekrabbe
  10. nordseekrabe

    Inventar und Objekte

    Ja, stimmt...Im Inspektor erscheint tatsächlich im Slot des Inventory-Scripts als Element 0 der Schraubenzieher im Moment des "Nimm" -Befehls. Jetzt heißt es herausfinden, woran die Methode FindItemByName("Schraubenzieher") scheitert. Morgen ist aber auch noch ein Tag, erst einmal vielen Dank! Nordseekrabbe
  11. nordseekrabe

    Inventar und Objekte

    Moin, Jolinah, danke für die rasche Antwort. Habe die Anregungen übernommen. DerEinsatz von "Inventory.Instance" hat zumindest keine Fehlermeldung gebracht, die Objekte sind im Inventar-Display wie gehabt mit Image und Name vorhanden. Eine Kontrolle im Inspektor habe ich derzeit nicht. Bei der Bedingungskonstellation wird die neue Syntax( Inventory.Instance.FindItemByName("Schraubenzieher") != null) zwar angenommen, aber das Programm springt weiterhin in den Else-Befehl. D.h. dann wohl, dass das Programm das Objekt nicht im Inventar findet. Könnte das daran liegen, dass die Methode nach einem Item(Itemname) sucht, der Schraubenzieher aber als GameObject deklariert ist ? Die Veränderung, wie von Dir empfohlen, von PlaceItemToInventar(Item myItem) klingt gut, aber wie kann Raycast ein Item finden ? einen schönen Abend wünscht Nordseekrabbe
  12. nordseekrabe

    Objekt im Objekt finden

    Eine Frage hätte ich noch zum besseren Verständnis: malzbie gibt die Objekte immer mit public in den Inspektor, was aber doch unglaublich aufwendig ist. Wenn ich im gesamten Spiel sagen wir mal 100 Objekte habe, die ich in irgendeiner Szene dann mal brauche, muss ich aber in jeder Szene unter den entsprechenden Scripts das Objekt eintragen, oder ? "Public" dient doch aber an sich für den Zugriff auf ein fremdes Script. Dann sollte doch [HideInInspector] public Object auch funktionieren, oder habe ich da etwas nicht verstanden ?
  13. nordseekrabe

    Inventar und Objekte

    Moin, liebe Unityfreunde, mit meinem Inventory kämpfe ich immer wieder und versuche dabei, die Zusammenhänge in Unity besser zu verstehen. Jetzt stellt sich eine neue Frage: meine Scripte erlauben, ein Objekt in der Szene durch anklicken des Kontext-Buttons "Nimm" in das Display des Inventars zu platzieren, sichtbar sind Image und Itemname, und das Objekt verschwindet aus der Szene. Allerdings sehe ich im Inspektor unter dem Objektaufnehmen-Script weiterhin eine 0 bei Size von ItemsInInventory ? Bei dem Versuch, eine Aktion mit der Bedingung, ein bestimmtes Objekt im Inventar vorhanden zu haben, springt das Programm zur Else-Variante "Objekt nicht vorhanden", obwohl dieses Objekt gleichzeitig im InventarDisplay dargestellt ist. Daraus schließe ich, dass mit dem Aufnehmen tatsächlich nur Image und Itemname ins Inventardisplay geschoben werden, aber nicht in die List<Item> itemsInInventory gelangen. Dies sollte doch eigentlich die Methode PlaceItemInInventory(GameObject obj) übernehmen ? Was mache ich falsch ? Für jeden Hinweis, Tipp bin ich wie immer sehr dankbar. Grüße von der Ostseeküste bei herrlichem goldenen Oktober Nordseekrabbe using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class Inventory : MonoBehaviour { private static Inventory m_Instance; public static Inventory Instance { get { return m_Instance; } } public List<Item> itemsInInventory = new List<Item>(); public Rect windowRect = new Rect(30, 30, 140, 300); public int windowScrollWidth = 140 - 20; public int windowScrollHeight = 300 - 30; public int windowScrollSize = 50; private Vector2 scrollPosition = Vector2.zero; private RaycastHit hit; private Ray ray; public bool showInventory = false; private void Awake() { if (m_Instance != null && m_Instance != this) { Destroy(this.gameObject); } else { m_Instance = this; } DontDestroyOnLoad(gameObject); } private void OnEnable() { //tell our "OnLevelFinishedLoading" function to start listening for scene change as soon as this script is enabled SceneManager.sceneLoaded += OnLevelFinishedLoading; } private void OnDisable() { //tell our "OnLevelFinishedLoading" function to stop listening for a scene change as soon as this script is diabled. // Remember to always have an unsubscription for every delegate you subscribe to ! SceneManager.sceneLoaded -= OnLevelFinishedLoading; } void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode) { //Debug.Log("Level Loaded: " + scene.name); RemoveDublicates(); } private void RemoveDublicates() { Item[] allItems = FindObjectsOfType<Item>(); foreach (Item itemInventory in itemsInInventory) { foreach (Item itemScene in allItems) { if (itemScene.itemName == itemInventory.itemName) { print("Doppeltes Item '" + itemScene.gameObject + "' zerstört"); Destroy(itemScene.gameObject); } } } } private void Start() { for (int i=0; i< itemsInInventory.Count; i++) { itemsInInventory[i].gameObject.SetActive(false); // Item deaktivieren, wenn bereits im Inventar } Item find = itemsInInventory.Find(x => x.itemName.Contains("")); if (find != null) print("gefunden"); } private void Update() { if (Input.GetKeyDown(KeyCode.I)) showInventory = !showInventory; ray = Camera.main.ScreenPointToRay(Input.mousePosition); } public void PlaceItemToInventar(GameObject obj) { Item collectedItem = obj.GetComponent<Item>(); if (collectedItem != null) { itemsInInventory.Add(collectedItem); DontDestroyOnLoad(obj); obj.SetActive(false); } } public void RestoreItemFromInventar(int index) { if (index >= itemsInInventory.Count) return; // falscher Index Item item = itemsInInventory[index]; item.gameObject.SetActive(true); string name = item.gameObject.name; // Namen zischenspeichern GameObject newItemGO = Instantiate(item.gameObject); // Item duplizieren, damit DontDestroyOnLoad verschwindet DestroyImmediate(item.gameObject); newItemGO.name = name; // Namen zurücksetzen itemsInInventory.RemoveAt(index); // Item aus dem Inventar nehmen } public Item FindItemByName(string itemName) { for (int i = 0; i < itemsInInventory.Count; i++) { if (itemsInInventory[i] != null) { if (itemsInInventory[i].GetComponent<Item>().itemName == itemName) { return itemsInInventory[i]; } } } return null; } private void OnGUI() { if (showInventory) windowRect = GUI.Window(0, windowRect, DoMyWindow, "Inventar"); } void DoMyWindow(int windowID) { int x = 10; int y = 20; scrollPosition = GUI.BeginScrollView(new Rect(10, 20, windowScrollWidth, windowScrollHeight), scrollPosition, new Rect(10, 10, windowScrollWidth + windowScrollSize, windowScrollHeight + windowScrollSize)); for (int i=0; i<itemsInInventory.Count; i++) { GUI.Label(new Rect(x + 52, y + 10, 85, 50), itemsInInventory[i].itemName); if (GUI.Button(new Rect(x, y+1, 48, 48), itemsInInventory[i].itemImage)) { // Button Listener print("Item '" + itemsInInventory[i].name + "' zurückgelegt"); RestoreItemFromInventar(i); } y += 50; } GUI.EndScrollView(); GUI.DragWindow(); } } using UnityEngine; using System.Collections.Generic; public class ObjektAufnehmen : MonoBehaviour { [HideInInspector] public Aktionsmanager aktionsManager; InteraktivesElement interaktivitaet; public Room zimmer; public List<Item> itemsInInventory = new List<Item>(); private Inventory myInventory; private RaycastHit hit; private Ray ray; private Item Schraubenzieher; public enum Room { Arbeitszimmer, Badezimmer, Bibliothek, Diele, Kueche, Wohnzimmer } void Start() { aktionsManager = GameObject.Find("Aktionsmanager").GetComponent<Aktionsmanager>(); interaktivitaet = GetComponent<InteraktivesElement>(); myInventory = GameObject.Find("Inventar").GetComponent<Inventory>(); Schraubenzieher = gameObject.GetComponent<Item>(); } void Update() { ray = Camera.main.ScreenPointToRay(Input.mousePosition); } private void OnMouseDown() { if (aktionsManager.aktuelleAktion == "Nimm" && interaktivitaet.aufnehmbar && interaktivitaet.ansehbar && interaktivitaet.zuuntersuchen) { if (zimmer == Room.Diele) // Zettel , nur Test { aktionsManager.Infotext.text = "Kann ja nicht schaden, den Zettel zu lesen!"; if (Physics.Raycast(ray, out hit, 20)) { myInventory.PlaceItemToInventar(hit.collider.gameObject); } } if (zimmer == Room.Kueche) { aktionsManager.Infotext.text = "Der Schraubenzieher ist unser!"; if (Physics.Raycast(ray, out hit, 20)) { myInventory.PlaceItemToInventar(hit.collider.gameObject); } } } } } using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class ObjektOeffnen : MonoBehaviour { [HideInInspector] public Aktionsmanager aktionsManager; InteraktivesElement interaktivitaet; public Room zimmer; public List<Item> itemsInInventory = new List<Item>(); private Inventory myInventory; private Item collectedItem; private Item Schraubenzieher; public enum Room { Arbeitszimmer, Badezimmer, Bibliothek, Diele, Kueche, Wohnzimmer } void Start() { aktionsManager = GameObject.Find("Aktionsmanager").GetComponent<Aktionsmanager>(); interaktivitaet = GetComponent<InteraktivesElement>(); Inventory m_Inventory = FindObjectOfType<Inventory>(); itemsInInventory = m_Inventory.itemsInInventory; Schraubenzieher = gameObject.GetComponent<Item>(); } private void OnMouseDown() { if (aktionsManager.aktuelleAktion == "Öffne" && interaktivitaet.zuoeffnen && interaktivitaet.einschaltbar) { if (zimmer == Room.Kueche) // Dunstabzug { Debug.Log("wir sind in der Küche"); if (itemsInInventory.Find(x => x.itemName.Contains("Schraubenzieher"))) { print("Item gefunden!"); Vokabelheft.GetComponent<SpriteRenderer>().enabled = true; Vokabelheft.GetComponent<InteraktivesElement>().enabled = true; aktionsManager.Infotext.text = "Mit dem Schraubenzieher gelingt es dir, alle Schrauben zu lösen und" + "in den Dunstabzug hineinzugreifen."; } else { print("Item nicht gefunden!"); aktionsManager.Infotext.text = "Nun ja, von ganz alleine fällt der Dunstabzug nicht auseinander."; } } } } }
  14. nordseekrabe

    Objekt im Objekt finden

    Tausend Dank, habe sicher beim Coden einige Fehler gemacht, denn im Prinzip hatte ich oben beschriebene Aktivierungen und Deaktivierungen versucht. Habe jetzt aber für mich die einfachste Lösung gefunden: FleischObjekt ist Child von Kühlschrank und ist als Objekt zunächst deaktiviert (und damit auch alle Componenten obwohl mit Häkchen versehen). Mit dem Öffnen des Kühlschrankes wird gleichzeitig auch das Fleischobjekt aktiviert (SetActice(true). So habt Ihr beide es auch beschrieben. Super, wieder eine offene Frage weniger. Einen schönen Abend und ein sonniges Wochenende Nordseekrabbe
  15. nordseekrabe

    Objekt im Objekt finden

    Sehr gutes Tutorial, wie auch all die anderen, die ich natürlich bereits durchgearbeitet habe, ohne behaupten zu wollen, alles verstanden zu haben, geschweige denn verinnerlicht zu haben. Das ist das grundsätzliche Problem des Laien, der sich autodidaktisch in eine solche Materie einarbeiten will, ohne eigentlich das umfassende Grundwissen zur Programmierung zu haben. Daher behaupte ich jetzt einfach mal, das das empfohlene Tut zu meinem Problem nicht weiterhilft. Das Problem ist (ja inzwischen), von einem Script (hier: "ObjektÖffnen") ein anderes Script (hier: "InteraktivesElement") enabled/disabled zu steuern. Beide Scripte liegen auf dem GO "Fleischbrocken" und "InteraktivesElement" ist disabled, weil ja bei geschlossenem Kühlschrank weder das Fleisch benannt noch sonst wie bearbeitet werden soll/kann. In dem Moment, in dem der Kühlschrank geöffnet wird, wird das Fleisch sichtbar (SpriteRenderer enabled), das Script "InteraktivesElement" sollte jetzt auch enabled werden. if (aktionsManager.aktuelleAktion == "Öffne") { if (zimmer == Room.Kueche) { GetComponent<Renderer>().enabled = true; //das Bild des offenen Kühlschrankes erscheint aktionsManager.Infotext.text = "Hoppla, da liegt ja ein riesiger Brocken Fleisch im Kühlschrank."; Fleischbrocken.gameObject.SetActive(true); Fleischbrocken.GetComponent<Renderer>().enabled = true; } } Das oben beschriebene Procedere gelingt mit dem genannte Code. Es fehlt eine entsprechendes Enabled für das Script "InteraktivesElement" des Fleischbrockens, weil mir dazu eine sinnvolle Syntax nicht gelingen will. Und das ist die Frage mit der ich um ein wenig Anregung bitten wollte. Nordseekrabbe
×