Jump to content
Unity Insider Forum

Versändnissfrage zum Thema Scene Load


Kojote

Recommended Posts

Grüße!

Ich hab ein mittelgroßes Verständnissproblem beim Scenenladen:

Ich möchte die erste Spielwelt laden und nutze zum Aufruf das:

        public void LoadFirstScene() {
            Cursor.visible = false;
            LD_SP_System_Settings.Instance.MusicVolFadeOut(0.05f);
            instance.StartCoroutine(instance.LoadSceneCoroutine(2)); // Geladen wird die erste Welt 
            instance.StartCoroutine(instance.LoadFirstSceneDisplayCoroutine());
        }

Startet im Endeffekt die Scenen-Ladung:

        private IEnumerator LoadSceneCoroutine(int scene) {
            yield return new WaitForSeconds(1.5f);
            async = SceneManager.LoadSceneAsync(scene, LoadSceneMode.Single);
            async.allowSceneActivation = false;
            while (!async.isDone) {
                float progress = Mathf.Clamp01(async.progress / 0.9f);
                sliderDisplay.value = progress;
                yield return null;
            }
        }

Und die bissl Optik drum herum:

        private IEnumerator LoadFirstSceneDisplayCoroutine() {
            // Schwarz ausblenden
            animSceneBlend.SetBool("Fade", false);
            yield return new WaitUntil(() => sceneBlendImage.color.a == 1);

            // Kurze Wartezeit
            yield return new WaitForSeconds(0.1f);

            // Hintergrundbild einblenden
            animSceneLoadingScreenBlend.SetBool("Fade", true);
            yield return new WaitUntil(() => sceneBlendImage.color.a == 1);

            // Slider einblenden
            sliderCG.alpha = 1;

            // Kurze Wartezeit
            yield return new WaitForSeconds(2);

            // Warten bis der Ladezyklus beendet ist
            do {
                yield return new WaitForFixedUpdate();
            } while (async.progress < 0.9f);

            // Einfügen der Spieleobjekte
            LD_SP_Spawn_Controler.Instance.FirstGameStartInitialisation();

            // Slider ausblenden
            sliderCG.alpha = 0;

            // Hintergrundbild einblenden
            animSceneLoadingScreenBlend.SetBool("Fade", false);
            yield return new WaitUntil(() => sceneBlendImage.color.a == 0);

            // Kurze Wartezeit
            yield return new WaitForSeconds(0.1f);

            // Scene freigeben
            async.allowSceneActivation = true;
        }
    }

Problem ist nun diese Zeile:

LD_SP_Spawn_Controler.Instance.FirstGameStartInitialisation();

In dieser Zeile wird nun aufgerufen, was auf der Spielwelt für gespeicherte Dinge geladen werden sollen. Derzeit ist es nur der Spieler. Später sollen noch Enemys, Wetterdaten und sonstwas hinzukommen. Problem ist, diese Scriptkomponente befindet sich in der neuen Scene, scheint sie aber nicht aufrufen zu können, wieso? Sucht er danach in der alten Scene? Ich könnte die Methode ja auch in der neuen Scene über Awake aufrufen, aber dann habe ich wieder zwei Probleme:

1. Beim allerersten Spielstart werden mehrere Parameter für das Spiel gesetzt, stecke ich das nun in die Awake Methode in der neuen Scene, wird das jedes mal ausgeführt, wenn ich die Scene starte.

2. Wenn erst der Spieler und die Enemys geladen werden, wenn der Spieler schon was sehen kann wirkt dies sehr unschön.

Könnt ihr mir nen Rat geben, glaub bei mir steht einer auf dem Schlauch.🤨

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du könntest die Daten in einer statischen Klasse oder einem ScriptableObject speichern. In der neuen Scene lädt sich das jeweilige Objekt selbst und referenziert die Klasse/ das ScriptableObject und nimmt dessen Daten in Awake oder wo auch immer.

