unity程序简易框架
1. 框架基本结构

2. 单例模式基类模块
2.1 BaseManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class BaseManager<T> where T:new()
{private static T instance;public static T GetInstance(){if (instance == null)instance = new T();return instance;}
}
2.2 SingletonAutoMono.cs
继承这种自动创建的 单例模式基类 不需要我们手动去拖 或者 api去加了
想用他 直接 GetInstance就行了
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;}
}
2.3 SingletonMon.cs
继承了 MonoBehaviour 的 单例模式对象 需要我们自己保证它的位移性
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SingletonMono<T> : MonoBehaviour where T: MonoBehaviour
{private static T instance;public static T GetInstance(){//继承了Mono的脚本 不能够直接new//只能通过拖动到对象上 或者 通过 加脚本的api AddComponent去加脚本//U3D内部帮助我们实例化它return instance;}protected virtual void Awake(){instance = this as T;}
}
单例注意点:
继承了Mono的脚本 不能够直接new
只能通过拖动到对象上 或者 通过 加脚本的api AddComponent去加脚本
U3D内部帮助我们实例化它
一些生命周期函数和协程函数需要继承Mono对象
unity 过场景时会移除场景里的对象
DontDestroyOnLoad(obj);
让这个单例模式对象 过场景 不移除
因为 单例模式对象 往往 是存在整个程序生命周期中的
3. 缓存池模块
缓存池达到的效果

使用缓存池的目的,unity 的内存gc 是内存满才gc 一次,gc 消耗比较大
切换场景时类丢失但是不会真正的删除
PoolMgr.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;/// <summary>
/// 抽屉数据 池子中的一列容器
/// </summary>
public class PoolData
{//抽屉中 对象挂载的父节点public GameObject fatherObj;//对象的容器public List<GameObject> poolList;public PoolData(GameObject obj, GameObject poolObj){//给我们的抽屉 创建一个父对象 并且把他作为我们pool(衣柜)对象的子物体fatherObj = new GameObject(obj.name);fatherObj.transform.parent = poolObj.transform;poolList = new List<GameObject>() {};PushObj(obj);}/// <summary>/// 往抽屉里面 压都东西/// </summary>/// <param name="obj"></param>public void PushObj(GameObject obj){//失活 让其隐藏obj.SetActive(false);//存起来poolList.Add(obj);//设置父对象obj.transform.parent = fatherObj.transform;}/// <summary>/// 从抽屉里面 取东西/// </summary>/// <returns></returns>public GameObject GetObj(){GameObject obj = null;//取出第一个obj = poolList[0];poolList.RemoveAt(0);//激活 让其显示obj.SetActive(true);//断开了父子关系obj.transform.parent = null;return obj;}
}/// <summary>
/// 缓存池模块
/// 1.Dictionary List
/// 2.GameObject 和 Resources 两个公共类中的 API
/// </summary>
public class PoolMgr : BaseManager<PoolMgr>
{//缓存池容器 (衣柜)public Dictionary<string, PoolData> poolDic = new Dictionary<string, PoolData>();private GameObject poolObj;/// <summary>/// 往外拿东西/// </summary>/// <param name="name"></param>/// <returns></returns>public void GetObj(string name, UnityAction<GameObject> callBack){//有抽屉 并且抽屉里有东西if (poolDic.ContainsKey(name) && poolDic[name].poolList.Count > 0){callBack(poolDic[name].GetObj());}else{//通过异步加载资源 创建对象给外部用ResMgr.GetInstance().LoadAsync<GameObject>(name, (o) =>{o.name = name;callBack(o);});//obj = GameObject.Instantiate(Resources.Load<GameObject>(name));//把对象名字改的和池子名字一样//obj.name = name;}}/// <summary>/// 换暂时不用的东西给我/// </summary>public void PushObj(string name, GameObject obj){if (poolObj == null)poolObj = new GameObject("Pool");//里面有抽屉if (poolDic.ContainsKey(name)){poolDic[name].PushObj(obj);}//里面没有抽屉else{poolDic.Add(name, new PoolData(obj, poolObj));}}/// <summary>/// 清空缓存池的方法 /// 主要用在 场景切换时/// </summary>public void Clear(){poolDic.Clear();poolObj = null;}
}
测试脚本
PoolMgrTest用于缓存对象的生成,鼠标左键点击生成Cube,鼠标右键点击生成Sphere。
using UnityEngine;public class PoolMgrTest : MonoBehaviour
{// Update is called once per framevoid Update(){if (Input.GetMouseButtonDown(0)){PoolMgr.GetInstance().GetObj("Prefabs/Cube",(o)=> {Debug.Log(o.name + "加载成功!");});}if (Input.GetMouseButtonDown(1)){PoolMgr.GetInstance().GetObj("Prefabs/Sphere", (o) => {o.transform.position= new Vector3(2f,0,0);Debug.Log(o.name + "加载成功!");});}}
}
DelayPush用于控制缓存对象的消失,挂载到Cube和Sphere两个预制体上。
public class DelayPush : MonoBehaviour
{private void OnEnable(){Invoke("Push", 1);}void Push() {PoolMgr.GetInstance().PushObj(this.gameObject.name, this.gameObject);}
}
4. 事件中心模块
EventCenter.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;public interface IEventInfo
{}public class EventInfo<T> : IEventInfo
{public UnityAction<T> actions;public EventInfo( UnityAction<T> action){actions += action;}
}public class EventInfo : IEventInfo
{public UnityAction actions;public EventInfo(UnityAction action){actions += action;}
}/// <summary>
/// 事件中心 单例模式对象
/// 1.Dictionary
/// 2.委托
/// 3.观察者设计模式
/// 4.泛型
/// </summary>
public class EventCenter : BaseManager<EventCenter>
{//key —— 事件的名字(比如:怪物死亡,玩家死亡,通关 等等)//value —— 对应的是 监听这个事件 对应的委托函数们private Dictionary<string, IEventInfo> eventDic = new Dictionary<string, IEventInfo>();/// <summary>/// 添加事件监听/// </summary>/// <param name="name">事件的名字</param>/// <param name="action">准备用来处理事件 的委托函数</param>public void AddEventListener<T>(string name, UnityAction<T> action相关文章:
unity程序简易框架
1. 框架基本结构 2. 单例模式基类模块 2.1 BaseManager.cs using System.Collections; using System.Collections.Generic; using UnityEngine;public class BaseManager<T> where T:new() {private static T instance;public static T GetInstance(){if (instance == …...
Go小技巧易错点100例(十六)
本期看点: 正文开始: 切片的长度和容量 在Go语言中,切片(slice)是一个引用类型,它是对底层数组的抽象表示,提供了动态长度的、灵活的序列类型。切片包含三个重要的属性:指向底层数…...
通过Golang实现中间人攻击,查看和修改https流量包
要查看和修改 HTTPS 流量包,需要使用一个能够执行 中间人攻击(Man-in-the-Middle, MITM) 的代理工具。这个工具将拦截并解密 HTTPS 流量,然后允许查看和修改流量包的内容,再将其重新加密并发送到目标服务器。 完整的 …...
MySQL 安装与配置指南
MySQL 是一种广泛使用的关系型数据库管理系统,为各种应用程序提供高效的数据存储和管理解决方案。本文将介绍如何在不同的操作系统中安装 MySQL,以及如何进行基本的配置,以确保数据库系统的最佳性能和稳定性。 一、环境准备 1.1 系统要求 …...
android13布局查看工具 无源码查看布局 在线查找ui布局id
总纲 android13 rom 开发总纲说明 目录 1.前言 2.工具介绍 2.1工具1 2.2工具2 2.3工具3 2.4工具4 3.彩蛋 1.前言 Android 13提供了一些工具来帮助开发人员查看和优化应用的布局。方便的让我们找到具体应用的布局文件等信息。 2.工具介绍 2.1工具1 老版本DDMS&#x…...
【自动化测试必学语言】python:UnitTest框架
目录 介绍 框架 什么是UnitTest框架? 为什么使用UnitTest框架? UnitTest核心要素(unitest 的组成部分) 1.TestCase(最核心的模块) 2.TestSuite 3.TestRunner 4.TestLoader 5.Fixture TestCase(…...
大话LLM之向量数据库
向量数据库是一种专门设计的存储系统,旨在高效处理和查询高维向量数据,通常用于人工智能和机器学习应用中,以实现快速准确的数据检索。 好的,今天我们就来聊聊人工智能和向量数据库的事儿。现在人工智能发展得特别快,特…...
EmguCV学习笔记 C# 2.2 Matrix类
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 EmguCV学习笔记目录 Vb.net EmguCV学习笔记目录 C# 笔者的博客网址:VB.Net-CSDN博客 教程相关说明以及如何获得pdf教…...
[Windows CMD] 查看网络连接状态 netstat -na | findstr “TCP“
在 Windows 系统中,我们可以使用 netstat 命令来查看网络连接状态,并使用 findstr 命令来过滤出 TCP 和 UDP 的连接。 查看所有网络连接的状态 netstat -na netstat -na: 显示所有网络连接的状态,-n 表示显示数字地址而非域名,…...
「OC」视图控制器的懒加载策略
「OC」视图控制器的懒加载策略 文章目录 「OC」视图控制器的懒加载策略懒加载懒加载的优点常见的懒加载实现方法使用懒加载的注意事项 控制器的懒加载参考资料 懒加载 懒加载(Lazy Loading)是一种设计模式,其核心思想是在需要时才进行对象的…...
android studio 中 .gitignore 文件改动后 忽略的文件夹或文件无效
问题原因:已跟踪文件的缓存问题: 如果之前已经跟踪了这些文件(即它们已经被 Git 加入到版本控制中),即使你在 .gitignore 文件中添加了忽略规则,Git 仍然会显示这些文件。你需要先从 Git 中移除这些文件&am…...
鸿蒙 next 实现摄像头视频预览编码(一)
鸿蒙 next 即将发布,让我们先喊3遍 遥遥领先~ 遥遥领先~ 遥遥领先~ 作为一门新的系统,本人也是刚入门学习中,如果对于一些理解有问题的,欢迎即使指出哈 首先这里要讲一下,在鸿蒙 next 中,要实现摄像头预览…...
YOLO-V3
一、概述 最大的改进就是网络结构,使其更适合小目标检测特征做的更细致,融入多持续特征图信息来预测不同规格物体先验框更丰富了,3种scale,每种3个规格,一共9种softmax改进,预测多标签任务 先验框…...
golang提案,内置 Go 错误检查函数
先来狠狠吐个槽 要吐槽 Go1 的 error ,那咱得先整明白大家为啥都猛喷它的错误处理做得不咋地。在 Go 语言里头,error 本质上其实就是个 Error 的接口: type error interface {Error() string }实际的应用场景如下: func main()…...
零售业务产品系统应用架构设计(三)
智慧物业依据《住房和城乡建设部等部门关于推动物业服务企业加快发展线上线下生活服务的意见建房〔2020〕99号》,推动物业管理公司广泛运用5G、互联网、物联网、云计算、大数据、区块链和人工智能等技术,建设智慧物业管理服务平台,对接城市信息模型(CIM)和城市运行管理服务…...
【GD32】从零开始学GD32单片机 | PMU电源管理单元+深度睡眠和待机例程(GD32F470ZGT6)
1. 简介 PMU电源管理单元通俗讲就是用来管理MCU的电源域的,它主要有两个功能——电压监测和低功耗管理。在GD32中一共有3个电源域——VDD/VDDA域、1.2V域和备份域。 VDD/VDDA域主要供PMU控制器、ADC、DAC等外设使用;1.2V域就是大部分外设都会使用的电源域…...
公司员工电脑桌面太乱如何解决?桌面管理软件一招解决!
“工欲善其事,必先利其器。” 在数字化管理的时代背景下,选择合适的桌面管理软件就如同为企业网络管理装上了一双慧眼。 员工的电脑桌面往往因为长时间的使用而变得杂乱无章,这不仅影响了工作效率,还可能给企业信息安全带来隐患。…...
leetcode:2119. 反转两次的数字(python3解法)
难度:简单 反转 一个整数意味着倒置它的所有位。 例如,反转 2021 得到 1202 。反转 12300 得到 321 ,不保留前导零 。 给你一个整数 num ,反转 num 得到 reversed1 ,接着反转 reversed1 得到 reversed2 。如果 reverse…...
5.vue中axios封装工程化
vue工程化中axios封装 视频演示地址:https://www.bilibili.com/video/BV121egeQEHg/?vd_source0f4eae2845bd3b24b877e4586ffda69a 通常我们封装需要封装request.js基础的发送请求工具类,再根据业务封装service类,service类是具体业务的接口…...
实验六:动态数码管实验
实验结果图,从右到左0-7,从左到右7-0,来回滚动。 硬件接线图: 具体看图,不说了,前面讲过,自己查资料就可以,资料得慢慢查,熟练就好了,不浪费时间和版面了 main.c代码 #include<reg52.h>typedef unsigned int u16; typedef unsigned char u8;#define SMG P0 …...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
