Unity程序基础框架学习笔记
Unity的程序基础框架,视频地址:https://www.bilibili.com/video/BV1C441117wU
一、建立目录
在Assets下建立标准目录,如下图:


二、功能模块

三、脚本
3.1、单例模式基类
知识点:单例模式是设计模式中很常用的一种模式,它的目的是让一个类在程序运行期间有且只有一个实例。因为只有一个实例,减少了内存消耗和系统性能开销。单例模式有三个特点:
(1)单例类只能有一个实例。
(2)单例类必须自己创建自己的唯一实例。
(3)单例类必须给所有其他对象提供这一实例。
脚本:BaseManager.cs
//定义单例模式基类,采用泛型构造,使用无参构造函数约束泛型T的类型。
public class BaseManager<T> where T:new()
{//定义单例模式基类实例变量private static T instance;//定义单例模式基类中实例化方法public static T GetInstance(){//如果实例为空,则实例化对象if (instance == null)instance = new T();return instance;}
}
//------------------------------------------------------------------------------------
//单例模式基类的使用,新的单例模式类直接继承基类
public class GameManager : BaseManager<GameManager>
{}
public class ItemManager : BaseManager<ItemManager>
{}
//其他单例模式类的使用
public class test
{void main(){GameManager.GetInstance();ItemManager.GetInstance();}
}
3.2、缓存池模块
在GameObject大量生成->销毁的情况下(如子弹射击),销毁的物体只是删除对内存空间的引用,但并未释放实例化物体占用的内存空间。当内存空间占满后进行GC(Garbage Collection),将造成游戏运行卡顿。为了避免这种情况,通过缓存池对销毁物体的内存空间进行暂存,当需要创建新物体时直接从缓存池取出,新物体不再占用新的内存空间(除非缓存池中存放的物体数量不够),从而减少内存的消耗。
知识点:命名空间System.Collections.Generic中有两个非常重要,而且常用的泛型集合类,它们分别是Dictionary
脚本:PoolMgr.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;public class PoolMgr : BaseManager<PoolMgr>
{//定义构造类,每类放入缓存池的物体应当有一个标识其类别的父对象,及存储物体的容器public class PoolData{public GameObject PoolFather;public List<GameObject> PoolList;//FObj物体用于在缓存池内表明物体具体类别,PoolObj物体用于代表缓存池,多个FObj的父对象都设置为PoolObj以体现层级关系public PoolData(GameObject Obj,GameObject PoolObj){PoolFather = new GameObject(Obj.name);PoolFather.transform.parent = PoolObj.transform;PoolList = new List<GameObject>() { };PutObj(Obj);}public void PutObj(GameObject Obj){Obj.SetActive(false);PoolList.Add(Obj);Obj.transform.parent = PoolFather.transform;}public GameObject GetObj(){GameObject Obj = null;Obj = PoolList[0];PoolList.RemoveAt(0);//取出物体时使其激活Obj.SetActive(true);//取出缓存池的物体断开和缓存池物体的父子联系Obj.transform.parent = null;return Obj;}}//创建缓存池,定义字典参数PoolDict实现多个对象的存储,其中第一个string参数说明缓存物体的类别,用自定义的PoolData类型作为第二个参数存储对象类别(PoolFather)和对象List列表(PoolList)。public Dictionary<string, PoolData> PoolDict = new Dictionary<string, PoolData>();//定义一个物体,放入缓存池中的物体挂接到该物体下面,实现界面的简介易懂private GameObject PoolObj;//把物体放入缓存池,第一个参数存储物体名字,第二个参数存储物体实例 public void PutObj(string name,GameObject Obj){//如果缓存池物体为空,则创建一个if (PoolObj == null)PoolObj = new GameObject("Pool");//如果缓存池中有此类物体的List,则添加进该类物体的List中;如缓存池中无此类物体,则新建一个此类物体的List,并将该物体存入新建的List。if (PoolDict.ContainsKey(name)){//在对应name类的List中存入物体PoolDict[name].PutObj(Obj);}else {//新建一个name类的PoolData,并把Obj物体添加进PoolData的List里PoolDict.Add(name, new PoolData(Obj,PoolObj));}} //采用异步加载方式从缓存池中取出指定物体,通过物体名字进行索引public void GetObj(string name,UnityAction<GameObject> CallBack){//如果缓存池中存在指定的物体名,且该类物体数量大于0则取出,否则重新实例化一个物体if (PoolDict.ContainsKey(name) && PoolDict[name].PoolList.Count > 0){CallBack(PoolDict[name].GetObj());//调用PoolData中的GetObj()方法,从缓存池中取出物体//Obj = PoolDict[name].GetObj();}else{ResourcesMgr.GetInstance().LoadAsync<GameObject>(name,(PObj)=>{PObj.name = name;CallBack(PObj);});//重新实例化要取出的物体,从Resources目录中调用预制体//Obj = GameObject.Instantiate(Resources.Load(name)); //把实例化的物体名字改为传入的调用名字,否则物体实例化后会在名字后面加上(clone),不利于后续处理//Obj.name = name;}}//切场景的时候应当清除缓存池并把缓存池物体置空,否则调用会报错public void PoolClear(){PoolDict.Clear();PoolObj = null;}
}
// PoolGetTest .cs----------------------------------------------------------------------
//从缓存池中取出物体脚本。当按下鼠标左键时,从缓存池取出指定名称为"Test/ Monster "的物体,当缓//存池中没有物体时,将从取出Resources/Test/目录下的Cube预制体进行实例化。按下鼠标右键时,则对"Test/ Player "物体进行相同操作。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PoolGetTest : MonoBehaviour
{void Update(){if(Input.GetMouseButtonDown(0)){PoolMgr.GetInstance().GetObj("Test/Monster",(Obj)=> { });}if (Input.GetMouseButtonDown(1)){PoolMgr.GetInstance().GetObj("Test/Player", (Obj) => { });}}
}
// PoolPutTest .cs----------------------------------------------------------------------
//将物体放入缓存池脚本。将此脚本挂在Resources/Test/目录下的预制体上,当该物体被实例化调用后,延迟1秒后放入缓存池。
public class PoolPutTest : MonoBehaviour
{//当对象激活时,会进入的生命周期函数private void OnEnable(){Invoke("Put",1);}void Put(){PoolMgr.GetInstance().PutObj(this.gameObject.name,this.gameObject);}
}
3.3、事件中心模块
通过Dictionary
脚本:EventMgr.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;public class EventMgr : BaseManager<EventMgr>
{//Dictionary的Key对应字符串类型的事件名(如怪物死亡,玩家死亡等),Value对应的是监听这个事件的委托函数们,此处使用UnityEngine.Events命名空间下自带的事件标识UnityAction。private Dictionary<string, UnityAction<object>> EventDict = new Dictionary<string, UnityAction<object>>();//添加事件监听,添加指定事件名字的监听器,并说明准备处理该事件的方法public void AddEventListener(string name,UnityAction<object> action){//如果事件管理模块中有name名字的事件,则在该事件中加入一个传入的处理方法if(EventDict.ContainsKey(name)){EventDict[name] += action;}//如果事件管理模块中没有name名字的事件,则添加这个事件以及对应的处理方法else {EventDict.Add(name, action);} }//移除事件监听,当物体销毁时应当在事件管理器中移除该物体监听事件执行的方法public void RemoveEventListener(string name,UnityAction<
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
