U3D应用缓存管理物体

 

1. 在Unity中比较常见的功能发射子弹,一般得我们都去动态生成物体(子弹prefab).

  •      动态生成物体优点:1.可以灵活的控制场景 2. 可以马上看到效果.
  •      缺点:这样不断的生成,销毁,性能开销大. 

 

2. 所以一般我们使用Cache 缓存来完成. 上代码.

 

3. 首先创建一个脚本,巢穴吧.

  

public class DbSpawn : MonoBehaviour
{
    public static DbSpawn Instance;

    public ObjectCache[] Caches;

    private Hashtable _cacheObjects;

    [System.Serializable]
    public class ObjectCache
    {
        public GameObject Prefab;
        public int CacheLens = 10;

        private GameObject[] _objects;
        private int cacheIndex = 0;


        /// <summary>
        /// 初始化
        /// </summary>
        public void Init()
        {
            _objects = new GameObject[CacheLens];

            for (int i = 0; i < CacheLens; i++)
            {
                _objects[i] = Instantiate(Prefab) as GameObject;
                _objects[i].gameObject.SetActive(false);
                _objects[i].name = _objects[i].name + i;
            }
        }


        /// <summary>
        /// 获取没有被激活的
        /// </summary>
        /// <returns></returns>
        public GameObject GetNextObjectCache()
        {
            GameObject obj = null;

            for (int i = 0; i < CacheLens; i++)
            {
                obj = _objects[cacheIndex];

                if (!obj.activeSelf)
                {
                    break;
                }

                cacheIndex = (cacheIndex + 1) % CacheLens;
            }

            if (obj != null && obj.activeSelf)
            {
                DbSpawn.Destroy(obj);
            }

            cacheIndex = (cacheIndex + 1) % CacheLens;
            return obj;
        }
    }


    void Awake()
    {
        Instance = this;

        var total = 0;

        foreach (ObjectCache t in Caches)
        {
            t.Init();

            total += t.CacheLens;
        }

        _cacheObjects = new Hashtable(total);
    }

    /// <summary>
    /// 孵化一个prefab实例
    /// </summary>
    /// <param name="prefab"></param>
    /// <param name="position"></param>
    /// <param name="rotation"></param>
    /// <returns></returns>
    public static GameObject SpawnObject(GameObject prefab, Vector3 position, Quaternion rotation)
    {
        ObjectCache cache = null;

        if (Instance)
        {
            //获取符合当前prefab缓存
            foreach (ObjectCache t in Instance.Caches)
            {
                if (t.Prefab == prefab)
                {
                    cache = t;
                    break;
                }
            }
        }

        if (cache == null)
        {
            return Instantiate(prefab, position, rotation) as GameObject;
        }

        //获取当前缓存容器 可用实例
        GameObject obj = cache.GetNextObjectCache();

        //设置实例属性

        obj.transform.position = position;
        obj.transform.rotation = rotation;

        obj.SetActive(true);
        //存入哈希表
        Instance._cacheObjects[obj] = true;

        return obj;
    }

    //销毁处理
    public static void Destroy(GameObject obj)
    {

        if (Instance && Instance._cacheObjects.ContainsKey(obj))
        {
            obj.SetActive(false);
            Instance._cacheObjects[obj] = false;
        }
        else
        {
            Destroy(obj);
        }
    }

4. 在子弹prefab创建一个脚本

   

public class DbBullet : MonoBehaviour
{

    /// <summary>
    /// 速度
    /// </summary>
    public float Speed = 10f;

    /// <summary>
    /// 子弹生命时间
    /// </summary>
    public float Life = 0.5f;

    /// <summary>
    /// 距离
    /// </summary>
    public float Dist = 1000;



    private float _spawnTime = 0f;
    private Transform _tr;

    void OnEnable()
    {
        _tr = transform;
        _spawnTime = Time.deltaTime;
    }

    // Update is called once per frame
    void Update()
    {
        _tr.position += transform.forward * Speed * Time.deltaTime;
        Dist -= Speed * Time.deltaTime;

        if (Time.deltaTime > _spawnTime + Life || Dist < 0)
        {
            DbSpawn.Destroy(gameObject);
            Dist = 10;
        }
    }

5. 模拟发射了.

   

public class DbShooter : MonoBehaviour
{


    public Transform point;
    public GameObject prefab;
    public float TimeCount = 10f;

    private float _timer = 0f;
    private bool _isShooter = false;
    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            _isShooter = true;
        }

        if (Input.GetMouseButtonUp(0))
        {

            _isShooter = false;
        }


        if (_isShooter)
        {
            _timer += Time.deltaTime;
            if (_timer > 1 / TimeCount)
            {
                DbSpawn.SpawnObject(prefab, point.position, Quaternion.identity);
                _timer = 0f;
            }
        }
    }
}

-  - 我也是初学者,小白,分享一下,同时自己也加深印象3Q..

  

posted @ 2015-05-30 12:53  db丶  阅读(804)  评论(0编辑  收藏  举报