Finden tut er dein Objekt wahrscheinlich nicht, weil dieses zum Zeitpunkt des Aufrufs noch nicht "da" ist, sprich geladen wurde.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich hab ScriptableObjects noch nie genutzt, hab mir gerade mal nen Tutorial angesehen. Is schon net schlecht da Teil.

Ich hab ne Klasse die ich eh brauche für den Chrakter und nen ScriptableObjects wo ich alles drin speichere. Problem ist, bzw. was ich nicht verstehe. Wenn ich nun den Spieler und 50 Enemys speichern will, brauche ich die Daten aus den ScriptableObjects, wie soll ich sie dann speichern, wenn ich JSON nutze?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Versteh ich jetzt nicht ganz.

Ich habe z.B. einen Spieler und 50 Enyms, die möchte ich nun alle in einem Haufen speichern, dass ich alles in Spielstand 1 habe und von da auch wieder laden kann, um den Spieler auf der Map und alle Enyms initialisieren kann.

Ich brauche also ein Listenobjekt was ich durch JSON speichern kann, mach ich z.B. bei mir hier:

LD_SP_Save_Data_Object_Manager.BasicDataInstance = JsonUtility.FromJson<LD_SP_Save_Data_Object_Manager>(json);

Im Endeffekt ist das ja schon ungefähr das was ich mache. Ich speichere es in Objekten, die dann der jeweiligen List zugeordnet werden.

        public List<LD_SP_Save_Data_Player> characterList;
        public List<LD_SP_Save_Data_Child> childList;
        public List<LD_SP_Save_Data_Enemy> enemyList;

Zum Beispiel für den Enemy:

    [System.Serializable]
    public class LD_SP_Save_Data_Enemy {
        // Keinesfalls von Monobehavior erben lassen, dies zerstoert die JSON-Datei!
        public animalTyp animalTyp;
        public int enemyID;
        public string enemyName;
        public int enemyVitaility;
        public int enemyMana;
        public Vector3 enemyPos;
        public Quaternion enymyRotation;


        public LD_SP_Save_Data_Enemy(animalTyp type, int id, string name, int vit, int mana, Vector3 pos, Quaternion rot) {
            animalTyp = type;
            enemyID = id;
            enemyName = name;
            enemyVitaility = vit;
            enemyMana = mana;
            enemyPos = pos;
            enymyRotation = rot;
        }
    }

Für jeden Enemy wird ein Objekt der Klasse LD_SP_Save_Date_Enemy  erstellt, wenn ich speichere.

Gut, man könnte nun sagen, jeder Enemy erzeugt nun selbst sein eigenes Scriptable Object in das er seine Daten speichert. Wenn ich nun Speichern klicke, muss ich aber trotzdem alle diese ScriptableObjects finden, in eine Liste packen, damit alles zusammen dann in eine JSON gepackt wird.

Ich sehe da nun wie gesagt nur den Unterschied das ich ein Objekt einer Klasse nutze, ich alternativ ein ScriptableObject hätte. Oder sehe ich das was falsch?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich schreib so was, dass erste mal, von daher vielleicht nicht 100% der beste weg.

Es geht darum, dass ich Daten von Spieler und Enyms speichern möchte.

Dazu habe ich mir wie gesagt, z.B. so eine Klasse für die Enyms angelegt:

[System.Serializable]
    public class LD_SP_Save_Data_Enemy {
        // Keinesfalls von Monobehavior erben lassen, dies zerstoert die JSON-Datei!
        public animalTyp animalTyp;
        public int enemyID;
        public string enemyName;
        public int enemyVitaility;
        public int enemyMana;
        public Vector3 enemyPos;
        public Quaternion enymyRotation;


        public LD_SP_Save_Data_Enemy(animalTyp type, int id, string name, int vit, int mana, Vector3 pos, Quaternion rot) {
            animalTyp = type;
            enemyID = id;
            enemyName = name;
            enemyVitaility = vit;
            enemyMana = mana;
            enemyPos = pos;
            enymyRotation = rot;
        }
    }

