11.5 网络联机对战11-1_哔哩哔哩_bilibili
优化技术
面临的问题:
经常生成重复的对象【可以是游戏对象,也可以是普通对象】
同样的对象,生命周期短
例如:子弹、怪物、特效、音效
问题在哪?频繁的生成和销毁
缺点:占用了一些内存
池子是动态的
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class CubeObject : PoolObject {
private Rigidbody _rigidbody;
private void Awake()
{
_rigidbody = GetComponent();
}public override void OnSpawn()
{
//速度归零
_rigidbody.velocity = Vector3.zero;_rigidbody.angularVelocity = Vector3.zero;
}public override void OnPause()
{
base.OnPause();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PoolObject : MonoBehaviour {
[Header("对象的生命周期")]
public float lifeTime = 2f;public virtual void OnEnable()
{
//启动协程
StartCoroutine(DelayEnterPool());
}///
/// 延迟进入对象池
///
///
private IEnumerator DelayEnterPool() {
yield return new WaitForSeconds(lifeTime);
//进入对象池
GameObjectPool.Instance.SetGameObject(gameObject);
}///
/// 对象出生后要做的事情【初始化操作】
///
public virtual void OnSpawn() {}
///
/// 对象进入对象池之前要做的事情
///
public virtual void OnPause() {}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class UsePool : MonoBehaviour {
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Space)) {
//获取对象
GameObjectPool.Instance.GetGameObject("Cube", Vector3.zero, Quaternion.identity);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using System;
namespace Utility
{
public class Singletonwhere T : class
{
//单例对象
private static T _singleton;
//获取单例
public static T Instance
{
get
{
if (_singleton == null)
{
//如果这样写,那么该类型T必有一个public的构造函数
//_singleton = new T();
//通过反射的方式,去实例化一个对象出来
//派生的单例类中必须要有一个私有的无参构造
_singleton = (T)Activator.CreateInstance(typeof(T), nonPublic: true);}
return _singleton;
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Utility
{
public class AssetsManager : Singleton
{
//私有构造
private AssetsManager()
{
assetsCache = new Dictionary();
}///
/// 资源缓存
///private Dictionary
assetsCache;
///
/// 获取资源
///
///
/// 资源路径
///public Object OldGetAsset
(string path)
{
//要返回的资源
Object assetObj = null;
//如果缓存中没有该资源
if (!assetsCache.ContainsKey(path))
{
//通过resources加载资源
assetObj = Resources.Load(path);
//将资源存进缓存
assetsCache.Add(path, assetObj);
}
else
{
//如果缓存中有,则直接从缓存中拿
assetObj = assetsCache[path];
}return assetObj;
}
///新方法---获取资源
public Object GetAsset(string path)
{
//要返回的资源
Object assetObj = null;
//尝试从字典中获取该路径所对应的资源
if (!assetsCache.TryGetValue(path, out assetObj))
{
//通过resources加载资源
assetObj = Resources.Load(path);
//将资源存进缓存
assetsCache.Add(path, assetObj);
}
return assetObj;
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Utility;public class GameObjectPool {
#region Singleton
//单例
public readonly static GameObjectPool Instance = new GameObjectPool();private GameObjectPool() {
pool = new Dictionary>();
}#endregion
#region Object Pool
///
/// 对象池
///
Dictionary> pool; ///取
///从对象池取对象
///
public GameObject GetGameObject(string objName,Vector3 pos, Quaternion rotation) {
//要返回的游戏对象
GameObject obj;
//没有对应的子对象池,或有对应的对象池但池子为空
if (!pool.ContainsKey(objName) || pool[objName].Count == 0)
{
//先拿到预设体
UnityEngine.Object prefab=AssetsManager.Instance.GetAsset(objName);
//Instantiate生成
obj=GameObject.Instantiate(prefab,pos,rotation) as GameObject;
//改名字
obj.name = objName;
}
else {
//从池子中获取
obj = pool[objName][0];
//删除池中对象
pool[objName].RemoveAt(0);
//设置位置
obj.transform.position = pos;
//设置旋转
obj.transform.rotation = rotation;
}
//激活对象
obj.SetActive(true);
try {
//获取对象脚本
obj.GetComponent().OnSpawn();
}
catch (Exception e) {
Debug.LogWarning(e);
}
//返回对象
return obj;
}
///存
///将对象存入对象池
///
public void SetGameObject(GameObject obj) {
try
{
//获取对象脚本
obj.GetComponent().OnPause();
}
catch (Exception e)
{
Debug.LogWarning(e);
}
//存入之前,先取消激活
obj.SetActive(false);
//判断有没有对应的子对象池
if (!pool.ContainsKey(obj.name))
{
//新建子对象池,并将当前对象存入
pool.Add(obj.name, new List() { obj });
}
else {
//将当前对象存入对象池
pool[obj.name].Add(obj);
}
}#endregion
}