unity程序简易框架

news2024/11/16 9:47:26

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;
    }
}

单例注意点:

  1. 继承了Mono的脚本 不能够直接new
    只能通过拖动到对象上 或者 通过 加脚本的api AddComponent去加脚本
    U3D内部帮助我们实例化它

  2. 一些生命周期函数和协程函数需要继承Mono对象

  3. 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 frame
    void 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2053118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

直播预约|2024 乐鑫科技全球开发者大会亮点揭秘

时隔一年&#xff0c;2024 乐鑫科技全球开发者大会将在 9 月 3-5 日如约而至。这一年&#xff0c;人工智能给物联网领域带来了哪些变化&#xff1f;乐鑫在 AIoT 领域实现了哪些新突破&#xff1f;ESP-IDF 经过升级后增添了哪些新功能&#xff1f;ESP32-P4、ESP32-C6 迎来了怎样…

C语言指针详解-上

C语言指针详解-上 前言1.指针的基本概念1.1指针是什么1.2指针的声明与初始化1.3取地址符&和解引用符*& 运算符用于**获取变量的地址*** 运算符用于访问指针指向的值 2.指针的类型常见数据类型的指针指针与数组、字符串数组指针结构体指针函数指针二级指针void指针 3.指…

多级评论的实现,评论回复功能(两层型)

前言&#xff1a; 技术栈&#xff1a;springboot mysql mybatis 比着写一遍&#xff0c;你也一定会实现多级评论的功能&#xff0c;简单易上手&#xff01; 1.效果 整体的结构只有两层&#xff0c;但是确实现了评论回复功能 [ { "id": 2, "userId": …

让JMeter测试数据生成更容易

让JMeter测试数据生成更容易 背景&#xff1a; 在软件测试过程中&#xff0c;为了确保系统的稳定性和可靠性&#xff0c;需要对各种场景进行全面的测试。而不同的场景往往需要各种各样的测试数据&#xff0c;这些数据需要具有一定的真实性和多样性&#xff0c;以模拟实际使用…

零基础小白实现C#调用halcon dll的过程,并测试程序证明C#halcon联合开发成功

本篇将介绍零基础小白实现C#调用halcon dll的过程&#xff0c;同时这其中涉及到很多知识&#xff0c;务必将HDevelop和VisualStudio安装成功。下面我将详细阐述C#调用halcon dll的过程&#xff0c;你的点赞和评论是我一直前行的动力。 1. C#调用Halcon DLL的过程 要在C#中调用…

选择TPM管理咨询公司,这几点是关键!

在这个日新月异的商业时代&#xff0c;企业的竞争力不仅体现在产品和服务上&#xff0c;更在于其内部管理的精细化与高效化。TPM作为提升企业综合生产效率的利器&#xff0c;正逐步成为众多企业转型升级的必然选择。然而&#xff0c;如何在众多TPM管理咨询公司中慧眼识珠&#…

嘉盛:股指、国债及商品期货分析

股指展望中证全指在2024年下半年可能迎来约20%的上涨空间。尽管市场估值较低&#xff0c;风险溢价仍维持在高位&#xff0c;这提升了指数的配置性价比。预计无风险利率将继续维持在较低水平&#xff0c;对中证全指估值产生积极影响。盈利方面&#xff0c;预计下半年中证全指EPS…

【广东】邀您共赴纷享销客生态伙伴大会

在数字化浪潮的驱动下&#xff0c;CRM行业正迎来前所未有的创新机遇。作为CRM领域的引领者&#xff0c;纷享销客特别举办“纷享销客2024生态伙伴大会&#xff08;广东站&#xff09;”。我们诚挚邀请各位生态伙伴莅临现场&#xff0c;共同探讨SaaS CRM行业的最新趋势&#xff0…

haproxy负载均衡+mysql读写分离

haproxy负载均衡 [roothaproxy01 ~]# yum -y install ntpdate [roothaproxy01 ~]# yum -y install ntp [roothaproxy01 ~]# systemctl start ntpd 安装haproxy [roothaproxy01 ~]# yum -y install ntpdate 配置文件的地址 [roothaproxy01 ~]# rpm -ql haproxy [roothap…

美摄科技携手蔚来汽车,共创用户出行新体验!

