框架API和简单示例
对象池
在Unity中,对象的生成、销毁都需要性能开销,在一些特定的应用场景下需要进行大量重复物体的克隆,因此需要通过设计对象池来实现重复利用对象实例,减少触发垃圾回收。常用在频繁创建、销毁对象的情况下,比如子弹、AI生成等等、背包格子。
本框架的对象池系统有两类对象池(GameObject对象池和Object对象池)分别负责对需要在场景中实际激活/隐藏的GameObject和不需要显示在场景里的对象(脚本类、材质资源)进行管理。
本框架提供提供对象池容量的限制,且初始化时,可以预先传入要放入的对象根据默认容量实例化放入对象池,比如场景中默认使用20发子弹,可以在对象池初始化时就实例化好20枚子弹放入对象池。
如有特殊需求,可以通过持有PoolMoudle层来单独构建一个不同于全局对象池PoolSystem的Pool,默认正常情况下使用全局对象池PoolSystem即可。
Object对象池(OP)
用于管理脚本类对象等非游戏物体对象,OP的API和GOP类似,只不过在传参部分OP支持更多方式
初始化OP
// API
//根据keyName初始化OP
//(string keyName, int maxCapacity = -1, int defaultQuantity = 0)
PoolSystem.InitObjectPool<T>(keyName, maxCapacity, defaultQuanity);
PoolSystem.InitObjectPool<T>(keyName, maxCapacity);
PoolSystem.InitObjectPool<T>(keyName);
//根据T的类型名初始化OP
PoolSystem.InitObjectPool<T>(maxCapacity, defaultQuanity);
PoolSystem.InitObjectPool<T>(maxCapacity);
PoolSystem.InitObjectPool<T>();
//根据keyName初始化OP,不考虑默认容量,无需传T
PoolSystem.InitObjectPool(keyName, maxCapacity);
PoolSystem.InitObjectPool(keyName);
//根据type类型名初始化OP
//System.Type type, int maxCapacity = -1
PoolSystem.InitObjectPool(xx.GetType());
//简单示例
// 设定一个Data数据类对象池,最大容量30,默认填满
PoolSystem.InitObjectPool<Data>("myData",30,30);
PoolSystem.InitObjectPool<Data>(30, 30);
参数说明:
- 通过keyName或者直接传入T根据T的类型名指定对象池的名字。
- 可设置对象池最大容量maxCapacity(超过maxCapacity再放入对象会被Destroy掉)。
- 可通过T和defaultQuanity设置默认容量(初始化时会自动按默认容量和最大容量的最小值自动生成Object放入对象池)。
- 泛型T起两个作用,一个是不指定keyName时用于充当type名称,另一个是进行默认容量设置时指定预先放入对象池的对象类型,所以如果不想用默认容量功能可以使用不传T的API。
- maxCapacity, prefab, defaultQuantity可不填,默认无限容量maxCapacity = -1,不预先放入对象,prefab = null, defaultQuantity = 0。
- defaultQuantity必须小于maxCapacity且如果想使用defaultQuantity则必须填入maxCapacity。
扩展功能:
- 可以通过重复初始化一个对象池的maxCapacity实现容量的更改,此时如果重新指定了defaultQuanity,则会补齐差量个数的对象进对象池。
- OP的初始化和GOP略有不同,使用了泛型T传递类型,参数列表更加精简,但只有有泛型参数的重载方法可以进行默认容量的初始化(需要指定泛型T进行类型转换)。
- 可以选择通过传入某个实例的type类型,初始化同名的无限容量OP。
将对象放入OP
// API
//根据keyName/obj.getType().FullName即obj对应的类型名放入对象池
//(object obj, string keyName)
PoolSystem.PushObject(obj, keyName);
PoolSystem.PushObject(obj);
//简单示例
//将一个Data数据类对象data放入Data对象池
PoolSystem.PushObject(data, "Data";
PoolSystem.PushObject(data);
// 扩展方法
bullet.ObjectPushPool();
参数说明:
- 通过keyName指定对象池名字放入对象obj,keyName不填则默认对象池名字为obj.name。
拓展功能:
- 可以使用拓展方法直接将对象放入同名对象池内。
- 如果传入的keyName/obj找不到对应的对象池(未Init),则会直接初始化生成一个同名的,无限容量的对象池并放入本次对象。
- obj为null时本次放入操作无效,会进行报错提示。
将对象从OP中取出
// API
//根据keyName返回System.object类型对象
//(string keyName)
PoolSystem.GetObject(keyName);
//根据keyName返回T类型的对象
PoolSystem.GetObject<T>(keyName);
//根据T类型名称返回对象
PoolSystem.GetObject<T>();
//根据type类型名返回对象
//(System.Type type)
PoolSystem.GetObject(xx.getType());
//简单实例
//将一个Data数据类对象data从对象池中取出
Data data = PoolSystem.GetObject("Data");
Data data = PoolSystem.GetObject<Data>();
参数说明:
- 通过keyName,泛型T,type类型指定对象池名字取出Object对象。
- 优先根据keyName索引,不存在keyName时,则通过泛型T的反射类型和type类型名索引
拓展功能:
- 推荐使用泛型方法,否则返回值是object类型还需要手动进行转换。
清空OP对象池
//API
//清空(GameObject/Object)对象池
//(bool clearGameObject = true, bool clearCSharpObject = true)
PoolSystem.ClearAll(false, true);
//清空Object类对象池下keyName/T类型名/type类型名对象池
//(string keyName)
PoolSystem.ClearObject(keyName);
PoolSystem.ClearObject<T>();
//(System.Type type)
PoolSystem.ClearObject(xx.getType());
//简单实例
//清空所有OP对象池
PoolSystem.ClearAll(false,true);
//清空Data对象池
PoolSystem.ClearObject("Data");
PoolSystem.ClearObject<Data>();
参数说明:
- ClearAll方法用于清空所有GOP/OP对象池,两个bool参数是否清空GOP、是否清空OP。
- 清空某一类OP通过传入keyName/泛型T的反射类型名/type类型名索引。
拓展功能:
- 清空所有对象池时(ClearAll),所有资源都会被释放。
- 清空某一类对象池时,Object中的数据载体会被放回对象池重复利用(使用时无需关心,底层实现)。
GameObject对象池(GOP)
用于管理实际存在场景中并出现在Hierarchy窗口上的GameObject对象。
初始化GOP
// API
//根据keyName初始化GOP
//(string keyName, int maxCapacity = -1,GameObject prefab = null,int defaultQuantity = 0)
PoolSystem.InitGameObjectPool(keyName, maxCapacity, prefab, defaultQuanity);
PoolSystem.InitGameObjectPool(keyName, maxCapacity);
PoolSystem.InitGameObjectPool(keyName);
//根据prefab.name初始化GOP
// //(GameObject prefab = null, int maxCapacity = -1,GameObject prefab = null,int defaultQuantity = 0)
PoolSystem.InitGameObjectPool(prefab, maxCapacity, defaultQuanity);
PoolSystem.InitGameObjectPool(prefab, maxCapacity);
PoolSystem.InitGameObjectPool(prefab);
//简单示例
// 设定一个子弹Bullet对象池,最大容量30,默认填满
Gameobject bullet = GameObject.Find("bullet");
PoolSystem.InitGameObjectPool("Bullet", 30, bullet, 30);
PoolSystem.InitGameObjectPool(bullet, 30, 30);
//最简形式
PoolSystem.InitGameObjectPool(“对象池名字”);
参数说明:
- 通过keyName或者直接传入prefab根据prefab.name 指定对象池的名字。
- 可设置对象池最大容量maxCapacity(超过maxCapacity再放入对象会被Destroy掉)。
- 可通过prefab和defaultQuanity设置默认容量(初始化时会自动按默认容量和最大容量的最小值自动生成GameObject放入对象池)。
- maxCapacity, prefab, defaultQuantity可不填,默认无限容量maxCapacity = -1,不预先放入对象,prefab = null, defaultQuantity = 0。
- defaultQuantity必须小于maxCapacity且如果想使用defaultQuantity则必须填入maxCapacity。
扩展功能:
- 可以通过重复初始化一个对象池的maxCapacity实现容量的更改,此时如果重新指定了defaultQuanity,则会补齐差量个数的对象进对象池。
将对象放入GOP
// API
//根据keyName/obj.name放入对象池
//(string assetName, GameObject obj)
PoolSystem.PushGameObject(keyName, obj);
PoolSystem.PushGameObject(obj);
//简单示例
//将一个子弹对象bullet放入Bullet对象池
PoolSystem.PushGameObject("Bullet", bullet);
// 扩展方法
bullet.GameObjectPushPool();
参数说明:
- 通过keyName指定对象池名字放入对象obj,keyName不填则默认对象池名字为obj.name。
拓展功能:
- 可以使用拓展方法直接将对象放入同名对象池内。
- 如果传入的keyName/prefab找不到对应的对象池(未Init),则会直接初始化生成一个同名的,无限容量的对象池并放入本次对象。
- obj为null时本次放入操作无效,会进行报错提示。
将对象从GOP中取出
// API
//根据keyName加载GameObject
//(string keyName, Transform parent)
PoolSystem.GetGameObject(keyName, parent);
PoolSystem.GetGameObject(keyName);
//根据keyName和T加载GameObject并获取组件
PoolSystem.GetGameObject<T>(keyName, parent);
PoolSystem.GetGameObject<T>(keyName);
//简单实例
//将一个子弹对象从对象池中取出
GameObject bullet = PoolSystem.GetGameObject("Bullet");
//将一个子弹对象从对象池中取出并获取其刚体组件
GameObject bullet = PoolSystem.GetGameOjbect<Rigidbody>("Bullet");
参数说明:
- 通过keyName指定对象池名字取出GameObject对象并设置父物体为parent,parent不填则默认无父物体在最顶层。
- 可以通过泛型T传参获取对象上的某个组件,组件依托于GameObject存在,因此物体此时也已被从对象池中取出。
拓展功能:
- 当某个对象池内无对象时,其对象池仍会被保存,只有通过Clear才能彻底清空对象池。
- 当对象池中无对象仍要取出时,会返回null。
清空GOP对象池
//API
//清空(GameObject/Object)对象池
//(bool clearGameObject = true, bool clearCSharpObject = true)
PoolSystem.ClearAll(true, false);
//清空GameObject类对象池中keyName索引的对象池
//(string assetName)
PoolSystem.ClearGameObject(keyName);
//简单实例
//清空所有GOP对象池
PoolSystem.ClearAll(true,false);
//清空Bullet对象池
PoolSystem.ClearGameObject("Bullet");
参数说明:
- ClearAll方法用于清空所有GOP/OP对象池,两个bool参数是否清空GOP、是否清空OP。
- 清空某一类GOP通过传入keyName对象池名索引。
拓展功能:
- 清空所有对象池时(ClearAll),所有资源都会被释放。
- 清空某一类对象池时,GameObject中的数据载体和根节点会被放回对象池重复利用(使用时无需关心,底层实现)。
对象池可视化
可以通过PoolSystemViewer观察OP和GOP。
注意
-
对象池的名字可以和放入的对象名字不同,并且每一个放入对象池的对象名词也可以不同(只要类型一致),但为了避免混淆,我们推荐同名(同类名或者同GameObject名)或者使用配置、枚举来记录对象池名。
-
PoolSystem可以直接使用,但大多情况下,推荐使用ResSystem来获取GameObject/Object对象来保证返回值不为null。
资源系统
资源系统实现了Unity资源、游戏对象、类对象的获取、异步加载,并在加载游戏对象和类对象资源时优先从对象池中获取资源来优化性能,若对象池不存在对应资源再通过资源加载方法进行实例化(因为在直接使用对象池时,返回值允许为null,但通过资源系统加载资源时,若没有对象池缓存则自动生成,只要资源名正确,资源系统必定返回对应的资源)。提供Resources和Addressables两种版本:
- Resources版本,关联对象池进行资源的加载、卸载。
- Addressables版本,除关联对象池进行资源的加载、卸载外,结合事件工具实现对象Destroy时Adressables自动unload。
两种版本在框架设置里进行切换,推荐使用资源系统进行资源的加载,而不是直接使用对象池系统避免返回null值。
Resources版本
普通类对象(obj)
类对象资源不涉及异步加载、Resources和Addressables的区别,直接走对象池系统。
初始化
资源系统的底层基于对象池系统,所以在资源系统层面也开放对对象池的初始化设置,API和PoolSystem一致。
// API
//根据keyName初始化OP
//(string keyName, int maxCapacity = -1, int defaultQuantity = 0)
ResSystem.InitObjectPool<T>(keyName, maxCapacity, defaultQuanity);
ResSystem.InitObjectPool<T>(keyName, maxCapacity);
ResSystem.InitObjectPool<T>(keyName);
//根据T的类型名初始化OP
ResSystem.InitObjectPool<T>(maxCapacity, defaultQuanity);
ResSystem.InitObjectPool<T>(maxCapacity);
ResSystem.InitObjectPool<T>();
//根据keyName初始化OP,不考虑默认容量,无需传T
ResSystem.InitObjectPool(keyName, maxCapacity);
ResSystem.InitObjectPool(keyName);
//根据type类型名初始化OP
//System.Type type, int maxCapacity = -1
ResSystem.InitObjectPool(xx.GetType());
//简单示例
// 设定一个Data数据类对象池,最大容量30,默认填满
ResSystem.InitObjectPool<Data>("myData",30,30);
ResSystem.InitObjectPool<Data>(30, 30);
参数说明:
- 通过keyName或者直接传入T根据T的类型名指定对象池的名字。
- 可设置对象池最大容量maxCapacity(超过maxCapacity再放入对象会被Destroy掉)。
- 可通过T和defaultQuanity设置默认容量(初始化时会自动按默认容量和最大容量的最小值自动生成T类型的对象放入对象池)。
- 泛型T起两个作用,一个是不指定keyName时用于充当type名称,另一个是进行默认容量设置时指定预先放入对象池的对象类型,所以如果不想用默认容量功能可以使用不传T的API。
- maxCapacity, prefab, defaultQuantity可不填,默认无限容量maxCapacity = -1,不预先放入对象,prefab = null, defaultQuantity = 0。
- defaultQuantity必须小于maxCapacity且如果想使用defaultQuantity则必须填入maxCapacity。
扩展功能:
- 可以通过重复初始化一个对象池的maxCapacity实现容量的更改,此时如果重新指定了defaultQuanity,则会补齐差量个数的对象进对象池。
- 只有有泛型参数的重载方法可以进行默认容量的初始化(需要指定泛型T进行类型转换)。
- 可以选择通过传入某个实例的type类型,初始化同名的无限容量OP。
obj加载
// API
//根据keyName从对象池中获取一个T类型对象,没有则new
//string keyName
ResSystem.GetOrNew<T>(keyName);
//根据T类型名从对象池中获取一个T类型对象,没有则new
ResSystem.GetOrNew<T>();
//简单示例,获取Data数据类的一个对象
GameObject go1 = ResSystem.GetOrNew<Data>("Data");
参数说明
- 通过keyName指定加载的类对象名,不填keyName则按照T的类型名加载。
扩展功能:
- 加载时优先通过对象池获取,如果对象池中无对应资源,自动new一个类对象返回,保证返回值不为null。
obj卸载
卸载obj即将obj放回对象池进行资源回收。
//API
//根据keyName/obj类型名将obj放回对象池
//object obj, string keyName
ResSystem.PushObjectInPool(obj);
ResSystem.PushObjectInPool(obj, string keyName);
//简单示例,卸载Data类的对象data
ResSystem.PushObjectInPool(data, "Data");
参数说明
- 通过obj指定卸载的对象,keyName指定对象池名,不填则按照obj的类型名卸载。
扩展功能:
- 卸载对象时如果没有初始化过对象池,则对应自动创建一个同名无限量对象池并将obj放入。
游戏对象(GameObject)
初始化
资源系统的底层基于对象池系统,所以在资源系统层面也开放对对象池的初始化设置,API和PoolSystem大体一致,在prefab部分传参略有不同,通过传Resources下对应的路径由资源系统获得预制体。
//API
//根据keyName初始化GOP
//(string keyName, int maxCapacity = -1, string assetPath = null, int defaultQuantity = 0)
ResSystem.InitGameObjectPool(keyName, maxCapacity, assetPath, defaultQuantity);
ResSystem.InitGameObjectPool(keyName, maxCapacity);
ResSystem.InitGameObjectPool(keyName);
//根据assetPath切割的资源名初始化GOP
//(string assetPath, int maxCapacity = -1, int defaultQuantity = 0)
ResSystem.InitGameObjectPool(string assetPath, maxCapacity, defaultQuantity);
ResSystem.InitGameObjectPool(string assetPath, maxCapacity);
ResSystem.InitGameObjectPool(string assetPath);
//简单示例
// 设定一个子弹Bullet对象池(假设Bullet的路径在Resources文件夹下),最大容量30,默认填满
Gameobject bullet = GameObject.Find("bullet");
ResSystem.InitGameObjectPool("Bullet", 30, bullet, 30);
ResSystem.InitGameObjectPool(bullet, 30, 30);
//最简形式
ResSystem.InitGameObjectPool(“对象池名字”);
参数说明:
- 通过keyName或者直接传入assetPath(完整资源路径)根据切割的资源名指定对象池的名字。
- 传入的assetPath会自动切割获得资源名。
- 可设置对象池最大容量maxCapacity(超过maxCapacity再放入对象会被Destroy掉)。
- 可通过assetPath获取的资源和defaultQuanity设置默认容量(初始化时会自动按默认容量和最大容量的最小值自动生成GameObject放入对象池)。
- 默认无限容量maxCapacity = -1,不预先放入对象,assetPath = null, defaultQuantity = 0。
- defaultQuantity必须小于maxCapacity且如果想使用defaultQuantity则必须填入maxCapacity。
扩展功能:
- 可以通过重复初始化一个对象池的maxCapacity实现容量的更改,此时如果重新指定了defaultQuanity,则会补齐差量个数的对象进对象池。
- 注意加载到内存的对象在被实例化之后会被自动释放。
GameObject加载并实例化
//API
//加载游戏物体
//(string assetPath, Transform parent = null,string keyName=null)
ResSystem.InstantiateGameObject(assetPath, parent, keyName);
ResSystem.InstantiateGameObject(assetPath, parent);
ResSystem.InstantiateGameObject(assetPath);
ResSystem.InstantiateGameObject(parent, keyName);
//加载游戏物体并获取组件T
ResSystem.InstantiateGameObject<T>(assetPath, parent, keyName);
ResSystem.InstantiateGameObject<T>(assetPath, parent);
ResSystem.InstantiateGameObject<T>(assetPath);
ResSystem.InstantiateGameObject<T>(parent, keyName);
//异步加载(void)游戏物体
//(string path, Action<GameObject> callBack = null, Transform parent = null, string keyName = null)
ResSystem.InstantiateGameObjectAsync(assetPath, Action<GameObject> callBack, parent, keyName);
ResSystem.InstantiateGameObjectAsync(assetPath, Action<GameObject> callBack, parent);
ResSystem.InstantiateGameObjectAsync(assetPath, Action<GameObject> callBack);
ResSystem.InstantiateGameObjectAsync(assetPath);
//异步加载(void)游戏物体并获取组件T
ResSystem.InstantiateGameObjectAsync<T>(assetPath, Action<GameObject> callBack, parent, keyName);
ResSystem.InstantiateGameObjectAsync<T>(assetPath, Action<GameObject> callBack, parent);
ResSystem.InstantiateGameObjectAsync<T>(assetPath, Action<GameObject> callBack);
ResSystem.InstantiateGameObjectAsync<T>(assetPath);
//简单示例
//实例化一个子弹对象(假设Bullet路径在在Resources下)
GameObject bullet = ResSystem.InstantiateGameObject("Bullet");
//实例化一个子弹对象取出并获取其刚体组件
GameObject bullet = ResSystem.InstantiateGameObject("Bullet");
//异步实例化一个子弹对象,并在其加载完后坐标归零
void getBullet(GameObject bullet)
{
bullet.transform.position = Vector3.zero;
}
ResSystem.InstantiateGameObjectAsync("Bullet", getBullet);
参数说明:
- 通过assetPath加载游戏物体并实例化返回。
- 实例化的游戏物体会设置父物体为parent,不填则默认为null无父物体在最顶层。
- 优先根据keyName从对象池获取,不填keyName则根据path加载的资源名在对象池中查找。
- 对象池中找不到根据assetpath走Resources加载出对象,不填assetPath时则通过keyName查询路径加载对象。
- 可以通过泛型T传参获取对象上的某个组件,组件依托于GameObject存在,因此物体此时也已被从对象池中取出。
- 异步加载游戏物体及其组件的方法返回值为void类型,无法直接加载的游戏物体,需要通过传入callback回调获取加载的对象并进行使用。
扩展功能:
- 如果资源路径正确,则返回值必不为空,优先从对象池中获取,对象池中不存在则根据Load的对象进行实例化返回。
GameObject卸载
卸载GameObject即将GameObject放回对象池进行资源回收。
//API
//根据keyName/gameObject.name回收gameObject
//string keyName, GameObject gameObject
ResSystem.PushGameObjectInPool(string keyName, gameObject);
ResSystem.PushGameObjectInPool(gameObject);
//简单示例,卸载子弹对象bullet
ResSystem.PushGameObjectInPool(bullet, "Bullet");
参数说明
- 通过gameObject指定卸载的对象,keyName指定对象池名,不填则按照gameObject的对象名卸载。
扩展功能:
- 卸载对象时如果没有初始化过对象池,则对应自动创建一个同名无限量对象池并将gameObject放入。
Unity资源
这类资源不需要进行实例化,所以不需要过对象池,只需要使用数据或者引用,比如AudioClip,Sprite,prefab。
加载Asset
//API
//根据assetPath异步加载T类型资源
//(string assetPath, Action<T> callBack)
ResSystem.LoadAssetAsync<T>(assetPath, callBack);
//根据assetPath加载T类型资源
ResSystem.LoadAsset<T>(assetPath);
//加载指定路径的所有资源返回object类型
ResSystem.LoadAssets(assetPath);
//加载指定路径的所有资源返回T类型
ResSystem.LoadAssets<T>(assetPath);
//简单示例,加载Resources下的clip音频资源
ResSystem.LoadAssets<AudioClip>("Resources/clip");
参数说明
- 通过assetPath路径加载资源,T用来指明加载的资源类型。
- 异步加载资源需要通过传入callback回调获取加载的资源并进行使用。
- 加载所有资源时不指定T则返回object数组。
- 注意加载的资源不会被自动释放。
卸载Asset
//API
//卸载某个资源
//(UnityEngine.Object assetToUnload)
ResSystem.UnloadAsset(assetToUnload);
//卸载所有资源
ResSystem.UnloadUnusedAssets();
卸载资源实际指释放内存中的asset。
对象池是帮做资源回收利用的,避免频繁GC,对象池管理不了Asset资源。而释放是资源不用了也不需要回收卸载掉就行了,GO的自动释放资源系统已经做好了,Asset需要你根据自己的需求来释放,因为Asset也没有生命周期,只能自己释放。
Addressables版本
普通类对象(obj)
类对象资源不涉及异步加载、Resources和Addressables的区别,直接走对象池系统,两个版本的API完全相同。
初始化
资源系统的底层基于对象池系统,所以在资源系统层面也开放对对象池的初始化设置,API和PoolSystem一致。
// API
//根据keyName初始化OP
//(string keyName, int maxCapacity = -1, int defaultQuantity = 0)
ResSystem.InitObjectPool<T>(keyName, maxCapacity, defaultQuanity);
ResSystem.InitObjectPool<T>(keyName, maxCapacity);
ResSystem.InitObjectPool<T>(keyName);
//根据T的类型名初始化OP
ResSystem.InitObjectPool<T>(maxCapacity, defaultQuanity);
ResSystem.InitObjectPool<T>(maxCapacity);
ResSystem.InitObjectPool<T>();
//根据keyName初始化OP,不考虑默认容量,无需传T
ResSystem.InitObjectPool(keyName, maxCapacity);
ResSystem.InitObjectPool(keyName);
//根据type类型名初始化OP
//System.Type type, int maxCapacity = -1
ResSystem.InitObjectPool(xx.GetType());
//简单示例
// 设定一个Data数据类对象池,最大容量30,默认填满
ResSystem.InitObjectPool<Data>("myData",30,30);
ResSystem.InitObjectPool<Data>(30, 30);
参数说明:
- 通过keyName或者直接传入T根据T的类型名指定对象池的名字。
- 可设置对象池最大容量maxCapacity(超过maxCapacity再放入对象会被Destroy掉)。
- 可通过T和defaultQuanity设置默认容量(初始化时会自动按默认容量和最大容量的最小值自动生成T类型的对象放入对象池)。
- 泛型T起两个作用,一个是不指定keyName时用于充当type名称,另一个是进行默认容量设置时指定预先放入对象池的对象类型,所以如果不想用默认容量功能可以使用不传T的API。
- maxCapacity, prefab, defaultQuantity可不填,默认无限容量maxCapacity = -1,不预先放入对象,prefab = null, defaultQuantity = 0。
- defaultQuantity必须小于maxCapacity且如果想使用defaultQuantity则必须填入maxCapacity。
扩展功能:
- 可以通过重复初始化一个对象池的maxCapacity实现容量的更改,此时如果重新指定了defaultQuanity,则会补齐差量个数的对象进对象池。
- 只有有泛型参数的重载方法可以进行默认容量的初始化(需要指定泛型T进行类型转换)。
- 可以选择通过传入某个实例的type类型,初始化同名的无限容量OP。
obj加载
// API
//根据keyName从对象池中获取一个T类型对象,没有则new
//string keyName
ResSystem.GetOrNew<T>(keyName);
//根据T类型名从对象池中获取一个T类型对象,没有则new
ResSystem.GetOrNew<T>();
//简单示例,获取Data数据类的一个对象
GameObject go1 = ResSystem.GetOrNew<Data>("Data");
参数说明
- 通过keyName指定加载的类对象名,不填keyName则按照T的类型名加载。
扩展功能:
- 加载时优先通过对象池获取,如果对象池中无对应资源,自动new一个类对象返回,保证返回值不为null。
obj卸载
卸载obj即将obj放回对象池进行资源回收。
//API
//根据keyName/obj类型名将obj放回对象池
//object obj, string keyName
ResSystem.PushObjectInPool(obj);
ResSystem.PushObjectInPool(obj, string keyName);
//简单示例,卸载Data类的对象data
ResSystem.PushObjectInPool(data, "Data");
参数说明
- 通过obj指定卸载的对象,keyName指定对象池名,不填则按照obj的类型名卸载。
扩展功能:
- 卸载对象时如果没有初始化过对象池,则对应自动创建一个同名无限量对象池并将obj放入。
游戏对象(GameObject)
初始化
资源系统的底层基于对象池系统,所以在资源系统层面也开放对对象池的初始化设置,API和PoolSystem类似,(Addressables通过Addressables name获取prefab,Res需要传路径来获取prefab)。
//API
//根据keyName初始化GOP
//(string keyName, int maxCapacity = -1, string assetName = null, int defaultQuantity = 0)
ResSystem.InitGameObjectPoolForKeyName(keyName, maxCapacity,assetName, defaultQuantity);
ResSystem.InitGameObjectPoolForKeyName(keyName, maxCapacity);
ResSystem.InitGameObjectPoolForKeyName(keyName);
//根据assetName在Addressables中的资源名初始化GOP
//(string assetName, int maxCapacity = -1, int defaultQuantity = 0)
ResSystem.InitGameObjectPoolForAssetName(assetName, maxCapacity, defaultQuantity);
ResSystem.InitGameObjectPoolForAssetName(assetName, maxCapacity);
ResSystem.InitGameObjectPoolForAssetName(assetName);
//简单示例
// 设定一个子弹Bullet对象池(假设Addressable资源名称为Bullet),最大容量30,默认填满
Gameobject bullet = GameObject.Find("bullet");
ResSystem.InitGameObjectPool("Bullet", 30, bullet, 30);
ResSystem.InitGameObjectPool(bullet, 30, 30);
//最简形式
ResSystem.InitGameObjectPool(“对象池名字”);
参数说明:
- 通过keyName或者直接传入assetName(Addressable资源的名称)根据获取的资源名指定对象池的名字。
- 可设置对象池最大容量maxCapacity(超过maxCapacity再放入对象会被Destroy掉)。
- 可通过prefab和defaultQuanity设置默认容量(初始化时会自动按默认容量和最大容量的最小值自动生成GameObject放入对象池)。
- 默认无限容量maxCapacity = -1,不预先放入对象,prefab = null, defaultQuantity = 0。
- defaultQuantity必须小于maxCapacity且如果想使用defaultQuantity则必须填入maxCapacity。
扩展功能:
- 可以通过重复初始化一个对象池的maxCapacity实现容量的更改,此时如果重新指定了defaultQuanity,则会补齐差量个数的对象进对象池。
GameObject加载并实例化
Addressable版本中游戏物体参数通过Addressable资源名assetName(Res是资源路径assetPath)指定,支持加载出的对象Destroy时在Addressables中自动释放。。
//API
//加载游戏物体
//(string assetName, Transform parent = null, string keyName = null, bool autoRelease = true)
ResSystem.InstantiateGameObject(assetName, parent, keyName, autoRelease);
ResSystem.InstantiateGameObject(assetName, parent, keyName);
ResSystem.InstantiateGameObject(assetName, parent);
ResSystem.InstantiateGameObject(assetName);
ResSystem.InstantiateGameObject(parent, keyName, autoRelease);
ResSystem.InstantiateGameObject(parent, keyName);
//加载游戏物体并获取组件T
ResSystem.InstantiateGameObject<T>(assetName, parent, keyName, autoRelease);
ResSystem.InstantiateGameObject<T>(assetName, parent, keyName);
ResSystem.InstantiateGameObject<T>(assetName, parent);
ResSystem.InstantiateGameObject<T>(assetName);
ResSystem.InstantiateGameObject<T>(parent, keyName, autoRelease);
ResSystem.InstantiateGameObject<T>(parent, keyName);
//异步加载(void)游戏物体
//(string assetName, Action<GameObject> callBack = null, Transform parent = null, string keyName = null, bool autoRelease = true)
ResSystem.InstantiateGameObjectAsync(assetName, callBack, parent, keyName, autoRelease);
ResSystem.InstantiateGameObjectAsync(assetName, callBack, parent, keyName);
ResSystem.InstantiateGameObjectAsync(assetName, callBack, parent);
ResSystem.InstantiateGameObjectAsync(assetName, callBack);
ResSystem.InstantiateGameObjectAsync(assetName);
//异步加载(void)游戏物体并获取组件T
//(string assetName, Action<T> callBack = null, Transform parent = null, string keyName = null, bool autoRelease = true)
ResSystem.InstantiateGameObjectAsync<T>(assetName, callBack, parent, keyName, autoRelease);
ResSystem.InstantiateGameObjectAsync<T>(assetName, callBack, parent, keyName);
ResSystem.InstantiateGameObjectAsync<T>(assetName, callBack, parent);
ResSystem.InstantiateGameObjectAsync<T>(assetName, callBack);
ResSystem.InstantiateGameObjectAsync<T>(assetName, callBack);
ResSystem.InstantiateGameObjectAsync<T>(assetName);
//简单示例
//实例化一个子弹对象(假设AB资源名称为Bullet)
GameObject bullet = ResSystem.InstantiateGameObject("Bullet");
//实例化一个子弹对象取出并获取其刚体组件
GameObject bullet = ResSystem.InstantiateGameObject("Bullet");
//异步实例化一个子弹对象,并在其加载完后坐标归零
void getBullet(GameObject bullet)
{
bullet.transform.position = Vector3.zero;
}
ResSystem.InstantiateGameObjectAsync("Bullet", getBullet);
参数说明:
- 通过assetPath加载游戏物体并实例化返回
- 实例化的游戏物体会设置父物体为parent,不填则默认为null无父物体在最顶层。
- 优先根据keyName从对象池获取,不填keyName则根据assetName在对象池中查找。
- 对象池中无缓存,则根据assetName从Addressable中获取资源,不填assetName则根据keyName从Addressable中获取资源。
- 可以通过泛型T传参获取对象上的某个组件,组件依托于GameObject存在,因此物体此时也已被从对象池中取出。
- autoRelease为true则通过事件工具为加载出的对象添加事件监听,会在其Destroy时自动调用Addressables的Release API。
- 异步加载游戏物体及其组件的方法返回值为void类型,无法直接加载的游戏物体,需要通过传入callback回调获取加载的对象并进行使用。
扩展功能:
- 如果资源路径正确,则返回值必不为空,优先从对象池中获取,对象池中不存在则根据Load的对象进行实例化返回。
GameObject卸载
卸载GameObject即将GameObject放回对象池进行资源回收。
//API
//根据keyName/gameObject.name卸载gameObject
//(string keyName, GameObject gameObject)
ResSystem.PushGameObjectInPool(keyName, gameObject);
ResSystem.PushGameObjectInPool(gameObject);
//简单示例,卸载子弹对象bullet
ResSystem.PushGameObjectInPool(bullet, "Bullet");
参数说明
- 通过gameObject指定卸载的对象,keyName指定对象池名,不填则按照gameObject的对象名卸载。
扩展功能:
- 卸载对象时如果没有初始化过对象池,则对应自动创建一个同名无限量对象池并将gameObject放入。
Unity资源
这类资源不需要进行实例化,所以不需要过对象池,只需要使用数据或者引用,比如AudioClip,Sprite,prefab。
加载Asset
//API
//根据assetName异步加载T类型资源
//(string assetName, Action<T> callBack)
ResSystem.LoadAssetAsync<T>(string assetName, Action<T> callBack);
//根据assetName加载T类型资源
ResSystem.LoadAsset<T>(assetName);
//根据keyName异步加载所有资源(void)
//(string keyName, Action<IList<T>> callBack = null, Action<T> callBackOnEveryOne = null)
ResSystem.LoadAssetsAsync<T>(keyName, callBack, callBackOnEveryOne);
//根据keyName加载所有资源(IList<T>)
//(tring keyName, Action<T> callBack = null)
ResSystem.LoadAssets<T>(keyName, callBackOnEveryOne);
//简单示例,加载Addressable clip音频资源
ResSystem.LoadAssets<AudioClip>("clip");
参数说明
- 通过path路径加载资源,T用来指明加载的资源类型。
- 异步加载单个资源需要通过传入callback回调获取加载的资源并进行使用。
- 加载所有资源时不指定T则返回object数组,keyName是Addressable中的Labels。
- Addressable加载指定keyName的所有资源时,支持每加载一个资源调用一次callBackOnEveryOne。
- 异步加载指定keyName所有资源时,调用callback获取加载的资源并进行使用。
- 注意加载的资源不会被自动释放。
卸载Asset
//API
//释放某个资源
//(T obj)
ResSystem.UnloadAsset<T>(T obj);
//销毁对象并释放资源
//(GameObject obj)
ResSystem.UnloadInstance(obj);
卸载Asset即释放资源,可以在Destroy游戏对象的同时释放Addressable资源。
资源系统-自动生成资源引用代码
针对Addressables版本,使用字符串来加载资源方式比较麻烦,而且容易输错,框架提供一种基于引用加载的方式。
通过Editor工具会在指定路径下生成资源引用代码R。
// API
//返回一个资源
R.GroupName.AddressableName;
//返回一个资源的实例
//(Transform parent = null,string keyName=null,bool autoRelease = true)
R.GroupName.AddressableName(parent, keyName, autoRelease);
R.GroupName.AddressableName(parent, keyName);
R.GroupName.AddressableName(parent);
//使用示例
//获取一个Bullet预制体资源(不实例化)
Gameobject bullet = R.DefaultLocalGroup.Bullet;
//获取一个Bullet预制体资源并实例化
Gameobject bullet = R.DefaultLocalGroup.Bullet(transform);
参数说明
- R是资源脚本的命名空间,固定。
- GroupName是Addressable的组名。
- AddressableName是资源名。
- 如果填写keyName,则先去对象池中找资源实例,找不着再通过Addressable获取资源并实例化。
- parent为实例的父物体。
- autoRelease为true则实例会在Destroy时自动释放Addressable中对应的资源。
拓展功能
对于Sprite的子图,也支持直接引用。
//子图
R.LV2.Img_Img_0;
//总图
R.Lv2.Img;
事件系统
框架的事件系统主要负责高效的方法调用与数据传递,实现各功能之间的解耦,通常在调用某个实例的方法时,必须先获得这个实例的引用或者新实例化一个对象,低耦合度的框架结构希望程序本身不去关注被调用的方法所依托的实例对象是否存在,通过事件系统做中转将功能的调用封装成事件,使用事件监听注册、移除和事件触发完成模块间的功能调用管理。常用在UI事件、跨模块事件上。
事件系统支持无返回值的Action,Func实际应用意义不大。
事件监听添加
//API
//添加无参数的事件监听
//string eventName, Action action
AddEventListener(eventName, action);
//添加多个参数的事件监听
//string eventName
AddEventListener<T>(eventName, action);
AddEventListener<T0, T1>(eventName, action);
AddEventListener<T0, T1, T2>(eventName, action);
...
AddEventListener<T0, T1, ..., T15>(eventName, action);
//简单示例
//添加无参数的事件监听,Doit方法对应名称为Test的事件
EventSystem.AddEventListener("Test", Doit);
void Doit()
{
Debug.Log("Doit");
}
//添加多个参数的事件监听,Doit2对应名称为TestM的事件,参数为int,string
EventSystem.AddEventListener<int, string>("TestM", Doit2);
void Doit2(int a, string b)
{
Debug.Log(a);
Debug.Log(b);
}
参数说明
- eventName是解耦执行的方法的标记,即事件名,是触发事件时的唯一依据。
- action传无返回值方法。
- T0~T15是泛型,用于指定参数表,支持最多16个参数的action。
事件监听移除
//API
//添加无参数的事件监听
//string eventName, Action action
RemoveEventListener(eventName, action);
//添加多个参数的事件监听
//string eventName
RemoveEventListener<T>(eventName, action);
RemoveEventListener<T0, T1>(eventName, action);
RemoveEventListener<T0, T1, T2>(eventName, action);
...
RemoveEventListener<T0, T1, ..., T15>(eventName, action);
//简单示例
//移除无参数的事件监听,Doit方法对应名称为Test的事件
EventSystem.RemoveEventListener("Test", Doit);
void Doit()
{
Debug.Log("Doit");
}
//移除多个参数的事件监听,Doit2对应名称为TestM的事件,参数为int,string
EventSystem.RemoveEventListener<int, string>("TestM", Doit2);
void Doit2(int a, string b)
{
Debug.Log(a);
Debug.Log(b);
}
参数说明
- eventName是解耦执行的方法的标记,即事件名,是触发事件时的唯一依据。
- action传无返回值方法。
- T0~T15是泛型,用于指定参数表,支持最多16个参数的action。
事件触发
//API
//触发无参数事件
EventSystem.EventTrigger(string eventName);
//触发多个参数事件
EventSystem.EventTrigger<T>(string eventName, T arg);
EventSystem.EventTrigger<T0, T1>(string eventName, T0 arg0, T1 arg1);
EventSystem.EventTrigger<T0, T1,..., T15>(string eventName, T0 arg0, T1 arg1, ..., T15 arg15);
//简单示例,使用添加监听的方法例子
EventSystem.EventTrigger("Test");
EventSystem.EventTrigger<int,string>("TestM",1,"test");
参数说明
- eventName是解耦执行的方法的标记,即事件名,是触发事件时的唯一依据。
- T0~T15是泛型,用于指定参数表,支持最多16个参数的action。
事件移除
事件移除和事件监听移除的区别参与:
- 事件监听移除只移除一条Action,比如添加了3次同名事件监听,则移除一次后触发还是会执行两次,且eventName记录不会被移除。
- 事件移除会将事件中心字典中有关eventName的记录连带存储的Action一同清空。
//API
//移除一类事件
//(string eventName)
EventSystem.RemoveEvent(eventName);
//移除事件中心中所有事件
EventSystem.Clear();
参数说明
- eventName是解耦执行的方法的标记,即事件名,是触发事件时的唯一依据。
注意
事件系统的运行逻辑是,预先添加/移除事件监听,再在能够获取相应参数的类内触发事件。
音效系统
音效服务集成了背景、特效音乐播放,音量、播放控制功能。包含了全局音量globalVolume、背景音量bgVolume、特效音量effectVolume、静音布尔量isMute、暂停布尔量isPause等音量相关的属性,播放背景音乐的PlayBGAudio方法且,播放特效音乐PlayOnShot方法且重载后支持在指定位置或绑定游戏对象播放特定的音乐,特效音乐由于要重复使用,可以从对象池中获取播放器并自动回收,支持播放后执行回调事件。
播放背景音乐
音量、播放属性控制
音效服务支持在Inspector面板上的值发生变化时自动执行相应的方法更新音量属性,也可以在属性值变化时自动调用相应的更新方法。
//API & 示例
//全局音量(float,0~1),音量设定为50%
AudioSystem.GlobalVolume = 0.5f;
//背景音乐音量(float,0~1),音量设定为50%
AudioSystem.BGVolume = 0.5f;
//特效音乐音量(flaot,0~1)
AudioStystem.EffectVolume = 0.5f;
//是否全局静音(bool),true则静音
AudioSystem.IsMute = true;
//背景音乐是否循环,true则循环
AudioSystem.IsLoop = true;
//背景音乐是否暂停,true则暂停
AudioSystem.IsPause = true;
参数说明
- GlobalVolume是全局音量,同时影响背景、特效音乐音量。
- BGVolume是背景音乐音量
- EffectVolume是特效音乐音量。
- IsMute控制全局音量是否静音。
- IsLoop控制背景音乐是否循环。
- IsPause控制背景音乐是否暂停。
拓展功能
支持通过面板更新音量属性。
播放背景音乐
//API
//播放背景音乐
//(AudioClip clip, bool loop = true, float volume = -1)
AudioSystem.PlayBGAudio(clip, loop, volume);
//轮播多个背景音乐
//(AudioClip[] clips, float volume = -1)
AudioSystem.PlayBGAudioWithClips(clips, volume);
//停止当前背景音乐
AudioSystem.StopBGAudio();
//暂停当前背景音乐
AudioSystem.PauseBGAudio();
//取消暂停当前音乐
AudioSystem.UnPauseBGAudio();
//简单示例
AudioClip clip = ResSystem.LoadAsset<AudioClip>("music");
AudioSystem.PlayBGAudio(clip);
参数说明
- clip是音乐片段,可以传clip数组来轮播音乐。
- volume是音乐的音量,不指定则按原来的背景音量。
- 停止当前背景音乐会将当前背景音乐置空。
- 暂停音乐可取消暂停恢复。
播放特效音乐
//API
//播放一次音效并绑定到游戏物体上,位置随物体变化
//(AudioClip clip, Component component = null, bool autoReleaseClip = false, float volumeScale = 1, bool is3d = true, Action callBack = null)
audioSystem.PlayOnShot(clip, component, autoReleaseClip, volumeScale, is3d, callBack);
audioSystem.PlayOnShot(clip, component, autoReleaseClip, volumeScale, is3d);
audioSystem.PlayOnShot(clip, component, autoReleaseClip, volumeScale);
audioSystem.PlayOnShot(clip, component, autoReleaseClip);
audioSystem.PlayOnShot(clip, component);
audioSystem.PlayOnShot(clip);
//在指定位置上播放一次音效
//(AudioClip clip, Vector3 position, bool autoReleaseClip = false, float volumeScale = 1, bool is3d = true, Action callBack = null)
audioSystem.PlayOnShot(clip, position, autoReleaseClip, volumeScale, is3d, callBack);
audioSystem.PlayOnShot(clip, position, autoReleaseClip, volumeScale, is3d);
audioSystem.PlayOnShot(clip, position, autoReleaseClip, volumeScale);
audioSystem.PlayOnShot(clip, position, autoReleaseClip);
audioSystem.PlayOnShot(clip, position);
//简单示例
//在玩家位置播放一次音效
AudioClip clip = ResSystem.LoadAsset<AudioClip>("music");
audioSystem.PlayOnShot(clip,player.transform.position);
//绑定玩家组件播放一次音效(等同于玩家位置)
audioSystem.PlayOnShot(clip,player.transform);
参数说明
- clip是音乐片段,音效系统中特效音乐在每次播放时优先从对象池中取出挂载了AudioSource的GameObject实例生成并会在音效播放完成后自动回收。
- postion是播放的位置,必填。
- component是绑定的组件,这个API的目的是让音效随着物体移动一起移动,不填则默认不绑定。
- autoReleaseClip代表是否需要在音乐播放结束后自动释放clip资源,Res和Addressable均可。
- volumeScle是音乐的音量,不指定默认按最大音量。
- is3D是启用空间音效,默认开启。
- callBack是回调事件,会在音效播放完执行一个无参无返回值方法。
拓展功能
使用Compoent绑定播放音效时,如果绑定物体如果在播放中被销毁了,那么AudioSource会提前解绑避免一同被销毁(通过事件工具提前添加监听),之后播放完毕会自动回收。
存档系统
完成对存档的创建,获取,保存,加载,删除,缓存,支持多存档。存档有两类,一类是用户型存档,存储着某个游戏用户具体的信息,如血量,武器,游戏进度,一类是设置型存档,与任何用户存档都无关,是通用的存储信息,比如屏幕分辨率、音量设置等。
存档系统支持两类本地文件:二进制流文件、Json,两者通过框架设置面板进行切换,切换时,原本地文件存档会清空!二进制流文件可读性较差不易修改,Json可读性较强,易修改,存档的数据存在Application.persistentDataPath下。
SaveData和setting分别存储用户存档和设置型存档。
用户存档下根据saveID分成若干文件夹用于存储具体的对象。
设置型存档
设置存档实际就是一个全局唯一的存档,可以向其中存储全局通用数据。
保存设置
//API
//保存设置到全局存档
//(object saveObject, string fileName)
SaveSystem.SaveSetting(saveObject, fileName);
SaveSystem.SaveSetting(saveObject)
//简单示例
//见下一小节结合加载说明
参数说明
- saveObject是要保存的对象,System.Object类型。
- fileName是保存的文件名称,不填默认取saveObject的类型名。
加载设置
///API
//从设置存档中加载设置
// string fileName
SaveSystem.LoadSetting<T>(fileName);
SaveSystem.LoadSetting<T>();
//简单示例
// GameSetting类中存储着游戏名称,作为全局数据
[Serializable]
public class GameSetting
{
public string gameName;
}
GameSetting gameSetting = new GameSetting();
gameSetting.gameName = "测试";
//保存设置
SaveSystem.SaveSetting(gameSetting);
//取出来用
String gameName = SaveSystem.LoadSetting<gameSetting>().gameName;
删除设置
//API
//删除用户存档和设置存档
SaveSystem.DeleteAll();
参数说明
- fileName是加载设置存档的文件名,T限定了所存储的数据类型,不填fileName则默认以T的类型名作为文件名加载。
用户存档
用户存档与具体的用户相关,不同用户存档位置不同,数据也不同,索引为SaveID。
创建用户存档
创建的存档索引默认自增。
//API
SaveSystem.CreateSaveItem();
//简单示例
SaveItem saveItem = SaveSystem.CreateSaveItem();
获取用户存档
存档层面
获取所有用户存档
根据一定规则获取所有用户存档,返回List。
//API
//最新的在最后面
SaveSystem.GetAllSaveItem();
//最近创建的在最前面
SaveSystem.GetAllSaveItemByCreatTime();
//最近更新的在最前面
SaveSystem.GetAllSaveItemByUpdateTime();
//万能解决方案,自定义规则
GetAllSaveItem<T>(Func<SaveItem, T> orderFunc, bool isDescending = false)
//简单示例,万能方案,按照SaveID倒序获得存档
GameSetting gameSetting = new GameSetting();
List<SaveItem> testList = SaveSystem.GetAllSaveItem<int>(oderFunc, true);
//List<SaveItem> testList = SaveSystem.GetAllSaveItem();
foreach (var item in testList)
{
Debug.Log(item.saveID);
}
//排序依据Func
int oderFunc(SaveItem item)
{
return item.saveID;
}
参数说明
- 提供多种重载方法获取存档List。
- 支持自定义排序依据的万解决方案,T传比较参数类型,orderFunc传比较方法。
获取某一项用户存档
//API
//(int id, SaveItem saveItem)
SaveSystem.GetSaveItem(id);
SaveSystem.GetSaveItem(saveItem);
//简单示例
SaveItem saveItem = SaveSystem.CreateSaveItem();
SaveSystem.GetSaveItem(saveItem);
参数说明
- id是用户存档的编号,存档系统会在创建时指定默认ID,使用时透明,因此推荐使用saveItem传参,saveItem是可维护的。
删除用户存档
删除所有用户存档
//API
//删除所有用户存档
SaveSystem.DeleteAllSaveItem();
删除某一项用户存档
//API
//(int id, SaveItem saveItem)
SaveSystem.DeleteSaveItem(id);
SaveSystem.DeleteSaveItem(saveItem);
//简单示例
SaveItem saveItem = SaveSystem.CreateSaveItem();
SaveSystem.DeleteSaveItem(saveItem);
参数说明
- id是用户存档的编号,存档系统会在创建时指定默认ID,使用时透明,因此推荐使用saveItem传参,saveItem是可维护的。
存档对象层面
保存用户存档中某一对象
//API
//(object saveObject, string saveFileName, SaveItem saveItemint, saveID = 0)
SaveSystem.SaveObject(saveObject, saveFileName, saveID);
SaveSystem.SaveObject(saveObject, saveFileName, saveItem);
SaveSystem.SaveObject(saveObject, saveID);
SaveSystem.SaveObject(saveObject, saveItem);
//简单示例
SaveItem saveItem = SaveSystem.CreateSaveItem();
GameSetting gameSetting = new GameSetting();
SaveSystem.SaveObject(gameSetting, saveItem);
参数说明
- saveObject是要保存的对象。
- saveFileName是保存后生成的本地文件名(对象会单独作为一个文件存储在对应saveID的文件夹下),不填则以对象的类型名为文件名。
- saveID/SaveItem是对象存储的存档。
- 保存对象时会更新用户存档缓存。
获取用户存档中某一对象
//API
//(string saveFileName, SaveItem saveItem, int saveID = 0)
SaveSystem.LoadObject<T>(saveFileName, saveID);
SaveSystem.LoadObject<T>(saveFileName, saveItem);
SaveSystem.LoadObject<T>(saveID);
SaveSystem.LoadObject<T>(saveItem);
//简单示例
SaveItem saveItem = SaveSystem.CreateSaveItem();
GameSetting gameSetting = new GameSetting();
SaveSystem.SaveObject(gameSetting, saveItem);
GameSetting gameSetting = SaveSystem.LoadObject<GameSetting>(saveItem);
参数说明
- T指定获取对象类型。
- saveFileName是获取对象的文件名,不填则默认以T的类型名作为文件名。
- saveID/SaveItem是对象存储的存档。
- 获取对象优先从缓存中读取,不存在则IO读文件获取,并加入缓存。
删除用户存档中某一对象
//API
//(string saveFileName, SaveItem saveItem, int saveID = 0)
SaveSystem.DeleteObject<T>(saveFileName, saveID);
SaveSystem.DeleteObject<T>(saveFileName, saveItem);
SaveSystem.DeleteObject<T>(saveID);
SaveSystem.DeleteObject<T>(saveItem);
//简单示例
SaveItem saveItem = SaveSystem.CreateSaveItem();
GameSetting gameSetting = new GameSetting();
SaveSystem.DeleteObject(gameSetting, saveItem);
GameSetting gameSetting = SaveSystem.DeleteObject<GameSetting>(saveItem);
参数说明
- T指定获取对象类型。
- saveFileName是获取对象的文件名,不填则默认以T的类型名作为文件名。
- saveID/SaveItem是对象存储的存档。
- 删除某一对象时,如果存在对应的缓存,则一并删除。
注意
在从用户存档中取出对象时,底层优先从缓存中读取,避免读时IO,使用时无需关注。
UI框架
UI框架实现对窗口的生命周期管理,层级遮罩管理,按键物理响应等功能,对外提供窗口的打开、关闭、窗口复用API,对内优化好窗口的缓存、层级问题,能够和场景加载、事件系统联动,将Model、View、Controller完全解耦。通过与配置系统、脚本可视化合作,实现新UI窗口对象的快速开发和已有UI窗口的方便接入。
UI窗口配置
使用UI框架需要先为UI窗口游戏对象添加控制类,该类继承自UI_WindowBase,并标有UIWindowData特性(Attribute可省略),并将UI窗口游戏对象加入Addressable列表/Resources文件夹下。
UIWindowDataAttribute(string windowKey, bool isCache, string assetPath, int layerNum){}
UIWindowDataAttribute(Type type,bool isCache, string assetPath, int layerNum){}
参数说明
- 特性中windowKey是UI窗口的名字唯一索引,可以直接传string也可以传Type使用其FullName。
- isCache指明UI窗口游戏对象是否需要缓存重用,true则在窗口关闭时不会被销毁,下次使用时可以通过windowKey调用切不需要实例化。
- assetPath是资源的路径,在Resources中是UI窗口对象在Resources文件夹下的路径,Addressable中是UI窗口对象的Addressable Name。
- layerNum是UI窗口对象的层级,从0开始,越大则约接近顶层。
UI窗口管理
UI窗口的