Oder auch diese Klasse für den Spieler:

    [System.Serializable]
    public class LD_SP_Save_Data_Player {
        // Keinesfalls von Monobehavior erben lassen, dies zerstoert die JSON-Datei!
        public string playerName;
        public string playTime;
        public int playerVitaility;
        public int playerMana;
        public int playerGender;
        public float[] playerBodyShape;
        public float[] playerBodyColor;
        public float[] playerEyeColor;
        public float[] playerNoseColor;
        public int playerBodyMaterial;
        public Vector3 playerPos;
        public Quaternion playerRotation;
        public int sceneID;
        public bool sceneSwitch;


        public LD_SP_Save_Data_Player(string name, string time, int vit, int mana, int gender, float[] bodyShape, float[] bodyColor, float[] eyeColor, float[] noseColor, int bodyMaterial, Vector3 pos, Quaternion rot, int sceneID, bool sceneSwitch) {
            playerName = name;
            playTime = time;
            playerVitaility = vit;
            playerMana = mana;
            playerGender = gender; // 0 = Female | 1 = Male
            playerBodyShape = new float[bodyShape.Length];
            playerBodyColor = new float[bodyColor.Length];
            playerEyeColor = new float[eyeColor.Length];
            playerNoseColor = new float[noseColor.Length];
            Array.Copy(bodyShape, playerBodyShape, bodyShape.Length);
            Array.Copy(bodyColor, playerBodyColor, bodyColor.Length);
            Array.Copy(eyeColor, playerEyeColor, eyeColor.Length);
            Array.Copy(noseColor, playerNoseColor, noseColor.Length);
            playerBodyMaterial = bodyMaterial;
            playerPos = pos;
            playerRotation = rot;
            this.sceneID = sceneID;
            this.sceneSwitch = sceneSwitch;
        }
    }

Wenn ich nun etwas speichern will, wie z.B. eben den Character auf der Karte oder die Enemys, lege ich mir über den Konstrukor ein Objekt der jeweiligen Klasse an und stecke das Objekt in eine Liste.

        public List<LD_SP_Save_Data_Player> characterList;
        public List<LD_SP_Save_Data_Child> childList;
        public List<LD_SP_Save_Data_Enemy> enemyList;

Diese Listen gehören zur Klasse "LD_SP_Save_Data_Object_Manager", diese Instanz speichere ich in JSON und lade sie wieder. Damit kann ich meine Spieldaten recht einfach speichern und laden.

Die Klasse bekommt auch irgendwann mal Daten für Wetter und Co.

So, die Klasse "LD_SP_Save_Data_Object_Manager" hällt ja wie gesagt die Daten aller Enemys und Spieler und ist dorch DontDestroyOnLoad in jeder Scene verfügbar. Ich wollte nun beim Wechsel der Scene in der neuen Scene den Spieler initialisieren aus den werten dieser Klasse. Eben mit diesem Aufruf:

LD_SP_Spawn_Controler.Instance.FirstGameStartInitialisation();

Der Chrakter muss ja irgendwie mit all seinen Daten und Einstellen vom Aussehen her in der neuen Scene geladen werden. Auch alle Enyms, Wetterdaten und sonst was, muss je beim Laden der Scene irgendwie wieder geladen werden. Draum gehts mir.

 

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich drück mich mal anders aus,

ist es möglich, beim Laden einer Scene ein Script aufzurufen und da eine Variable zu verändern?

Es ist ja ein Unterschied, ob ich die Scene das erste mal mit seinen Einstellungen lade oder einen Speicherstand dieser Scene lade, es muss ja alles etwas anders initalisiert werden.

Also müsste ich ja von einer Scene, der nächsten in der Awake Methode sagen, mache dies und jenes anders.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...