少年修仙传客户端代码仓库
client_Wu Xijin
2018-10-27 45c82c513c67130bb52cb5e7f2f10c957e463cf1
Core/ResModule/GameObjectPoolManager.cs
@@ -1,643 +1,645 @@
using System.Collections.Generic;
using UnityEngine;
using System;
using TableConfig;
public class GameObjectPoolManager : SingletonMonobehaviour<GameObjectPoolManager>
{
#if UNITY_EDITOR
    private Dictionary<int, DebugItem> m_DebugInstIDDict = null;
#endif
    private Dictionary<int, GameObjectPool> m_PoolDict = null;
    // 不需要销毁的对象列表
    private List<int> dontDestoryGoInstIDList = null;
    private Transform m_TargetContainer;
    public void Initialize()
    {
        if (m_PoolDict == null)
        {
            m_PoolDict = new Dictionary<int, GameObjectPool>();
        }
        if (!m_TargetContainer)
        {
            m_TargetContainer = new GameObject("Container").transform;
            m_TargetContainer.SetParent(transform);
        }
        if (dontDestoryGoInstIDList == null)
        {
            dontDestoryGoInstIDList = new List<int>();
        }
#if UNITY_EDITOR
        if (m_DebugInstIDDict == null)
        {
            m_DebugInstIDDict = new Dictionary<int, DebugItem>();
        }
#endif
    }
    public void AddDontDestroyGoInstID(int id)
    {
        if (!dontDestoryGoInstIDList.Contains(id))
        {
            dontDestoryGoInstIDList.Add(id);
        }
    }
    public bool ExistPool(GameObject prefab)
    {
        if (prefab == null)
        {
            return false;
        }
        if (m_PoolDict.ContainsKey(prefab.GetInstanceID()))
        {
            return true;
        }
        return false;
    }
    public GameObjectPool RequestPool(GameObject prefab)
    {
        if (prefab == null)
        {
            return null;
        }
        int _prefabInstanceId = prefab.GetInstanceID();
        GameObjectPool _pool = null;
        if (m_PoolDict.TryGetValue(_prefabInstanceId, out _pool))
        {
            return _pool;
        }
        _pool = new GameObjectPool(prefab);
        m_PoolDict[_prefabInstanceId] = _pool;
        return _pool;
    }
    public void CacheGameObject(GameObject prefab, int count, bool _prefabActive)
    {
        if (prefab == null)
        {
            return;
        }
        RequestPool(prefab).Cache(count, _prefabActive);
    }
    public void CacheNpc(int npcID, int count, bool prefabActive)
    {
        string _assetName;
        string _assetBundleName;
        NPCConfig _m = ConfigManager.Instance.GetTemplate<NPCConfig>(npcID);
        if (_m == null || _m.MODE.Equals("0"))
        {
            return;
        }
        if (GAMgr.Instance.s_NpcID2Assetname.TryGetValue(npcID, out _assetName))
        {
            _assetBundleName = GAMgr.Instance.s_NpcID2BundleName[npcID];
        }
        else
        {
            _assetName = StringUtility.Contact(InstanceResourcesLoader.raceSuffix, _m.MODE);
            _assetBundleName = StringUtility.Contact(ResourcesPath.MOB_FOLDER_NAME, _assetName);
            GAMgr.Instance.s_NpcID2Assetname[npcID] = _assetName;
            GAMgr.Instance.s_NpcID2BundleName[npcID] = _assetBundleName;
        }
        GameObject _prefab = InstanceResourcesLoader.LoadMob(_assetBundleName, _assetName);
        if (!_prefab)
        {
            return;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        _pool.assetBundleName = _assetBundleName;
        _pool.assetName = _assetName;
        _pool.Cache(count, prefabActive);
    }
    public GameObject RequestGameObject(GameObject prefab)
    {
        if (prefab == null)
        {
            return null;
        }
        return RequestPool(prefab).Request();
    }
    public GameObject RequestDefaultPet()
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralConfig.Instance.ModeDefaultConfig[2][0],
                                                             GeneralConfig.Instance.ModeDefaultConfig[2][1]);
        if (!_prefab)
        {
            return null;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        _pool.assetName = GeneralConfig.Instance.ModeDefaultConfig[2][1];
        _pool.assetBundleName = GeneralConfig.Instance.ModeDefaultConfig[2][0];
        return _pool.Request();
    }
    public GameObject RequestDefaultFightNpc()
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralConfig.Instance.ModeDefaultConfig[1][0],
                                                             GeneralConfig.Instance.ModeDefaultConfig[1][1]);
        if (!_prefab)
        {
            return null;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        _pool.assetName = GeneralConfig.Instance.ModeDefaultConfig[1][1];
        _pool.assetBundleName = GeneralConfig.Instance.ModeDefaultConfig[1][0];
        return _pool.Request();
    }
    public GameObject RequestDefaultFuncNpc()
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralConfig.Instance.ModeDefaultConfig[0][0],
                                                             GeneralConfig.Instance.ModeDefaultConfig[0][1]);
        if (!_prefab)
        {
            return null;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        _pool.assetName = GeneralConfig.Instance.ModeDefaultConfig[0][1];
        _pool.assetBundleName = GeneralConfig.Instance.ModeDefaultConfig[0][0];
        return _pool.Request();
    }
    public void ReleaseDefaultPet(GameObject go)
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralConfig.Instance.ModeDefaultConfig[2][0],
                                                             GeneralConfig.Instance.ModeDefaultConfig[2][1]);
        if (!_prefab)
        {
            return;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        if (_pool != null)
        {
            _pool.Release(go);
        }
    }
    public void ReleaseDefaultHorse(GameObject go)
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralConfig.Instance.ModeDefaultConfig[3][0],
                                                             GeneralConfig.Instance.ModeDefaultConfig[3][1]);
        if (!_prefab)
        {
            return;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        if (_pool != null)
        {
            _pool.Release(go);
        }
    }
    public void ReleaseDefaultFightNPC(GameObject go)
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralConfig.Instance.ModeDefaultConfig[1][0],
                                                             GeneralConfig.Instance.ModeDefaultConfig[1][1]);
        if (!_prefab)
        {
            return;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        if (_pool != null)
        {
            _pool.Release(go);
        }
    }
    public void ReleaseDefaultFuncNPC(GameObject go)
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralConfig.Instance.ModeDefaultConfig[0][0],
                                                             GeneralConfig.Instance.ModeDefaultConfig[0][1]);
        if (!_prefab)
        {
            return;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        if (_pool != null)
        {
            _pool.Release(go);
        }
    }
    public GameObject RequestNpcGameObject(int npcID)
    {
        string _assetName;
        string _assetBundleName;
        NPCConfig _m = ConfigManager.Instance.GetTemplate<NPCConfig>(npcID);
        if (_m == null || _m.MODE.Equals("0"))
        {
            return null;
        }
        if (GAMgr.Instance.s_NpcID2Assetname.TryGetValue(npcID, out _assetName))
        {
            _assetBundleName = GAMgr.Instance.s_NpcID2BundleName[npcID];
        }
        else
        {
            _assetName = StringUtility.Contact(InstanceResourcesLoader.raceSuffix, _m.MODE);
            _assetBundleName = StringUtility.Contact(ResourcesPath.MOB_FOLDER_NAME, _assetName);
            GAMgr.Instance.s_NpcID2Assetname[npcID] = _assetName;
            GAMgr.Instance.s_NpcID2BundleName[npcID] = _assetBundleName;
        }
        GameObject _prefab = InstanceResourcesLoader.LoadMob(_assetBundleName, _assetName);
        if (!_prefab)
        {
            return null;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        _pool.assetBundleName = _assetBundleName;
        _pool.assetName = _assetName;
        return _pool.Request();
    }
    public void ReleaseGameObject(GameObject prefab, GameObject go)
    {
        GameObjectPool _pool = RequestPool(prefab);
        if (_pool == null)
        {
            return;
        }
        _pool.Release(go);
    }
    public void Release(GameObject prefab)
    {
        int _prefabInstanceId = prefab.GetInstanceID();
        GameObjectPool _pool = null;
        if (m_PoolDict.TryGetValue(_prefabInstanceId, out _pool))
        {
            _pool.Clear();
            if (_pool.IsEmpty())
            {
                m_PoolDict.Remove(_pool.PrefabInstanceId);
            }
        }
    }
    public void UnLoadNPC(int npcID)
    {
        if (!AssetSource.mobFromEditor)
        {
            string _assetName;
            string _assetBundleName;
            if (!GAMgr.Instance.s_NpcID2Assetname.TryGetValue(npcID, out _assetName))
            {
                return;
            }
            _assetBundleName = GAMgr.Instance.s_NpcID2BundleName[npcID];
            if (!AssetBundleUtility.Instance.JudgeExistAssetBundle(_assetBundleName))
            {
                return;
            }
            GameObject _prefab = InstanceResourcesLoader.LoadMob(_assetBundleName, _assetName);
            if (!_prefab)
            {
                return;
            }
            if (!ExistPool(_prefab))
            {
                return;
            }
            GameObjectPool _pool = RequestPool(_prefab);
            _pool.Clear();
            m_PoolDict.Remove(_pool.PrefabInstanceId);
        }
    }
    public void UnLoadAll(bool force = false)
    {
        List<int> _removeList = new List<int>();
        foreach (var _pool in m_PoolDict.Values)
        {
            if (GAMgr.Instance.needDestroyPrefabList.Contains(_pool.Prefab))
            {
                _pool.Clear();
                _removeList.Add(_pool.PrefabInstanceId);
            }
        }
        for (int i = 0; i < _removeList.Count; ++i)
        {
            m_PoolDict.Remove(_removeList[i]);
        }
    }
    public class GameObjectPool
    {
        private GameObject m_Prefab = null;
        public GameObject Prefab
        {
            get
            {
                return m_Prefab;
            }
        }
        public int PrefabInstanceId
        {
            get; private set;
        }
        public List<GameObject> m_ActiveList = null;
        private List<GameObject> m_FreeList = null;
        Action<GameObject> releaseCallBack;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
        private Transform m_DebugContainer;
        private Transform m_DebugActive;
        private Transform m_DebugFree;
#endif
        public string assetBundleName;
        public string assetName;
        internal protected GameObjectPool(GameObject prefab)
        {
            m_Prefab = prefab;
            PrefabInstanceId = m_Prefab.GetInstanceID();
            m_ActiveList = new List<GameObject>();
            m_FreeList = new List<GameObject>();
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            m_DebugContainer = new GameObject(prefab.name).transform;
            m_DebugActive = new GameObject("Active").transform;
            m_DebugFree = new GameObject("Free").transform;
            m_DebugActive.SetParent(m_DebugContainer);
            m_DebugFree.SetParent(m_DebugContainer);
            m_DebugContainer.SetParent(Instance.transform);
#endif
        }
        public void AddReleaseListener(Action<GameObject> _callBack)
        {
            releaseCallBack = _callBack;
        }
        public void RemoveReleaseListener()
        {
            releaseCallBack = null;
        }
        public void Cache(int count, bool _prefabActive)
        {
            GameObject _go;
            for (int i = 0; i < count; ++i)
            {
                _go = Instantiate(m_Prefab, Constants.Special_Hide_Position, Quaternion.identity);
                m_FreeList.Add(_go);
                _go.transform.SetParent(Instance.m_TargetContainer);
                _go.transform.position = Constants.Special_Hide_Position;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                DebugItem _debugItem = new GameObject(_go.GetInstanceID().ToString()).AddMissingComponent<DebugItem>();
                _debugItem.transform.SetParent(m_DebugFree);
                _debugItem.target = _go;
                Instance.m_DebugInstIDDict[_go.GetInstanceID()] = _debugItem;
#endif
                var animator = _go.GetComponent<Animator>();
                if (animator != null)
                {
                    animator.enabled = false;
                }
                _go.SetActive(_prefabActive);
            }
        }
        public GameObject Request()
        {
            GameObject _go = null;
            while (m_FreeList.Count > 0)
            {
                if (m_FreeList[0] != null)
                {
                    _go = m_FreeList[0];
                    m_ActiveList.Add(_go);
                    m_FreeList.RemoveAt(0);
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                    if (Instance.m_DebugInstIDDict.ContainsKey(_go.GetInstanceID()))
                    {
                        DebugItem _debugItem = Instance.m_DebugInstIDDict[_go.GetInstanceID()];
                        _debugItem.transform.SetParent(m_DebugActive);
                    }
#endif
                    break;
                }
                else
                {
                    m_FreeList.RemoveAt(0);
                }
            }
            if (_go == null)
            {
                _go = Instantiate(m_Prefab, Constants.Special_Hide_Position, Quaternion.identity);
                m_ActiveList.Add(_go);
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                DebugItem _debugItem = new GameObject(_go.GetInstanceID().ToString()).AddMissingComponent<DebugItem>();
                _debugItem.transform.SetParent(m_DebugActive);
                _debugItem.target = _go;
                Instance.m_DebugInstIDDict[_go.GetInstanceID()] = _debugItem;
#endif
            }
            _go.transform.SetParent(null);
            _go.transform.localScale = Vector3.one;
            return _go;
        }
        public void Release(GameObject go)
        {
            if (go == null)
            {
                return;
            }
            if (m_ActiveList.Contains(go))
            {
                m_ActiveList.Remove(go);
            }
            if (m_FreeList.Contains(go))
            {
                return;
            }
            m_FreeList.Add(go);
            go.transform.SetParent(Instance.m_TargetContainer);
            go.transform.position = Constants.Special_Hide_Position;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            if (Instance.m_DebugInstIDDict.ContainsKey(go.GetInstanceID()))
            {
                DebugItem _debugItem = Instance.m_DebugInstIDDict[go.GetInstanceID()];
                _debugItem.transform.SetParent(m_DebugFree);
            }
#endif
            if (releaseCallBack != null)
            {
                releaseCallBack(go);
            }
        }
        public void ReleaseAll()
        {
            for (int i = m_ActiveList.Count - 1; i >= 0; i--)
            {
                var _go = m_ActiveList[i];
                m_ActiveList.Remove(_go);
                if (!m_FreeList.Contains(_go))
                {
                    m_FreeList.Add(_go);
                }
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                DebugItem _debugItem = Instance.m_DebugInstIDDict[_go.GetInstanceID()];
                _debugItem.transform.SetParent(m_DebugFree);
#endif
                _go.transform.position = Constants.Special_Hide_Position;
                if (releaseCallBack != null)
                {
                    releaseCallBack(_go);
                }
            }
        }
        public void Clear()
        {
            for (int i = m_ActiveList.Count - 1; i >= 0; --i)
            {
                if (m_ActiveList[i] == null
                || Instance.dontDestoryGoInstIDList.Contains(m_ActiveList[i].GetInstanceID()))
                    continue;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                Destroy(Instance.m_DebugInstIDDict[m_ActiveList[i].GetInstanceID()].gameObject);
#endif
                Destroy(m_ActiveList[i]);
                m_ActiveList.RemoveAt(i);
            }
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            if (m_ActiveList.Count != 0)
            {
                Debug.LogWarningFormat("{0} 池清理后, 还有 {1} 个活跃对象. ", m_Prefab.name, m_ActiveList.Count);
                for (int i = 0; i < m_ActiveList.Count; ++i)
                {
                    Debug.LogWarningFormat(" |-- {0}", m_ActiveList[i].name);
                }
            }
#endif
            for (int i = m_FreeList.Count - 1; i >= 0; --i)
            {
                if (m_FreeList[i] == null
                 || Instance.dontDestoryGoInstIDList.Contains(m_FreeList[i].GetInstanceID()))
                    continue;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                Destroy(Instance.m_DebugInstIDDict[m_FreeList[i].GetInstanceID()].gameObject);
#endif
                Destroy(m_FreeList[i]);
                m_FreeList.RemoveAt(i);
            }
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            if (m_FreeList.Count != 0)
            {
                Debug.LogWarningFormat("{0} 池清理后, 还有 {1} 个空闲对象. ", m_Prefab.name, m_FreeList.Count);
                for (int i = 0; i < m_FreeList.Count; ++i)
                {
                    Debug.LogWarningFormat(" |-- {0}", m_FreeList[i].name);
                }
            }
#endif
            if (IsEmpty())
            {
                m_Prefab = null;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                Destroy(m_DebugContainer.gameObject);
#endif
            }
            if (!string.IsNullOrEmpty(assetBundleName) && !string.IsNullOrEmpty(assetName))
            {
                InstanceResourcesLoader.UnloadAsset(assetBundleName, assetName);
            }
        }
        public bool IsEmpty()
        {
            return m_ActiveList.Count == 0 && m_FreeList.Count == 0;
        }
    }
}
using System.Collections.Generic;
using UnityEngine;
using System;
using TableConfig;
[XLua.LuaCallCSharp]
public class GameObjectPoolManager : SingletonMonobehaviour<GameObjectPoolManager>
{
#if UNITY_EDITOR
    private Dictionary<int, DebugItem> m_DebugInstIDDict = null;
#endif
    private Dictionary<int, GameObjectPool> m_PoolDict = null;
    // 不需要销毁的对象列表
    private List<int> dontDestoryGoInstIDList = null;
    private Transform m_TargetContainer;
    public void Initialize()
    {
        if (m_PoolDict == null)
        {
            m_PoolDict = new Dictionary<int, GameObjectPool>();
        }
        if (!m_TargetContainer)
        {
            m_TargetContainer = new GameObject("Container").transform;
            m_TargetContainer.SetParent(transform);
        }
        if (dontDestoryGoInstIDList == null)
        {
            dontDestoryGoInstIDList = new List<int>();
        }
#if UNITY_EDITOR
        if (m_DebugInstIDDict == null)
        {
            m_DebugInstIDDict = new Dictionary<int, DebugItem>();
        }
#endif
    }
    public void AddDontDestroyGoInstID(int id)
    {
        if (!dontDestoryGoInstIDList.Contains(id))
        {
            dontDestoryGoInstIDList.Add(id);
        }
    }
    public bool ExistPool(GameObject prefab)
    {
        if (prefab == null)
        {
            return false;
        }
        if (m_PoolDict.ContainsKey(prefab.GetInstanceID()))
        {
            return true;
        }
        return false;
    }
    public GameObjectPool RequestPool(GameObject prefab)
    {
        if (prefab == null)
        {
            return null;
        }
        int _prefabInstanceId = prefab.GetInstanceID();
        GameObjectPool _pool = null;
        if (m_PoolDict.TryGetValue(_prefabInstanceId, out _pool))
        {
            return _pool;
        }
        _pool = new GameObjectPool(prefab);
        m_PoolDict[_prefabInstanceId] = _pool;
        return _pool;
    }
    public void CacheGameObject(GameObject prefab, int count, bool _prefabActive)
    {
        if (prefab == null)
        {
            return;
        }
        RequestPool(prefab).Cache(count, _prefabActive);
    }
    public void CacheNpc(int npcID, int count, bool prefabActive)
    {
        string _assetName;
        string _assetBundleName;
        NPCConfig _m = Config.Instance.Get<NPCConfig>(npcID);
        if (_m == null || _m.MODE.Equals("0"))
        {
            return;
        }
        if (GAMgr.Instance.s_NpcID2Assetname.TryGetValue(npcID, out _assetName))
        {
            _assetBundleName = GAMgr.Instance.s_NpcID2BundleName[npcID];
        }
        else
        {
            _assetName = StringUtility.Contact(InstanceResourcesLoader.raceSuffix, _m.MODE);
            _assetBundleName = StringUtility.Contact(ResourcesPath.MOB_FOLDER_NAME, _assetName);
            GAMgr.Instance.s_NpcID2Assetname[npcID] = _assetName;
            GAMgr.Instance.s_NpcID2BundleName[npcID] = _assetBundleName;
        }
        GameObject _prefab = InstanceResourcesLoader.LoadMob(_assetBundleName, _assetName);
        if (!_prefab)
        {
            return;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        _pool.assetBundleName = _assetBundleName;
        _pool.assetName = _assetName;
        _pool.Cache(count, prefabActive);
    }
    public GameObject RequestGameObject(GameObject prefab)
    {
        if (prefab == null)
        {
            return null;
        }
        return RequestPool(prefab).Request();
    }
    public GameObject RequestDefaultPet()
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralDefine.ModeDefaultConfig[2][0],
                                                             GeneralDefine.ModeDefaultConfig[2][1]);
        if (!_prefab)
        {
            return null;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        _pool.assetName = GeneralDefine.ModeDefaultConfig[2][1];
        _pool.assetBundleName = GeneralDefine.ModeDefaultConfig[2][0];
        return _pool.Request();
    }
    public GameObject RequestDefaultFightNpc()
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralDefine.ModeDefaultConfig[1][0],
                                                             GeneralDefine.ModeDefaultConfig[1][1]);
        if (!_prefab)
        {
            return null;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        _pool.assetName = GeneralDefine.ModeDefaultConfig[1][1];
        _pool.assetBundleName = GeneralDefine.ModeDefaultConfig[1][0];
        return _pool.Request();
    }
    public GameObject RequestDefaultFuncNpc()
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralDefine.ModeDefaultConfig[0][0],
                                                             GeneralDefine.ModeDefaultConfig[0][1]);
        if (!_prefab)
        {
            return null;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        _pool.assetName = GeneralDefine.ModeDefaultConfig[0][1];
        _pool.assetBundleName = GeneralDefine.ModeDefaultConfig[0][0];
        return _pool.Request();
    }
    public void ReleaseDefaultPet(GameObject go)
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralDefine.ModeDefaultConfig[2][0],
                                                             GeneralDefine.ModeDefaultConfig[2][1]);
        if (!_prefab)
        {
            return;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        if (_pool != null)
        {
            _pool.Release(go);
        }
    }
    public void ReleaseDefaultHorse(GameObject go)
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralDefine.ModeDefaultConfig[3][0],
                                                             GeneralDefine.ModeDefaultConfig[3][1]);
        if (!_prefab)
        {
            return;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        if (_pool != null)
        {
            _pool.Release(go);
        }
    }
    public void ReleaseDefaultFightNPC(GameObject go)
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralDefine.ModeDefaultConfig[1][0],
                                                             GeneralDefine.ModeDefaultConfig[1][1]);
        if (!_prefab)
        {
            return;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        if (_pool != null)
        {
            _pool.Release(go);
        }
    }
    public void ReleaseDefaultFuncNPC(GameObject go)
    {
        GameObject _prefab = InstanceResourcesLoader.LoadMob(GeneralDefine.ModeDefaultConfig[0][0],
                                                             GeneralDefine.ModeDefaultConfig[0][1]);
        if (!_prefab)
        {
            return;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        if (_pool != null)
        {
            _pool.Release(go);
        }
    }
    public GameObject RequestNpcGameObject(int npcID)
    {
        string _assetName;
        string _assetBundleName;
        NPCConfig _m = Config.Instance.Get<NPCConfig>(npcID);
        if (_m == null || _m.MODE.Equals("0"))
        {
            return null;
        }
        if (GAMgr.Instance.s_NpcID2Assetname.TryGetValue(npcID, out _assetName))
        {
            _assetBundleName = GAMgr.Instance.s_NpcID2BundleName[npcID];
        }
        else
        {
            _assetName = StringUtility.Contact(InstanceResourcesLoader.raceSuffix, _m.MODE);
            _assetBundleName = StringUtility.Contact(ResourcesPath.MOB_FOLDER_NAME, _assetName);
            GAMgr.Instance.s_NpcID2Assetname[npcID] = _assetName;
            GAMgr.Instance.s_NpcID2BundleName[npcID] = _assetBundleName;
        }
        GameObject _prefab = InstanceResourcesLoader.LoadMob(_assetBundleName, _assetName);
        if (!_prefab)
        {
            return null;
        }
        GameObjectPool _pool = RequestPool(_prefab);
        _pool.assetBundleName = _assetBundleName;
        _pool.assetName = _assetName;
        return _pool.Request();
    }
    public void ReleaseGameObject(GameObject prefab, GameObject go)
    {
        GameObjectPool _pool = RequestPool(prefab);
        if (_pool == null)
        {
            return;
        }
        _pool.Release(go);
    }
    public void Release(GameObject prefab)
    {
        int _prefabInstanceId = prefab.GetInstanceID();
        GameObjectPool _pool = null;
        if (m_PoolDict.TryGetValue(_prefabInstanceId, out _pool))
        {
            _pool.Clear();
            if (_pool.IsEmpty())
            {
                m_PoolDict.Remove(_pool.PrefabInstanceId);
            }
        }
    }
    public void UnLoadNPC(int npcID)
    {
        if (!AssetSource.mobFromEditor)
        {
            string _assetName;
            string _assetBundleName;
            if (!GAMgr.Instance.s_NpcID2Assetname.TryGetValue(npcID, out _assetName))
            {
                return;
            }
            _assetBundleName = GAMgr.Instance.s_NpcID2BundleName[npcID];
            if (!AssetBundleUtility.Instance.JudgeExistAssetBundle(_assetBundleName))
            {
                return;
            }
            GameObject _prefab = InstanceResourcesLoader.LoadMob(_assetBundleName, _assetName);
            if (!_prefab)
            {
                return;
            }
            if (!ExistPool(_prefab))
            {
                return;
            }
            GameObjectPool _pool = RequestPool(_prefab);
            _pool.Clear();
            m_PoolDict.Remove(_pool.PrefabInstanceId);
        }
    }
    public void UnLoadAll(bool force = false)
    {
        List<int> _removeList = new List<int>();
        foreach (var _pool in m_PoolDict.Values)
        {
            if (GAMgr.Instance.needDestroyPrefabList.Contains(_pool.Prefab))
            {
                _pool.Clear();
                _removeList.Add(_pool.PrefabInstanceId);
            }
        }
        for (int i = 0; i < _removeList.Count; ++i)
        {
            m_PoolDict.Remove(_removeList[i]);
        }
    }
    public class GameObjectPool
    {
        private GameObject m_Prefab = null;
        public GameObject Prefab
        {
            get
            {
                return m_Prefab;
            }
        }
        public int PrefabInstanceId
        {
            get; private set;
        }
        public List<GameObject> m_ActiveList = null;
        private List<GameObject> m_FreeList = null;
        Action<GameObject> releaseCallBack;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
        private Transform m_DebugContainer;
        private Transform m_DebugActive;
        private Transform m_DebugFree;
#endif
        public string assetBundleName;
        public string assetName;
        internal protected GameObjectPool(GameObject prefab)
        {
            m_Prefab = prefab;
            PrefabInstanceId = m_Prefab.GetInstanceID();
            m_ActiveList = new List<GameObject>();
            m_FreeList = new List<GameObject>();
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            m_DebugContainer = new GameObject(prefab.name).transform;
            m_DebugActive = new GameObject("Active").transform;
            m_DebugFree = new GameObject("Free").transform;
            m_DebugActive.SetParent(m_DebugContainer);
            m_DebugFree.SetParent(m_DebugContainer);
            m_DebugContainer.SetParent(Instance.transform);
#endif
        }
        public void AddReleaseListener(Action<GameObject> _callBack)
        {
            releaseCallBack = _callBack;
        }
        public void RemoveReleaseListener()
        {
            releaseCallBack = null;
        }
        public void Cache(int count, bool _prefabActive)
        {
            GameObject _go;
            for (int i = 0; i < count; ++i)
            {
                _go = Instantiate(m_Prefab, Constants.Special_Hide_Position, Quaternion.identity);
                m_FreeList.Add(_go);
                _go.transform.SetParent(Instance.m_TargetContainer);
                _go.transform.position = Constants.Special_Hide_Position;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                DebugItem _debugItem = new GameObject(_go.GetInstanceID().ToString()).AddMissingComponent<DebugItem>();
                _debugItem.transform.SetParent(m_DebugFree);
                _debugItem.target = _go;
                Instance.m_DebugInstIDDict[_go.GetInstanceID()] = _debugItem;
#endif
                var animator = _go.GetComponent<Animator>();
                if (animator != null)
                {
                    animator.enabled = false;
                }
                _go.SetActive(_prefabActive);
            }
        }
        public GameObject Request()
        {
            GameObject _go = null;
            while (m_FreeList.Count > 0)
            {
                if (m_FreeList[0] != null)
                {
                    _go = m_FreeList[0];
                    m_ActiveList.Add(_go);
                    m_FreeList.RemoveAt(0);
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                    if (Instance.m_DebugInstIDDict.ContainsKey(_go.GetInstanceID()))
                    {
                        DebugItem _debugItem = Instance.m_DebugInstIDDict[_go.GetInstanceID()];
                        _debugItem.transform.SetParent(m_DebugActive);
                    }
#endif
                    break;
                }
                else
                {
                    m_FreeList.RemoveAt(0);
                }
            }
            if (_go == null)
            {
                _go = Instantiate(m_Prefab, Constants.Special_Hide_Position, Quaternion.identity);
                m_ActiveList.Add(_go);
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                DebugItem _debugItem = new GameObject(_go.GetInstanceID().ToString()).AddMissingComponent<DebugItem>();
                _debugItem.transform.SetParent(m_DebugActive);
                _debugItem.target = _go;
                Instance.m_DebugInstIDDict[_go.GetInstanceID()] = _debugItem;
#endif
            }
            _go.transform.SetParent(null);
            _go.transform.localScale = Vector3.one;
            return _go;
        }
        public void Release(GameObject go)
        {
            if (go == null)
            {
                return;
            }
            if (m_ActiveList.Contains(go))
            {
                m_ActiveList.Remove(go);
            }
            if (m_FreeList.Contains(go))
            {
                return;
            }
            m_FreeList.Add(go);
            go.transform.SetParent(Instance.m_TargetContainer);
            go.transform.position = Constants.Special_Hide_Position;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            if (Instance.m_DebugInstIDDict.ContainsKey(go.GetInstanceID()))
            {
                DebugItem _debugItem = Instance.m_DebugInstIDDict[go.GetInstanceID()];
                _debugItem.transform.SetParent(m_DebugFree);
            }
#endif
            if (releaseCallBack != null)
            {
                releaseCallBack(go);
            }
        }
        public void ReleaseAll()
        {
            for (int i = m_ActiveList.Count - 1; i >= 0; i--)
            {
                var _go = m_ActiveList[i];
                m_ActiveList.Remove(_go);
                if (!m_FreeList.Contains(_go))
                {
                    m_FreeList.Add(_go);
                }
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                DebugItem _debugItem = Instance.m_DebugInstIDDict[_go.GetInstanceID()];
                _debugItem.transform.SetParent(m_DebugFree);
#endif
                _go.transform.SetParent(Instance.m_TargetContainer);
                _go.transform.position = Constants.Special_Hide_Position;
                if (releaseCallBack != null)
                {
                    releaseCallBack(_go);
                }
            }
        }
        public void Clear()
        {
            for (int i = m_ActiveList.Count - 1; i >= 0; --i)
            {
                if (m_ActiveList[i] == null
                || Instance.dontDestoryGoInstIDList.Contains(m_ActiveList[i].GetInstanceID()))
                    continue;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                Destroy(Instance.m_DebugInstIDDict[m_ActiveList[i].GetInstanceID()].gameObject);
#endif
                Destroy(m_ActiveList[i]);
                m_ActiveList.RemoveAt(i);
            }
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            if (m_ActiveList.Count != 0)
            {
                Debug.LogWarningFormat("{0} 池清理后, 还有 {1} 个活跃对象. ", m_Prefab.name, m_ActiveList.Count);
                for (int i = 0; i < m_ActiveList.Count; ++i)
                {
                    Debug.LogWarningFormat(" |-- {0}", m_ActiveList[i].name);
                }
            }
#endif
            for (int i = m_FreeList.Count - 1; i >= 0; --i)
            {
                if (m_FreeList[i] == null
                 || Instance.dontDestoryGoInstIDList.Contains(m_FreeList[i].GetInstanceID()))
                    continue;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                Destroy(Instance.m_DebugInstIDDict[m_FreeList[i].GetInstanceID()].gameObject);
#endif
                Destroy(m_FreeList[i]);
                m_FreeList.RemoveAt(i);
            }
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            if (m_FreeList.Count != 0)
            {
                Debug.LogWarningFormat("{0} 池清理后, 还有 {1} 个空闲对象. ", m_Prefab.name, m_FreeList.Count);
                for (int i = 0; i < m_FreeList.Count; ++i)
                {
                    Debug.LogWarningFormat(" |-- {0}", m_FreeList[i].name);
                }
            }
#endif
            if (IsEmpty())
            {
                m_Prefab = null;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                Destroy(m_DebugContainer.gameObject);
#endif
            }
            if (!string.IsNullOrEmpty(assetBundleName) && !string.IsNullOrEmpty(assetName))
            {
                InstanceResourcesLoader.UnloadAsset(assetBundleName, assetName);
            }
        }
        public bool IsEmpty()
        {
            return m_ActiveList.Count == 0 && m_FreeList.Count == 0;
        }
    }
}