unity3d框架研究之对象池

本文介绍了一个对象池服务的实现方式,该服务通过复用对象来减少系统开销和内存垃圾的产生。对象池在激活对象时从池中提取,停用时放回池中等待下一次使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码内容不是本人原创的,请原谅我斗胆作为原创发表:


对象池服务可以减少从头创建每个对象的系统开销,在激活对象时,它从池中提取。在停用对象时,它放回池中,等待下一个请求。

下面是代码:

/**  
 * 简    述:对象池服务可以减少从头创建每个对象的系统开销。而且可以避免多余的内存垃圾产生。  
 * 在激活对象时,它从池中提取。在停用对象时,它放回池中,等待下一个请求。  
 */  
using UnityEngine;  
using System;  
using System.Collections;  
using Need.Mx;  
  
public interface IDynamicObject  
{  
    /// <summary>  
    /// 可以用来创建实际的对象,如:建立数据库连接,并打开这个连接  
    /// </summary>  
    void Create(System.Object param);  
    /// <summary>  
    /// 使用户可以返回这个实际 的对象,如一个SqlConnection对象  
    /// </summary>  
    System.Object GetInnerObject();  
    /// <summary>  
    /// 用来判断用户自定义对象的有效性的,是对象池决定是否重新创建对象的标志  
    /// </summary>  
    bool IsValidate();  
    /// <summary>  
    /// 用户可以进行资源释放工作。   
    /// </summary>  
    void Release();  
}  
  
public sealed class ObjectPool  
{  
    private class PoolItem  
    {  
        private IDynamicObject _object;  
        /// <summary>  
        /// 代表是否正在被用户使用  
        /// </summary>  
        private bool _bUsing;  
        private Type _type;  
  
        /// <summary>  
        /// 创建内部持有对象的必要基本参数。  
        /// </summary>  
        private System.Object _CreateParam;  
  
        public PoolItem(Type type, System.Object param)  
        {  
            _type = type;  
            _CreateParam = param;  
            Create();  
        }  
  
        private void Create()  
        {  
            _bUsing = false;  
            _object = (IDynamicObject)System.Activator.CreateInstance(_type);  
            _object.Create(_CreateParam);  
        }  
  
        public void Recreate()  
        {  
            _object.Release();  
            Create();  
        }  
  
        public void Release()  
        {  
            _object.Release();  
        }  
  
        public System.Object InnerObject { get { return _object.GetInnerObject(); } }  
  
        public int InnerObjectHashcode { get { return InnerObject.GetHashCode(); } }  
  
        public bool IsValidate { get { return _object.IsValidate(); } }  
  
        public bool Using  
        {  
            get { return _bUsing; }  
            set { _bUsing = value; }  
        }  
    }// class PoolItem  
    private int _nCapacity;  
    private int _nCurrentSize;  
    private Hashtable _listObjects;  
    private ArrayList _listFreeIndex;  
    private ArrayList _listUsingIndex;  
    private Type _typeObject;  
    private System.Object _objCreateParam;  
  
    /// <summary>  
    /// 构造指定类型的对象池,主要给具体对象池使用。  
    /// </summary>  
    /// <param name="type">对象的类型typeof</param>  
    /// <param name="create_param">创建对象的参数</param>  
    /// <param name="init_size">预创建的对象个数</param>  
    /// <param name="capacity">预创建的对象池大小</param>  
    public ObjectPool(Type type, System.Object create_param, int init_size, int capacity)  
    {  
        if (init_size < 0 || capacity < 1 || init_size > capacity)  
        {  
            throw (new Exception("Invalid parameter!"));  
        }  
  
        _nCapacity = capacity;  
        _listObjects = new Hashtable(capacity);  
        _listFreeIndex = new ArrayList(capacity);  
        _listUsingIndex = new ArrayList(capacity);  
        _typeObject = type;  
        _objCreateParam = create_param;  
  
        for (int i = 0; i < init_size; i++)  
        {  
            PoolItem pitem = new PoolItem(type, create_param);  
            _listObjects.Add(pitem.InnerObjectHashcode, pitem);  
            _listFreeIndex.Add(pitem.InnerObjectHashcode);  
        }  
  
        _nCurrentSize = _listObjects.Count;  
    }  
  
