在场景之间传递的最佳方式是啥? [复制]

Posted

技术标签:

【中文标题】在场景之间传递的最佳方式是啥? [复制]【英文标题】:What is the best way to pass between scenes? [duplicate]在场景之间传递的最佳方式是什么? [复制] 【发布时间】:2019-12-14 08:47:27 【问题描述】:

我有 3 个场景。游戏,主菜单,经理。 在管理器上,我有一个带有保存管理器脚本的保存管理器对象:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System;
using System.IO;

public class SaveManager : MonoBehaviour

    public static void Save(SaveState player)
    
        BinaryFormatter formatter = new BinaryFormatter();
        string path = Application.persistentDataPath + "/player.bin";
        FileStream stream = new FileStream(path, FileMode.Create);

        formatter.Serialize(stream, player);
        stream.Close();
    

    public static SaveState Load()
    
        string path = Application.persistentDataPath + "/player.bin";
        if (File.Exists(path))
        
            BinaryFormatter formatter = new BinaryFormatter();
            FileStream stream = new FileStream(path, FileMode.Open);

            SaveState data = formatter.Deserialize(stream) as SaveState;
            stream.Close();

            return data;
        
        else
        
            Debug.LogError("Save file not found in " + path);
            return null;
        
    

还有一个类: 这个 Save State 类应该稍后处理游戏中所有事物的状态。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

[Serializable]
public class SaveState

    [Serializable]
    public struct SerializableVector3
    
        public float X;
        public float Y;
        public float Z;

        public SerializableVector3(Vector3 v)
        
            X = v.x;
            Y = v.y;
            Z = v.z;
        

        // And now some magic
        public static implicit operator SerializableVector3(Vector3 v)
        
            return new SerializableVector3(v);
        

        public static implicit operator Vector3(SerializableVector3 sv)
        
            return new Vector3(sv.X, sv.Y, sv.Z);
        
    

    [Serializable]
    public struct SerializableQuaternion
    
        public float X;
        public float Y;
        public float Z;
        public float W;

        public SerializableQuaternion(Quaternion q)
        
            X = q.x;
            Y = q.y;
            Z = q.z;
            W = q.w;
        

        public static implicit operator SerializableQuaternion(Quaternion q)
        
            return new SerializableQuaternion(q);
        

        public static implicit operator Quaternion(SerializableQuaternion sq)
        
            return new Quaternion(sq.X, sq.Y, sq.Z, sq.W);
        
    

    public SerializableVector3 position;
    public SerializableQuaternion rotation;
    public SerializableVector3 scale;

    public SaveState(Vector3 pos, Quaternion rot, Vector3 sca)
    
        position = pos;
        rotation = rot;
        scale = sca;
    

    public void ApplyToPlayer(Transform player)
    
        player.localPosition = position;
        player.localRotation = rotation;
        player.localScale = scale;
    

以及在游戏场景中附加到玩家的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerState : MonoBehaviour

    public void Save()
    
        SaveState saveState = new SaveState(transform.localPosition,
            transform.localRotation, transform.localScale);
       SaveManager.Save(saveState);
    

    public void Load()
    
        var playerInfo = SaveManager.Load();
        playerInfo.ApplyToPlayer(transform);
    

在此之前,PlayerState 与 SaveManager 具有相同的场景,我在 Update 中使用输入键来保存和加载,它工作正常。

现在我想使用更新和输入键来使用我拥有的主菜单场景 ui 按钮保存和加载。问题是播放器是一个场景,主菜单是另一个场景,当玩家开始新游戏时,播放器被卸载并再次加载的场景会丢失主菜单 ui 按钮中的引用。

Save System 下 Main Menu 中的 Save/Load ui 按钮,这是我想在 On Click 事件中调用 PlayerState 脚本中的 Save/Load 函数的 ui 按钮。

【问题讨论】:

【参考方案1】:

我认为你最好的选择是确保你的经理和你的 UI 是持久的,所以只需设置:

private void Awake()

    DontDestroyOnLoad(this);

然后在他们的更新中只有一个 switch 语句检查当前场景,因此您将只更新该场景所需的内容,如下所示:

private void Update()

    switch(SceneManager.GetActiveScene().name)
    
        case "Game":
            //Do you game update stuff...
            break;

        case "Menu":
            //Do your menu update stuff...
            break;
    

希望对你有帮助:)

【讨论】:

以上是关于在场景之间传递的最佳方式是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

在线程之间传递信息的最佳方式是啥?

对于使用 Facebook iOS SDK 的混合 SSO 场景,为我们自己的自定义用户记录生成密码/密钥的最佳方式是啥?

在视图控制器/情节提要场景之间传递核心数据结果

几种在场景之间传递数据的方式

几种在场景之间传递数据的方式

SpriteKit:在场景之间传递数据