【U3D/簡單框架】1.單例模式(普通單例,mono單例)

自我介紹

廣東雙非一本的大三小白,計科專業,想在製作畢設前夯實基礎,畢設做出一款屬於自己的遊戲!

單例模式基類

  • 目的:
    1. 通過代碼設計,讓某個對象在遊戲中,永遠只存在一份:
      • 比如一個遊戲玩家只有一份角色數據
      • 比如各個遊戲模塊,都只需要獨立的一個控制器即可
    2. 約束了代碼的調用方式,讓其訪問的時候指向唯一的對象:
      • 而不是進行重複的創建對象,銷燬對象
      • 對性能而言,減少了內存垃圾回收的頻率,點點滴滴的優化,積少成多
  • 通常有兩種需求:
    1. 不需要繼承mono,因爲不需要用到生命週期:
      • 通常用在數據實體上
    2. 需要繼承mono:
      • 要用到組件上的一些生命週期
      • 通常用在模塊的控制器上
  • 代碼怎麼寫:
    • singleton:
      • 定義屬性訪問器instance
      • 用static進行聲明,就可以基於類級別進行訪問
    • MonoSingleton:
      • 建議所有繼承該類的腳本都掛載到同個對象上
      • 用bool變量來表示該對象是否在場景切換的時候銷燬,然後監聽場景變化的時間,做邏輯,根據布爾值將組件從物體上移除

BaseSingleton.cs

// where表示約束,需要這個T擁有一個無參構造函數才能作爲泛型傳進來
public class BaseSingleton<T> where T:new()
{
    private static T instance;
    public static T Instance()
    {
        if (instance == null) instance = new T();
        return instance;
    }
}

使用只需要繼承即可 BaseSingleton

// 使用
public class GameManager: BaseManager<GameManager> { }

mono單例

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

public class MonoSingleton<T> : MonoBehaviour where T: MonoBehaviour
{
    static T instance;
    //有時候,有的組件場景切換的時候回收
    public static bool destroyOnLoad = false;
    public static GameObject monoSingleton;
    public static T Instance
    {
        get
        {
            if (monoSingleton == null)
            {
                monoSingleton = new GameObject("monoSingleton");
                DontDestroyOnLoad(monoSingleton);
            }

            if (monoSingleton != null && instance == null)
                instance = monoSingleton.AddComponent<T>();

            return instance;
        }
    }

    //添加場景切換時候的事件
    public void AddSceneChangedEvent()
    {
        SceneManager.activeSceneChanged += OnSceneChanged;
    }

    private void OnSceneChanged(Scene arg0, Scene arg1)
    {
        if (destroyOnLoad == true)
        {
            if (instance != null)
            {
                DestroyImmediate(instance);     //立即銷燬
            }
        }
    }
}

使用:常規繼承,如果要在切換場景的時候銷燬,則需要在構造函數中把destroyOnLoad值設置爲true

public class TestMonoSingleton : MonoSingleton<TestMonoSingleton>
{
    public TestMonoSingleton()
    {
        destroyOnLoad = true;
    }

    public void Test()
    {
        Debug.Log("MonoSingleton...");
    }

    void Start()
    {
        AddSceneChangedEvent();
    }
}

隨便新建一個 test.cs

void Start()
{
    TestMonoSingleton.Instance.Test();
}

因爲 destroyOnLoad 值設置爲true所以如果有切換場景操作, TestMonoSingleton 腳本會自動銷燬,而不是銷燬 GameObject

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章