7月27日&#xff0c;蔚来举办了以 AI 为主线的 “NIO IN 2024 蔚来创新科技日”&#xff0c;此次活动展示了蔚来在智能电动汽车领域最新探索与成果&#xff0c;为中国乃至全球的智能汽车行业树立了新的标杆。当晚&#xff0c;央视《主播说联播》以“中国智能车在全球竞争的另一…

MIT6.s081 2021 Lab Multithreading

Uthread: switching between threads 思路 xv6 已经实现了进程的切换机制&#xff0c;本实验要求参考进程的切换&#xff0c;实现一个用户态线程的切换。 要实现线程切换&#xff0c;必然涉及上下文&#xff0c;即寄存器的保存和恢复&#xff0c;那么需要保存哪些寄存器&…

建筑工程项目管理系统-计算机毕设Java|springboot实战项目

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

建筑工地安全检查

在现代化的建筑工地中&#xff0c;安全始终是至关重要的核心问题。随着科技的不断进步&#xff0c;凡尔码建筑工地安全系统应运而生&#xff0c;灵活根据施工现场管理要求搭建建筑工地安全系统各个模块&#xff0c;为施工安全带来了全新的保障。 如何注册建筑工地安全系统后台…

自动打电话软件给企业带来了什么?

使用机器人外呼系统肯定都是想要给自己企业带来好处和解决问题的&#xff0c;想让自己的企业有所改变&#xff0c;有更好的发展&#xff0c;所以才会选择使用机器人外呼系统。而它也确实没让大家失望&#xff0c;使用了机器人外呼系统之后确实有许多企业发生了很大改变和进步&a…

鲁棒性目标检测 TOP2 方案分享

关联比赛: ACM MM2021 安全AI挑战者计划第七期&#xff1a;鲁棒性标识检测 ACM MM2021 鲁棒性目标检测比赛 TOP 2 方案 ​ 赛题背景 在商品知识产权领域&#xff0c;知识产权体现为在线商品的设计和品牌。不幸的是&#xff0c;在每一天&#xff0c;存在着非法商户通过一些…

一文学会本地部署可视化应用JSONCrack并配置公网地址实现远程协作

文章目录 前言1. Docker安装JSONCrack2. 安装Cpolar内网穿透工具3. 配置JSON Crack界面公网地址4. 远程访问 JSONCrack 界面5. 固定 JSONCrack公网地址 前言 本文主要介绍如何在Linux环境使用Docker安装数据可视化工具JSONCrack&#xff0c;并结合cpolar内网穿透工具实现团队在…

[Python学习日记-9] Python中的运算符

简介 计算机可以进行的运算有很多种&#xff0c;但可不只加减乘除这么简单&#xff0c;运算按种类可分为算数运算、比较运算、逻辑运算、赋值运算、成员运算、身份运算、位运算&#xff0c;而本篇我们暂只介绍算数运算、比较运算、逻辑运算、赋值运算 算数运算 一、运算符描述…

猫头虎分享:Python库 Pillow 的简介、安装、用法详解入门教程

猫头虎分享&#xff1a;Python库 Pillow 的简介、安装、用法详解入门教程 &#x1f4da; 大家好&#xff0c;今天猫头虎要和大家分享一款非常实用的 Python 图像处理库——Pillow。 &#x1f4a1; Pillow 是 Python 中非常流行的图像处理库&#xff0c;基于已经停止维护的 PI…

CE修改器步骤9学习教程

一、打开教程&#xff0c;因为我的电脑是64位的&#xff0c;所以打开这个&#xff08;x86_64&#xff09; 二、 跳转到步骤9&#xff0c;并让ce读取其内存 三、使用之前教程学到的知识&#xff0c;找到四个角色的健康值地址&#xff08;找到即可&#xff0c;不必找基址&#xf…

【STM32 FreeRTOS】Tickless低功耗模式

STM32低功耗模式 STM32 提供了 3 种低功耗模式&#xff0c;以达到不同层次的降低功耗的目的 睡眠模式&#xff08;内核停止工作&#xff0c;外设仍在运行&#xff09;停止模式&#xff08;所有时钟都停止&#xff09;待机模式&#xff08; 1.8 V 内核电源关闭&#xff09; Fr…