using System; using UnityEngine; using System.Collections.Generic; public class BattlePrepareManager : Singleton { public delegate void EffectReadyCallback (int id); Dictionary mEffectDataCache = new Dictionary (); Dictionary mBulletDataCache = new Dictionary (); Dictionary mBuffDataCache = new Dictionary (); Dictionary> mPrecacheAssets = new Dictionary>(); List mPrecacheParterModels = new List(); List mPrecacheHeroModels = new List(); List mPrecacheMonsterModels = new List(); List mPrecachePetModels = new List(); List mPrecacheCtrls = new List(); List mPrecacheUIPrefabs = new List(); private bool mIsLoading = false; public bool IsLoading { get { return mIsLoading; } } int loadtaskCnt = 0; float loadingProgress = 0.4f; float loadingDelta = 0; public int CacheEffectCnt { get { return mEffectDataCache.Count; } } public override void Init() { base.Init(); } public override void UnInit() { base.UnInit(); } public void PrecacheEffect(int id) { if (mEffectDataCache.ContainsKey(id)) return; EffectData data = new EffectData(id); mEffectDataCache.Add(id, data); PrecacheAssets(Constants.EffectPath, data.effect); } public void PrecacheEffects (int[] ids) { for (int idx =0; idx < ids.Length;idx++) { var id = ids[idx]; if (mEffectDataCache.ContainsKey (id)) continue; EffectData data = new EffectData (id); mEffectDataCache.Add (id, data); } PrecacheEffectAssets (ids); } public EffectData PopEffectData(int id, bool autoPrecache = true) { if (!mEffectDataCache.ContainsKey(id)) { if (autoPrecache) { PrecacheEffects(new[] { id }); return mEffectDataCache[id]; } else return new EffectData(id); } else return mEffectDataCache[id]; } void DisablePreLoad() { mPrecacheAssets.Clear(); } public void StartLoad() { DisablePreLoad(); foreach (var p in mPrecacheAssets) { if(p.Value.Count > 0) { loadtaskCnt++; Debug.Log("[StartLoad] " + p.Key + " : " + string.Join(",", p.Value.ToArray())); ResourceMgr.Instance.LoadAsset>(OnLoadAssetsCompleted, p.Key, p.Value.ToArray()); } } mPrecacheAssets.Clear(); if (mPrecacheCtrls.Count > 0) { loadtaskCnt++; Debug.Log("[StartLoad] " + Constants.AnimatorPath + " : " + string.Join(",", mPrecacheCtrls.ToArray())); ResourceMgr.Instance.LoadAsset>(OnLoadAssetsCompleted, Constants.AnimatorPath, mPrecacheCtrls.ToArray()); mPrecacheCtrls.Clear(); } if(mPrecacheUIPrefabs.Count > 0) { loadtaskCnt++; Debug.Log("[StartLoad] " + Constants.UIPath + " : " + string.Join(",", mPrecacheUIPrefabs.ToArray())); ResourceMgr.Instance.LoadAsset>(OnLoadAssetsCompleted, Constants.UIPath, mPrecacheUIPrefabs.ToArray()); mPrecacheUIPrefabs.Clear(); } if (mPrecacheHeroModels.Count > 0) { loadtaskCnt++; Debug.Log("[StartLoad] " + Constants.ModelPath + " : " + string.Join(",", mPrecacheHeroModels.ToArray())); ResourceMgr.Instance.LoadAsset>(OnLoadAssetsCompleted, Constants.ModelPath, mPrecacheHeroModels.ToArray()); mPrecacheHeroModels.Clear(); } if(mPrecacheMonsterModels.Count > 0) { loadtaskCnt++; Debug.Log("[StartLoad] " + Constants.ModelPath + " : " + string.Join(",", mPrecacheMonsterModels.ToArray())); ResourceMgr.Instance.LoadAsset>(OnLoadAssetsCompleted, Constants.ModelPath, mPrecacheMonsterModels.ToArray()); mPrecacheMonsterModels.Clear(); } if(mPrecacheParterModels.Count > 0) { loadtaskCnt++; Debug.Log("[StartLoad] " + Constants.ModelPath + " : " + string.Join(",", mPrecacheParterModels.ToArray())); ResourceMgr.Instance.LoadAsset>(OnLoadAssetsCompleted, Constants.ModelPath, mPrecacheParterModels.ToArray()); mPrecacheParterModels.Clear(); } if(mPrecachePetModels.Count > 0) { loadtaskCnt++; Debug.Log("[StartLoad] " + Constants.ModelPath + " : " + string.Join(",", mPrecachePetModels.ToArray())); ResourceMgr.Instance.LoadAsset>(OnLoadAssetsCompleted, Constants.ModelPath, mPrecachePetModels.ToArray()); mPrecachePetModels.Clear(); } mIsLoading = loadtaskCnt > 0; loadingProgress = 0.4f; if (mIsLoading) loadingDelta = 0.5f / loadtaskCnt; if(!mIsLoading) { EventMgr.DispatchEvent(new CoreEvent(ECoreEventType.EID_PREPARE_LOAD_OK, true)); } } public void PrecacheBuffs(int[] ids, int gender, ProfessionType jobType, int jobStage, int jobBranch) { if (ids == null) return; for(int idx =0; idx < ids.Length;idx++) { if (mBuffDataCache.ContainsKey(ids[idx])) continue; PrecacheBuff(ids[idx],gender,jobType,jobStage,jobBranch); } } public BuffData PrecacheBuff(int id,int gender, ProfessionType jobType, int jobStage, int jobBranch) { if (mBuffDataCache.ContainsKey(id)) return mBuffDataCache[id]; BuffData data = new BuffData(id, gender,jobType,jobStage,jobBranch); mBuffDataCache.Add(id, data); List buffs = PrecacheBuffAssets(id); if(buffs != null && buffs.Count > 0) { for (int idx = 0; idx < buffs.Count; idx++) { PrecacheBuff(buffs[idx], (int)(Role_Gender.Male), jobType, jobStage, jobBranch); } } if (data.extendBuffs!=null) { for(int idx =0; idx < data.extendBuffs.Count;idx++) { PrecacheBuff(data.extendBuffs[idx].id, (int)(Role_Gender.Male),jobType,jobStage,jobBranch); } } if(data.markExtendList != null) { for (int idx = 0; idx < data.markExtendList.Count; idx++) { PrecacheBuff(data.markExtendList[idx].val, (int)(Role_Gender.Male), jobType, jobStage, jobBranch); } } return data; } public BulletData PopBulletData(int id, bool autoPrecache = true) { if (!mBulletDataCache.ContainsKey(id)) { if (autoPrecache) { PrecacheBullets(new[] { id }, BattleMgr.Instance != null); return mBulletDataCache[id]; } else return new BulletData(id); } else return mBulletDataCache[id]; } public BuffData PopBuffData(int id, bool autoPrecache = true) { if (mBuffDataCache.ContainsKey(id)) { return mBuffDataCache[id]; } return null; } public void PrecacheBullets(int[] ids, bool cacheAssets = true) { foreach (var id in ids) { if (mBulletDataCache.ContainsKey(id)) continue; BulletData data = new BulletData(id); mBulletDataCache.Add(id, data); } if (cacheAssets) PrecacheBulletAssets(ids); } public void PrecacheModel(string prefabName, ActorType actorType) { if (ResourceMgr.Instance.HasAsset(Constants.ModelPath, prefabName)) return; if (actorType == ActorType.Hero) { if (!mPrecacheHeroModels.Contains(prefabName)) { mPrecacheHeroModels.Add(prefabName); } } else if(actorType == ActorType.Fellow) { if(!mPrecacheParterModels.Contains(prefabName)) { mPrecacheParterModels.Add(prefabName); } } else if(actorType == ActorType.Monster) { if(!mPrecacheMonsterModels.Contains(prefabName)) { mPrecacheMonsterModels.Add(prefabName); } } else if(actorType == ActorType.Pet) { if(!mPrecachePetModels.Contains(prefabName)) { mPrecachePetModels.Add(prefabName); } } } public void PrecacheAnimatorCtrl(string ctrlName) { if (string.IsNullOrEmpty(ctrlName)) return; if (mPrecacheCtrls.Contains(ctrlName)) return; if (ResourceMgr.Instance.HasAsset(Constants.AnimatorPath, ctrlName)) return; mPrecacheCtrls.Add(ctrlName); } public void PrecacheUIPrefabs(string[] prefabNames) { if (prefabNames == null || prefabNames.Length == 0) return; for(int idx =0; idx < prefabNames.Length;idx++) { PrecacheUIPrefab(prefabNames[idx]); } } public void PrecacheUIPrefab(string prefabName) { if (string.IsNullOrEmpty(prefabName)) return; if (mPrecacheUIPrefabs.Contains(prefabName)) return; if (ResourceMgr.Instance.HasAsset(Constants.UIPath, prefabName)) return; mPrecacheUIPrefabs.Add(prefabName); } public void LoadMonsterPrefabGo (string assetPath,string prefabName, ResourceLoadCallback cb) { ResourceMgr.Instance.LoadAsset(cb,assetPath , prefabName); } public void PrecacheAnimPrefabGo (string prefabName, ResourceLoadCallback callback) { ResourceMgr.Instance.LoadAsset(callback, Constants.AnimPath, prefabName); } public GameObject PopAssetGo(string path,string assetName) { return ResourceMgr.Instance.GetGoFromPool(path,assetName); } public void PopAssetGoAsync(string path,string assetName, Action cb) { ResourceMgr.Instance.GetGoFromPoolAsync(path,assetName, (o) => { cb(o); }); } public GameObject GetMonsterPrefabGo (string prefabName) { return ResourceMgr.Instance.GetGoFromPool(Constants.ModelPath, prefabName); } public void GetMonsterPrefabGoAsync(string prefabName, Action cb) { ResourceMgr.Instance.GetGoFromPoolAsync(Constants.ModelPath, prefabName, (o) => { cb(o); }); } public GameObject GetAnimPrefabGo (string prefabName) { return ResourceMgr.Instance.GetGoFromPool(Constants.AnimPath, prefabName); } public void GetAnimPrefabGoAsync(string prefabName, Action cb) { ResourceMgr.Instance.GetGoFromPoolAsync(Constants.AnimPath, prefabName, (o) => { cb(o); }); } //清理数据 public void Clear () { mEffectDataCache.Clear (); mBulletDataCache.Clear (); mBuffDataCache.Clear (); mPrecacheAssets.Clear(); mPrecacheHeroModels.Clear(); mPrecacheMonsterModels.Clear(); mPrecacheParterModels.Clear(); mPrecachePetModels.Clear(); mIsLoading = false; loadtaskCnt = 0; } private void PrecacheEffectAssets(int[] ids) { List assets = new List(); for (int i = 0; i < ids.Length; i++) { EffectData data = mEffectDataCache[ids[i]]; if (!string.IsNullOrEmpty(data.effect)) assets.Add(data.effect); } if (assets.Count > 0) PrecacheAssets(Constants.EffectPath, assets.ToArray()); } private void PrecacheAssets(string packageName, params string[] assetNames) { List assets = null; if (!mPrecacheAssets.TryGetValue(packageName, out assets)) { assets = new List(); mPrecacheAssets.Add(packageName, assets); } for (int idx = 0; idx < assetNames.Length; idx++) { if (!assets.Contains(assetNames[idx]) && !ResourceMgr.Instance.HasAsset(packageName, assetNames[idx])) { assets.Add(assetNames[idx]); } } } private void PrecacheBulletAssets(int[] ids) { List assets = new List(); List sounds = new List(); List effects = new List(); for (int i = 0; i < ids.Length; i++) { BulletData data = mBulletDataCache[ids[i]]; if (!string.IsNullOrEmpty(data.effect)) assets.Add(data.effect); if (!string.IsNullOrEmpty(data.sound)) sounds.Add(data.sound); } if (sounds.Count > 0) MusicMgr.Instance.PreloadFightSound(sounds.ToArray()); if (assets.Count > 0) PrecacheAssets(Constants.EffectPath, assets.ToArray()); if (effects.Count > 0) PrecacheEffects(effects.ToArray()); } List PrecacheBuffAssets(int id) { BuffData buffData = mBuffDataCache[id]; if (buffData.ActionFrameEvents == null || buffData.ActionFrameEvents.Length == 0) return null; List sounds = new List(); List effects = new List(); List bulletActors = new List(); List buffs = new List(); for (int idx = 0; idx < buffData.ActionFrameEvents.Length; idx++) { SkillActionFrameEvent ev = buffData.ActionFrameEvents[idx]; switch (ev.eventType) { case SkillActionFrameEventType.FE_PlaySound: { string sound = ev.GetStr(Constants.s_skillaction_frame_key_sound); if(!string.IsNullOrEmpty(sound) && !sounds.Contains(sound)) { sounds.Add(sound); } break; } case SkillActionFrameEventType.FE_PlayEffect: case SkillActionFrameEventType.FE_PlayUnscaleTimeEffect: { int v = ev.GetN(Constants.s_skillaction_frame_key_effect); if (v > 0 && !effects.Contains(v)) effects.Add(v); break; } case SkillActionFrameEventType.FE_PlayEffectEx: { int v = (int)ev.GetN(Constants.s_skillaction_frame_key_effect); if (v > 0 && !effects.Contains(v)) effects.Add(v); break; } case SkillActionFrameEventType.FE_Hit: case SkillActionFrameEventType.FE_Skill_Sing: case SkillActionFrameEventType.FE_Repeat_Caster: case SkillActionFrameEventType.FE_Delay_Hurt: case SkillActionFrameEventType.FE_Bullet: { SkillActionAttackInfo attackInfo = ev.CreateAttackInfo(); if (attackInfo != null) { if (attackInfo.bulletID > 0 && !bulletActors.Contains(attackInfo.bulletID)) { bulletActors.Add(attackInfo.bulletID); } if (attackInfo.hitEffect > 0 && !effects.Contains(attackInfo.hitEffect)) { effects.Add(attackInfo.hitEffect); } if(attackInfo.effect > 0 && !effects.Contains(attackInfo.effect)) { effects.Add(attackInfo.effect); } if (!string.IsNullOrEmpty(attackInfo.sound) && !sounds.Contains(attackInfo.sound)) { sounds.Add(attackInfo.sound); } } break; } case SkillActionFrameEventType.FE_Clone: { int npcPos = ev.GetN(Constants.s_skillaction_frame_key_npcPos); int npcId = ev.GetN(Constants.s_skillaction_frame_key_npcId); int bornEffectId = ev.GetN(Constants.s_skillaction_frame_key_effect); if (bornEffectId > 0 && !effects.Contains(bornEffectId)) { effects.Add(bornEffectId); } buffData.cloneBossId = npcId; } break; case SkillActionFrameEventType.FE_Buff: { int buffId = ev.GetN(Constants.s_skillaction_frame_key_buffid); if (buffId > 0 && !buffs.Contains(buffId)) buffs.Add(buffId); } break; default: break; } } for (int idx = 0; idx < buffData.BuffFunList.Count; idx++) { var data = buffData.BuffFunList[idx]; if (data.effectId > 0 && !effects.Contains(data.effectId)) { effects.Add(data.effectId); } if (data.endeffectId > 0 && !effects.Contains(data.endeffectId)) { effects.Add(data.endeffectId); } } //添加的印记特效 if(buffData.markData!=null && buffData.markData.markId > 0 && buffData.markData.markVal > 0) { MarkData markData = new MarkData(buffData.markData.markId); if(markData.Valid && markData.effectId > 0) { effects.Add(markData.effectId); } } if(effects.Count > 0) BattlePrepareManager.Instance.PrecacheEffects(effects.ToArray()); if(bulletActors.Count > 0) BattlePrepareManager.Instance.PrecacheBullets(bulletActors.ToArray()); if(sounds.Count > 0) MusicMgr.Instance.PreloadFightSound(sounds.ToArray()); return buffs; } void OnLoadAssetsCompleted(List goes, string packageName, params string[] assetNames) { for (int idx = 0; idx < assetNames.Length; idx++) { ResourceMgr.Instance.GetGoFromPoolAsync(packageName, assetNames[idx], (o) => { GameObject instGo = o; if (instGo != null) ResourceMgr.Instance.RecycleGO(packageName, assetNames[idx], instGo); }); } Debug.Log($"[OnLoadAssetsCompleted] {packageName} : {string.Join(',', assetNames)}"); CheckLoadStatus(); } void OnLoadAssetsCompleted(List ctrls,string packageName,params string[] assetNames) { CheckLoadStatus(); } void CheckLoadStatus() { loadtaskCnt--; mIsLoading = loadtaskCnt > 0; loadingProgress += loadingDelta; EventMgr.DispatchEvent(new CoreEvent(ECoreEventType.EID_LOAD_PROGRESS, loadingProgress)); if (!mIsLoading) EventMgr.DispatchEvent(new CoreEvent(ECoreEventType.EID_PREPARE_LOAD_OK, true)); } }