Unity小框架之單例模式基類

????????????????單例模式(Singleton Pattern)是一種常用的創建型設計模式,其核心目標是確保一個類只有一個實例,并提供一個全局訪問點。它常用于需要控制資源訪問、共享配置或管理全局狀態的場景(如數據庫連接池、日志管理器、應用配置等)。????????

單例模式的核心思想

  1. ?私有構造函數:防止外部通過?new?創建多個實例。
  2. ?靜態私有實例:類內部持有唯一的實例。
  3. ?全局訪問方法:提供一個靜態方法(如?getInstance())獲取唯一實例。

????????下面來介紹一下在C#和unity中實現的單例模式基類,你某些需要進行單例模式化的腳本,就可以繼承這個基類然后就實現了自己的單例化,那你就可以在其他地方進行使用了。

一、最基本的單例基類

代碼:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;//單例模式基類模塊//1.C#泛型的知識
//2.設計模式中 單例模式的知識
public class BaseManager <T> where T : new()
{//單例模式private static T instance;public static T GetInstance(){if (instance == null){instance = new T();}return instance;}
}

使用方法:

例如下面這個腳本,我們創建了一個NewBehaviourScript的腳本,然后直接繼承單例模式基類,如果其他地方需要調用,就直接使用就行

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class NewBehaviourScript : BaseManager<NewBehaviourScript>
{   void Start(){Debug.Log(NewBehaviourScript.GetInstance());}
}

再來一個示例:

// 子類繼承 BaseManager,并滿足 new() 約束
public class GameManager : BaseManager<GameManager>
{// 必須有一個公共無參構造函數public GameManager() {Debug.Log("GameManager Created");}public void Init(){Debug.Log("GameManager Initialized");}
}// 使用方式
void Start()
{
//可以在你項目中的任意一個地方進行使用GameManager manager = GameManager.GetInstance();manager.Init();// 問題:外部仍然可以 new GameManager(),破壞單例!GameManager another = new GameManager(); // 這是允許的 但是你自己選擇可以不實現 后面我們還有保護措施 使得外部不能實例化
}

二、繼承了Mono的單例模式基類

繼承了Mono那么我們就可以使用Unity的生命周期函數了

代碼:

public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour
{private static T _instance;// 使用屬性替代 GetInstance(),更符合 C# 習慣public static T Instance{get{// 如果實例不存在,嘗試查找或創建if (_instance == null){_instance = FindObjectOfType<T>();// 如果場景中沒有,自動創建一個新的 GameObjectif (_instance == null){GameObject obj = new GameObject(typeof(T).Name);_instance = obj.AddComponent<T>();}}return _instance;}}protected virtual void Awake(){// 如果實例已存在且不是當前對象,銷毀自身if (_instance != null && _instance != this){Destroy(gameObject);return;}// 初始化實例_instance = this as T;// 按需設置跨場景保留DontDestroyOnLoad(gameObject); }
}