    /// <summary>  
    /// foreach的会产生一些内存垃圾,Release()还是少调用比较好。  
    /// </summary>  
    public void Release()  
    {  
        lock (this)  
        {  
            foreach (DictionaryEntry de in _listObjects)  
            {  
                ((PoolItem)de.Value).Release();  
            }  
            _listObjects.Clear();  
            _listFreeIndex.Clear();  
            _listUsingIndex.Clear();  
        }  
    }  
  
    /// <summary>  
    /// 当前对象池中所拥有的对象个数。  
    /// </summary>  
    public int CurrentSize  
    {  
        get { return _nCurrentSize; }  
    }  
  
    public int ActiveCount  
    {  
        get { return _listUsingIndex.Count; }  
    }  
  
    public System.Object GetOne()  
    {  
        lock (this)  
        {  
            if (_listFreeIndex.Count == 0)  
            {  
                if (_nCurrentSize == _nCapacity)  
                {  
                    UnityEngine.Debug.LogError("ObjectPool has no more capacity to create new object");  
                    return null;  
                }  
                PoolItem pnewitem = new PoolItem(_typeObject, _objCreateParam);  
                Debug.Log("Create New PoolItem!! ID:" + pnewitem.InnerObjectHashcode);  
                _listObjects.Add(pnewitem.InnerObjectHashcode, pnewitem);  
                _listFreeIndex.Add(pnewitem.InnerObjectHashcode);  
                _nCurrentSize++;  
            }  
            //Debug.Log("UsingIndex Add Object :" + _listFreeIndex[0]);  
            int nFreeIndex = (int)_listFreeIndex[0];  
            PoolItem pitem = (PoolItem)_listObjects[nFreeIndex];  
            _listFreeIndex.RemoveAt(0);  
            _listUsingIndex.Add(nFreeIndex);  
            //Debug.Log("UsingIndex Add Object :" + nFreeIndex);  
            if (!pitem.IsValidate)  
            {  
                //这里需要注意,Recreate()很可能会改变InnerObject的HashCode,  
                //所以考虑在这里,使用  
                pitem.Recreate();  
  
                if (nFreeIndex != pitem.InnerObjectHashcode)  
                {  
                    _listObjects.Remove(nFreeIndex);  
                    _listUsingIndex.Remove(nFreeIndex);  
                    nFreeIndex = pitem.InnerObjectHashcode;  
                    _listObjects.Add(nFreeIndex, pitem);  
                    _listUsingIndex.Add(nFreeIndex);  
                }  
            }  
            pitem.Using = true;  
            return pitem.InnerObject;  
        }  
    }  
  
    public void FreeObject(System.Object obj)  
    {  
        lock (this)  
        {  
            int key = obj.GetHashCode();  
            if (_listObjects.ContainsKey(key))  
            {  
                PoolItem item = (PoolItem)_listObjects[key];  
                item.Using = false;  
                _listUsingIndex.Remove(key);  
                _listFreeIndex.Add(key);  
            }  
            else  
            {  
                //throw new InvalidOperationException("试图归还一个非法的资源!ID:" + obj.GetHashCode() + obj);  
                Debug.LogWarning("试图归还一个非法的资源!ID:" + key + obj + obj.GetHashCode());  
            }  
        }  
    }  
  
    public int DecreaseSize(int size)  
    {  
        int nDecrease = size;  
        lock (this)  
        {  
            if (nDecrease <= 0)  
            {  
                return 0;  
            }  
            if (nDecrease > _listFreeIndex.Count)  
            {  
                nDecrease = _listFreeIndex.Count;  
            }  
  
            for (int i = 0; i < nDecrease; i++)  
            {  
                _listObjects.Remove(_listFreeIndex[i]);  
            }  
  
            _listFreeIndex.Clear();  
            _listUsingIndex.Clear();  
  
            foreach (DictionaryEntry de in _listObjects)  
            {  
                PoolItem pitem = (PoolItem)de.Value;  
                if (pitem.Using)  
                {  
                    _listUsingIndex.Add(pitem.InnerObjectHashcode);  
                }  
                else  
                {  
                    _listFreeIndex.Add(pitem.InnerObjectHashcode);  
                }  
            }  
        }  
        _nCurrentSize -= nDecrease;  
        return nDecrease;  
    }  
}  

