using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; public class DynamicLoader : MonoBehaviour { public static DynamicLoader Instance; private void OnEnable() { Instance = this; } /// /// 已加载对象池 /// private List poolLoaded; /// /// 缓存对象池 /// private List poolCache; /// /// 待加载预设体名称列表 /// public List poolWillLoaded; /// /// 最大缓存数 /// public int cacheMaxNum { get; set; } /// /// 通过设置层实现显示对象 /// string showLayer = "Default"; /// /// 通过设置层实现隐藏对象 /// string hideLayer = "CacheLayer"; int showLayerIndex; int hideLayerIndex; public string LastPos; // Start is called before the first frame update void Start() { cacheMaxNum = 10; poolLoaded = new List< GameObject>(); poolCache = new List(); hideLayerIndex = LayerMask.NameToLayer(hideLayer); showLayerIndex = LayerMask.NameToLayer(showLayer); } /// /// 从缓存获取要加载的对象 /// /// 对象名 /// GameObject GetObjectFromCache(string objName) { return poolCache.FirstOrDefault(obj => obj.name == objName); } /// /// 从已加载列表获取要加载的对象 /// /// 对象名 /// GameObject GetObjectFromLoaded(string objName) { return poolLoaded.FirstOrDefault(obj => obj.name == objName); } /// /// 加载该位置所需要的预设体 /// /// 预设体名称数组 public void Load(string[] preNames) { // 添加缓存数组中已存在的预设体 List lstFromCache = poolCache.FindAll(obj => preNames.Contains(obj.name)); foreach (var obj in lstFromCache) { obj.layer = showLayerIndex; poolLoaded.Add(obj); poolCache.Remove(obj); } // 移除已加载数组中不需要的预设体 List lstFromLoaded = poolLoaded.FindAll(obj => !preNames.Contains(obj.name)); foreach (var obj in lstFromLoaded) { obj.layer = hideLayerIndex; poolCache.Add(obj); if (poolCache.Count > cacheMaxNum) { Destroy(poolCache[0]); poolCache.RemoveAt(0); } poolLoaded.Remove(obj); } // 加载不在场景中的预设体 GameObject tmp = null; foreach (var name in preNames) { tmp = poolLoaded.FirstOrDefault(obj => obj.name == name); if (tmp == null) { StartCoroutine(GeneratePrefab(name)); } } } IEnumerator GeneratePrefab(string name) { string parentName = name.Substring(0, name.IndexOf("_")); // 父对象名称 GameObject tmp = Resources.Load("Prefabs\\" + name); tmp = GameObject.Instantiate(tmp, GameObject.Find(parentName).transform); tmp.name = name; tmp.layer = showLayerIndex; poolLoaded.Add(tmp); // DataLoader.Instance.AttachOperation(); yield return new WaitForSeconds(0.5f); } }