当前位置: 首页 > 知识库问答 >
问题:

如何在重新加载场景时使我的单例单行为类实例以新的方式开始?

谯皓君
2023-03-14

我有一个带有“LevelManager”单例实例(并与之接口)的“SingletonManager”类。“LevelManager”GameObject不应该在整个应用程序生命周期内持久存在,并且应该在每次加载新级别时替换为新实例。

在运行我当前的代码时,当场景第二次加载时,“LevelManager”似乎丢失了,尽管场景中有GameObject(附加脚本)。我意识到这可能是因为我仍在尝试访问旧的参考。

确保我的“SingletonManager”在每次加载新级别时都保存“LevelManager”的新实例的最佳方法是什么?

我的代码(删除不相关项):

SingletonManager:

public class SingletonManager
{
    private static LevelManager instance;
    public static ILevelManager Instance
    {
        get
        {
            if (this.levelManager == null)
            {
                this.levelManager = GameObject.FindObjectOfType(typeof(LevelManager)) as LevelManager;
            }
            return this.levelManager;
        }
    }
}

Singleton不是持久的:

public class Singleton<Instance> : MonoBehaviour where Instance : Singleton<Instance> {
    public static Instance instance;
    public bool isPersistant;

    public virtual void Awake() {
        if(isPersistant) {
            if(!instance) {
                instance = this as Instance;
            }
            else {
                DestroyObject(gameObject);
            }
            DontDestroyOnLoad(gameObject);
        }
        else {
            instance = this as Instance;
        }
    }
}

共有2个答案

顾学真
2023-03-14

简单解决方案:

为级别经理创建一个经理。它应该是持久的,并且有一个LevelManager预置数组(我假设您是从预置中实例化它们的?)。加载每个级别时,让它生成适当的LevelManager预制(或构建它或创建它所需的任何东西)。

每个级别管理器只需将实例设置为唤醒,并让级别在最后销毁它。(即,你的非持久性单身。)

public class LevelManagerSpawner
{
    public GameObject[] LevelManagerPrefabs;

    void OnLevelWasLoaded( int levelNumber )
    {
        Instantiate( LevelManagerPrefabs[ levelNumber ] );
    }
}
虞华翰
2023-03-14

我从你的问题中了解到,随着游戏阶段的变化,你需要一个新的对象,如果我理解正确,这可能会对你有所帮助
尝试使用Multiton模式解决方案<这里有一个例子

class levelManager {
    private static readonly Dictionary<object, levelManager> _instances = new Dictionary<object, levelManager>();

    private levelManager() {
    }

    public static levelManager GetInstance(object key) { // unique key for your stage
        lock (_instances) {   
            levelManager instance;
            if (!_instances.TryGetValue(key, out instance)) {
                instance = new levelManager();
                _instances.Add(key, instance);
            }
            return instance;
        }
    }
}

注意:-我只给你举了一个例子,不适合你的类
参考链接:http://en.wikipedia.org/wiki/Multiton_pattern

 类似资料:
  • 问题内容: 背景: 我有一个MainTest类,其中包含许多按钮,每个按钮都实例化我正在编码/测试的类。我希望这些类的代码/测试周期更快,并希望每分钟几次快速查看更改的效果。稳定的MainTest大约需要20秒的加载时间,如果我实例化的类中的每个更改都不需要重新加载它,这将不是问题。我想一次加载MainTest,当它实例化另一个类时,我们多次调用它为ChildTest(通过按钮事件),它应该重新加

  • 问题内容: 我有2个fxml文件: 布局(标题,菜单栏和内容) Anchorpane(应该放在另一个fxml文件的内容中) 我想知道如何从“主”场景将第二个文件加载到内容空间内。在javaFX中工作是一件好事,还是加载一个新场景更好? 我正在尝试做这样的事情,但是不起作用: 谢谢您的帮助。 问题答案: 为什么您的代码不起作用 加载程序会创建一个新的AnchorPane,但是您绝不会将新窗格添加到场

  • null 我正试着做这样的事情,但它不起作用: 谢谢你的帮助。

  • 问题内容: 今天,在我的采访中,一位面试官要求我写一个单例课程。我给我的答案是 突然他告诉我这是上课的老方法。谁能帮我他为什么这么说。 问题答案: 创建单例时,我想到的第一件事是。我通常使用enum实现单例: 使用枚举可为您带来的好处之一就是序列化。 对于单例类,您将必须确保通过实现方法来确保序列化和反序列化不会创建新实例,而enum并非如此。 使用类,您应该这样创建单例:

  • 在这个情景下,委托就可以帮助我们了。我们直到我们的单例不会是null,但是我们不能使用构造函数去初始化属性。所以我们可以使用notNull委托: class App : Application() { companion object { var instance: App by Delegates.notNull() } override fun onCr

  • 问题内容: 目标:实施标准的“设置” GUI窗口。类别位于 ListView左侧,而相应选项位于Pane右侧。 (请忽略具有重复类别的明显错误;仍在处理) 在此处输入图片说明 我有一个用于整体“设置”窗口的主窗口,其中包含 ListView带有所有类别的设置。窗口的右侧 具有AnchorPane, 当从列表中选择一个类别时,用于为每个类别加载单独的FXML文件。 当用户选择类别时,我需要他们能够编