還有個簡單的版本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;//C#泛型的知識
//設計模式中 單例模式的知識//繼承了MonoBehaviour的 單例模式對象 需要我們自己保證它的唯一性
public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour
{private static T instance;public static T GetInstance(){//繼承了MonoBehaviour的類,不能直接new//只能通過拖動到對象上 或者通過加腳本的api AddComponent//U3d內部會幫助我們直接實例化return instance;}protected virtual void Awake(){instance = this as T;}
}

請注意:繼承了這個單例模式基類的話,是不能夠自己去new的你只能拖拽到物體身上。

示例:

這樣改進是為了讓我們在沒有繼承Mono的時候,仍然能使用生命周期函數

public class AudioManager : SingletonMono<AudioManager>
{public void PlaySound(string clipName){Debug.Log("Playing: " + clipName);}
}// 使用方式
void Start()
{AudioManager.Instance.PlaySound("BackgroundMusic");
}

示例:

using UnityEngine;// 繼承 SingletonMono,并指定自身為泛型類型 T
public class SoundManager : SingletonMono<SoundManager>
{// 自定義音頻方法public void PlaySound(string clipName){Debug.Log("播放音效: " + clipName);}// 初始化音頻資源(在 Awake 中調用)protected override void Awake(){base.Awake(); // 調用基類的 Awake 方法,確保單例賦值Debug.Log("SoundManager 初始化完成");}
}

創建這樣一個空物體,掛在腳本后,其他的類里面才能使用

使用:

public class PlayerController : MonoBehaviour
{private void Start(){// 獲取 SoundManager 實例并調用方法SoundManager.Instance.PlaySound("跳躍音效");}private void Update(){// 直接通過 Instance 屬性訪問if (Input.GetKeyDown(KeyCode.Space)){SoundManager.Instance.PlaySound("射擊音效");}}
}

三、繼承了mono并且已經自己實例化的

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SingletonAutoMono<T> : MonoBehaviour where T : MonoBehaviour
{private static T instance;public static T GetInstance(){if (instance == null){GameObject obj = new GameObject();//設置對象的名字為腳本名字obj.name = typeof(T).ToString();//讓這個單例模式對象過場景不移除//因為 單例模式對象 往往是存在于整個程序生命周期中的DontDestroyOnLoad(obj);instance = obj.AddComponent<T>();}return instance;}}

使用示例:

在繼承了這個類的腳本里面直接使用內部的函數即可

public class NetworkManager : SingletonAutoMono<NetworkManager>
{public void Connect(string serverIP){Debug.Log($"連接到服務器: {serverIP}");}protected override void Awake(){base.Awake(); // 調用基類 Awake 確保單例初始化Debug.Log("網絡管理器已初始化");}
}// 使用方式
void Start()
{NetworkManager.Instance.Connect("127.0.0.1");
}

?注意事項

  1. ?手動掛載與自動創建的沖突

    • 如果手動在場景中掛載腳本,需確保只有一個實例。
    • 優化后的代碼會優先使用手動掛載的實例。
  2. ?跨場景行為

    • 若需某個單例僅在特定場景存在,移除?DontDestroyOnLoad

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/898215.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/898215.shtml
英文地址,請注明出處:http://en.pswp.cn/news/898215.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

安裝 Powerlevel10k 及 Oh My Zsh 的使用

1. 簡介 Powerlevel10k 是 Oh My Zsh 最流行的終端主題&#xff0c;它不僅美觀&#xff0c;還提供 Git 狀態顯示、命令執行時間、網絡狀態、Python 虛擬環境指示等 實用功能。相比其他主題&#xff0c;Powerlevel10k 速度更快、可定制性更強。 本教程將詳細介紹如何安裝 Powe…

verilog有符號數處理摘要

在FPGA設計中&#xff0c;一般的算數運算符都是按照無符號數進行的。那么需要有符號數計算的時候&#xff0c;該怎么辦呢&#xff1f; 很久很久以前也就是Verilog-2001還沒有出現時&#xff0c;是手動操作的&#xff0c;也就是說&#xff0c;對于一個8位的無符號數&#xff0c…

在IDEA中連接達夢數據庫:詳細配置指南

達夢數據庫&#xff08;DM Database&#xff09;作為國產關系型數據庫的代表&#xff0c;廣泛應用于企業級系統開發。本文將詳細介紹如何在IntelliJ IDEA中配置并連接達夢數據庫&#xff0c;助力開發者高效完成數據庫開發工作。 準備工作 1. 下載達夢JDBC驅動 訪問達夢官方資…

app.config.globalProperties

目錄 一:基礎使用 1、簡介 2、使用 3、打印結果: 二:封裝 1、創建一個.ts文件(utils/msg.ts) 2、在main.ts中全局注冊 3、在頁面中使用 4、打印結果 一:基礎使用 1、簡介 app.config.globalProperties 是 Vue 3 應用實例&#xff08;app&#xff09;的一個配置屬性&…

openai 標準化協議 Structured Outputs 具體示例教程

Structured Outputs 具體示例教程 場景&#xff1a;個人財務管理助手 假設我們要構建一個 AI 助手&#xff0c;幫助用戶記錄和管理個人財務支出。用戶可以輸入自然語言描述&#xff08;如“昨天我花了50元買了午餐”&#xff09;&#xff0c;助手將提取關鍵信息并以結構化 JS…

16.使用讀寫包操作Excel文件:XlsxWriter 包

一 XlsxWriter 的介紹 XlsxWriter 只能寫入 Excel 文件。 OpenPyXL 和 XlsxWriter 的區別在筆記 15 。 二 如何使用 XlsxWriter 1.導包 import datetime as dtimport xlsxwriterimport excel 2.實例化工作簿 book xlsxwriter.Workbook("xlxswriter.xlsx") book.clo…

ChatGPT and Claude國內使用站點

RawChat kelaode chatgptplus chatopens&#xff08;4.o mini免費&#xff0c;plus收費&#xff09; 網頁&#xff1a; 定價&#xff1a; wildcard 網頁&#xff1a; 虛擬卡定價&#xff1a; 2233.ai 網頁&#xff1a; 定價&#xff1a; MaynorAPI chatgpt cla…

【MySQL】MySQL審計工具Audit Plugin安裝使用

MySQL審計工具Audit Plugin安裝使用 https://www.cnblogs.com/waynechou/p/mysql_audit.html MySQL 5.6 開啟審計功能 https://blog.51cto.com/u_15127556/4344503 MySQL之添加日志審計功能 https://blog.csdn.net/weixin_43279032/article/details/105507170 MySQL開啟日志記錄…

QT 磁盤文件 教程04-創建目錄、刪除目錄、遍歷目錄

【1】新建目錄 bool CreateDir(QString name){QString fileName name ;QDir dir(fileName);if (dir.isEmpty()) {dir.mkdir(fileName);return true;}else{qDebug()<<"文件夾已存在";return false;} } 【2】刪除目錄 bool DeleteDir(QString fileName){if (…

Git——分布式版本控制工具使用教程

本文主要介紹兩種版本控制工具——SVN和Git的概念&#xff0c;接著會講到Git的安裝&#xff0c;Git常用的命令&#xff0c;以及怎么在Vscode中使用Git。幫助新手小白快速上手Git。 1. SVN和Git介紹 1.1 SVN 集中式版本控制工具&#xff0c;版本庫是集中存放在中央服務器的&am…

Vue:添加響應式數據

Vue&#xff1a;添加響應式數據 1. 什么是響應式&#xff1f; 修改 data 后&#xff0c;頁面自動改變/刷新&#xff0c;這就是響應式。就像我們在使用 Excel 的時候&#xff0c;修改一個單元格中的數據&#xff0c;其它單元格的數據會聯動更新&#xff0c;這也是響應式。在前…

算法刷題記錄——LeetCode篇(10) [第901~1000題](持續更新)

(優先整理熱門100及面試150&#xff0c;不定期持續更新&#xff0c;歡迎關注) 994. 腐爛的橘子 在給定的 m x n 網格 grid 中&#xff0c;每個單元格可以有以下三個值之一&#xff1a; 值 0 代表空單元格&#xff1b;值 1 代表新鮮橘子&#xff1b;值 2 代表腐爛的橘子。 每…

Secs/Gem第二講 (基于secs4net項目的ChatGpt介紹)

好的&#xff0c;我們正式進入&#xff1a; 第二講&#xff1a;深入 SECS4NET 項目結構——主機程序是怎么搭起來的&#xff1f; 關鍵詞&#xff1a;項目結構、類圖、通信類、事件處理、連接生命周期、異步機制 本講目的 我們從源碼入手&#xff0c;一步步搞懂&#xff1a; S…

壓測實戰 | 微信小程序商城 “雙 11” 的壓測實踐

背景 某全球知名珠寶品牌&#xff0c;始終以創新驅動零售變革。隨著全渠道戰略的深化&#xff0c;其小程序官方商城逐漸成為品牌私域流量的核心陣地&#xff0c;不僅承載了線上銷售、會員運營等功能&#xff0c;同時還與其內部系統打通&#xff0c;如會員管理系統、人力資源系…

垃圾分類--環境配置

寫在前面&#xff1a; 如果你們打這屆比賽時&#xff0c;還有我們所保留的內存卡&#xff0c;那么插上即可運行&#xff08;因為內存卡里我們已經配置好所有的環境&#xff09; 本文提供兩種環境的配置 一種是基于yolov8&#xff1a;YOLOv8 - Ultralytics YOLO Docshttps://d…

工具(十二):Java導出MySQL數據庫表結構信息到excel

一、背景 遇到需求&#xff1a;將指定數據庫表設計&#xff0c;統一導出到一個Excel中&#xff0c;存檔查看。 如果一個一個弄&#xff0c;很復雜&#xff0c;耗時長。 二、寫一個工具導出下 廢話少絮&#xff0c;上碼&#xff1a; 2.1 pom導入 <dependency><grou…

Postman 新手入門指南:從零開始掌握 API 測試

Postman 新手入門指南&#xff1a;從零開始掌握 API 測試 一、Postman 是什么&#xff1f; Postman 是一款功能強大的 API 開發與測試工具&#xff0c;支持 HTTP 請求調試、自動化測試、團隊協作等功能。無論是開發人員還是測試工程師&#xff0c;都可以用它快速驗證接口的正確…

運維工具推薦 -- 寶塔面板:一鍵部署服務器

標題&#xff1a;寶塔面板&#xff1a;一鍵部署服務器&#xff0c;輕松管理你的云端世界 引言 在數字化時代&#xff0c;服務器管理對于個人開發者、中小企業或站長來說既是機遇也是挑戰。手動配置服務器環境耗時費力&#xff0c;而 寶塔面板 作為一款 免費開源、功能全面 的服…

【軟件工程】03_軟件需求分析

3.1 系統分析 1. 系統分析概述 系統分析是一組統稱為計算機系統工程的活動。它著眼于所有的系統元素,而非僅僅局限于軟件。系統分析主要探索軟件項目的目標、市場預期、主要的技術指標等,其目的在于幫助決策者做出是否進行軟件項目立項的決定。 2. 可行性分析(Feasibility …

WD5202L超低成本 Buck 電源芯片的特性與應用電路解析, 將市電轉換為 5V 電壓

WD5202L&#xff1a;超低成本 Buck 電源芯片的特性與應用電路解析 在現代電子設備的小型化、低成本化趨勢下&#xff0c;對電源管理芯片的性能、成本和尺寸提出了嚴苛要求。WD5202L 作為一款超低成本的 Buck 電源芯片&#xff0c;憑借其獨特的特性&#xff0c;在眾多應用場景中…