<think>嗯,用户现在需要Unity3D答辩的PPT模板或者内容。首先,我需要回顾一下用户之前的对话和需求。用户之前提到过基于Unity的餐厅经营游戏毕业设计,包括源码、开题报告、论文、答辩PPT等,所以他们的项目可能与游戏开发相关,特别是餐厅模拟经营类。 用户现在的请求是寻找答辩PPT的模板或内容,可能需要结构化的建议,而不仅仅是模板链接。考虑到学术答辩的特点,PPT需要涵盖项目背景、技术实现、创新点、成果展示等部分。同时,用户可能希望内容能突出他们的技术选型和项目亮点,比如Unity的功能应用、数据库设计、网络功能等。 根据引用内容,用户之前的项目涉及到服务器端控制、倒计时同步、客户端交互,这些技术点应该在PPT中有所体现。另外,他们可能还需要展示游戏的核心玩法、系统架构、遇到的挑战及解决方案。需要提醒用户注意答辩PPT的结构,比如分章节、逻辑清晰,以及视觉设计上的建议,比如使用截图、视频和代码片段来增强展示效果。 用户可能没有明确说出的是,他们希望PPT不仅结构合理,还能吸引评委注意,有效传达项目的价值和创新。因此,除了模板结构,还需要强调内容的具体要点,比如技术实现的细节、成果展示的方式,以及如何突出项目的独特之处,比如AR功能或AI算法的应用。 需要检查是否有遗漏的部分,比如测试与优化、未来展望,这些也是答辩中常被问到的内容。同时,用户可能需要避免常见的答辩错误,比如内容过于技术化而忽略项目背景和实际应用,或者PPT文字过多,不够简洁。 最后,确保回答符合用户的要求,使用中文,结构清晰,分点说明,并提供相关问题供用户进一步思考。可能的问题包括如何组织答辩演讲、如何处理评委提问等,但根据用户提供的引用,相关问题需要围绕Unity3D答辩PPT的内容展开,比如模板获取途径、结构优化、技术展示方法等。</think>### Unity3D答辩PPT内容框架与制作建议 #### 一、PPT核心模块(基于游戏开发类项目示例) 1. **封面设计** - 主标题:基于Unity3D的XX系统/游戏开发(如《餐厅经营模拟系统》) - 副标题:设计与实现/关键技术研究 - 必要元素:学校LOGO、答辩人姓名、导师信息、日期 - 视觉建议:使用游戏场景截图+半透明蒙版 2. **技术架构图示** ```mermaid graph TD A[Unity3D引擎] --> B[核心模块] B --> C(场景搭建) B --> D(物理系统) B --> E(UI交互) B --> F(网络同步) A --> G[数据库] G --> H(MySQL存储玩家数据) G --> I(Redis缓存高频数据) ``` 3. **创新点展示** - 同步技术实现:如引用[2]中提到的倒计时同步方案 - 关键技术:$T_{sync}=T_{server}+ΔT$ 时间同步公式 - 性能优化:通过对象池技术将内存占用降低40%[^2] #### 二、内容编排技巧 1. **技术细节可视化** - 使用Unity Profiler性能分析截图 - 展示Shader代码片段: ```hlsl Shader "Custom/CelShading" { Properties { _MainTex ("Texture", 2D) = "white" {} _RampTex ("Ramp Texture", 2D) = "white" {} } // 此处省略具体实现代码 } ``` 2. **成果对比展示** - 开发前后对比:传统管理 vs 游戏化系统(参考引用[1]的行业痛点分析) - 技术指标对比表: | 指标 | 优化前 | 优化后 | |--------------|--------|--------| | 帧率(FPS) | 30 | 60 | | 加载时间(s) | 8 | 2.5 | | 安装包大小(MB)| 450 | 220 | #### 三、资源获取途径 1. **模板资源平台** - OfficePLUS(微软官方模板库) - SlideModel(专业答辩模板) - GitHub搜索关键词:"unity-defense-ppt" 2. **素材处理工具** - 三维模型展示:Blender导出glTF格式模型 - 动态图表:使用Power BI嵌入实时数据 - 特效展示:ScreenToGif录制游戏演示 #### 四、答辩演示技巧 1. **代码展示规范** - 关键算法使用语法高亮: ```csharp void UpdatePlayerState() { if (isServer) { currentTime -= Time.deltaTime; if (currentTime <= 0) StartGame(); } } ``` - 网络同步逻辑需标注引用[2]的实现方案 2. **常见问题准备** - 物理系统:如何实现碰撞检测优化? - 人工智能:NPC行为树的实现方式? - 性能优化:Draw Call合并的具体策略?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值