|
@@ -0,0 +1,237 @@
|
|
|
|
+using CommonAI.Zone;
|
|
|
|
+using CommonLang;
|
|
|
|
+using Sirenix.Utilities;
|
|
|
|
+using System.Collections.Generic;
|
|
|
|
+using UnityEngine;
|
|
|
|
+
|
|
|
|
+namespace ET.Client
|
|
|
|
+{
|
|
|
|
+ [FriendOf(typeof(GameObjectPool))]
|
|
|
|
+ public static class GameObjectPoolSystem
|
|
|
|
+ {
|
|
|
|
+ [ObjectSystem]
|
|
|
|
+ public class GameObjectPoolAwakeSystem : AwakeSystem<GameObjectPool>
|
|
|
|
+ {
|
|
|
|
+ protected override void Awake(GameObjectPool self)
|
|
|
|
+ {
|
|
|
|
+ GameObjectPool.Instance = self;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ [ObjectSystem]
|
|
|
|
+ public class GameObjectPoolDestroySystem : DestroySystem<GameObjectPool>
|
|
|
|
+ {
|
|
|
|
+ protected override void Destroy(GameObjectPool self)
|
|
|
|
+ {
|
|
|
|
+ self.ClearCache();
|
|
|
|
+ GameObjectPool.Instance = null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ [ComponentOf(typeof(Scene))]
|
|
|
|
+ public class GameObjectPool : Entity, IAwake, IDestroy
|
|
|
|
+ {
|
|
|
|
+ [StaticField]
|
|
|
|
+ public static GameObjectPool Instance;
|
|
|
|
+
|
|
|
|
+ private readonly HashMap<string, List<GameObject>> goPool = new();
|
|
|
|
+
|
|
|
|
+ //TODO: 选取当前场景的单位、技能(事件触发等等)
|
|
|
|
+ //TODO: BUFF
|
|
|
|
+ public async ETTask CacheSceneObject(/*int scnId*/)
|
|
|
|
+ {
|
|
|
|
+ var templates = BattleResourceMgr.Instance.GameEditorTemplates.Templates;
|
|
|
|
+
|
|
|
|
+ //遍历模型
|
|
|
|
+ var units = templates.getUnits();
|
|
|
|
+ foreach(var unit in units.Values)
|
|
|
|
+ {
|
|
|
|
+ var name = $"Unit_{unit.FileName}";
|
|
|
|
+ var handle = await YooAssetProxy.LoadAssetAsync<GameObject>(name);
|
|
|
|
+ var prefab = handle.GetAssetObject<GameObject>();
|
|
|
|
+ var gameobj = UnityEngine.Object.Instantiate(prefab, GlobalViewComponent.Instance.RecycleNode, true);
|
|
|
|
+ gameobj.name = name;
|
|
|
|
+ RecycleObject(gameobj);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<string> effectlist = new();
|
|
|
|
+ var skills = templates.getAllSkillData();
|
|
|
|
+ foreach (var skt in skills.Values)
|
|
|
|
+ {
|
|
|
|
+ foreach (var act in skt.ActionQueue)
|
|
|
|
+ {
|
|
|
|
+ if (!act.ActionEffectFileName.IsNullOrWhitespace())
|
|
|
|
+ {
|
|
|
|
+ effectlist.Add(act.ActionEffectFileName);
|
|
|
|
+ }
|
|
|
|
+ foreach (var kf in act.KeyFrames)
|
|
|
|
+ {
|
|
|
|
+ if (kf.Effect != null && !kf.Effect.Name.IsNullOrWhitespace())
|
|
|
|
+ {
|
|
|
|
+ effectlist.Add(kf.Effect.Name);
|
|
|
|
+ }
|
|
|
|
+ if (kf.Spell != null)
|
|
|
|
+ {
|
|
|
|
+ CacheSpellEffect(templates, kf.Spell.SpellID, ref effectlist);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ foreach (var ef in effectlist)
|
|
|
|
+ {
|
|
|
|
+ var name = $"Effect_{ef}";
|
|
|
|
+ var handle = await YooAssetProxy.LoadAssetAsync<GameObject>(name);
|
|
|
|
+ var prefab = handle.GetAssetObject<GameObject>();
|
|
|
|
+ var gameobj = UnityEngine.Object.Instantiate(prefab, GlobalViewComponent.Instance.RecycleNode, true);
|
|
|
|
+ gameobj.name = name;
|
|
|
|
+ RecycleObject(gameobj);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void CacheSpellEffect(TemplateManager templates, int spellid, ref List<string> effectlist)
|
|
|
|
+ {
|
|
|
|
+ var spell = templates.getSpell(spellid);
|
|
|
|
+ if (spell == null)
|
|
|
|
+ {
|
|
|
|
+ Log.Error($"spell({spellid}) not exist");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (!spell.FileName.IsNullOrWhitespace())
|
|
|
|
+ {
|
|
|
|
+ effectlist.Add(spell.FileName);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var frame = spell.HitIntervalKeyFrame;
|
|
|
|
+ if (frame != null)
|
|
|
|
+ {
|
|
|
|
+ if (frame.Effect != null && !frame.Effect.Name.IsNullOrWhitespace())
|
|
|
|
+ {
|
|
|
|
+ effectlist.Add(frame.Effect.Name);
|
|
|
|
+ }
|
|
|
|
+ if (frame.Spell != null && frame.Spell.SpellID != 0)
|
|
|
|
+ {
|
|
|
|
+ CacheSpellEffect(templates, frame.Spell.SpellID, ref effectlist);
|
|
|
|
+ }
|
|
|
|
+ if (frame.Attack != null)
|
|
|
|
+ {
|
|
|
|
+ var attack = frame.Attack;
|
|
|
|
+ if (attack.Effect != null && !attack.Effect.Name.IsNullOrWhitespace())
|
|
|
|
+ {
|
|
|
|
+ effectlist.Add(attack.Effect.Name);
|
|
|
|
+ }
|
|
|
|
+ if (attack.Spell != null && attack.Spell.SpellID != 0)
|
|
|
|
+ {
|
|
|
|
+ CacheSpellEffect(templates, attack.Spell.SpellID, ref effectlist);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ frame = spell.HitOnExplosionKeyFrame;
|
|
|
|
+ if (spell.HitOnExplosion && frame != null)
|
|
|
|
+ {
|
|
|
|
+ if (frame.Effect != null && !frame.Effect.Name.IsNullOrWhitespace())
|
|
|
|
+ {
|
|
|
|
+ effectlist.Add(frame.Effect.Name);
|
|
|
|
+ }
|
|
|
|
+ if (frame.Spell != null && frame.Spell.SpellID != 0)
|
|
|
|
+ {
|
|
|
|
+ CacheSpellEffect(templates, frame.Spell.SpellID, ref effectlist);
|
|
|
|
+ }
|
|
|
|
+ if (frame.Attack != null)
|
|
|
|
+ {
|
|
|
|
+ var attack = frame.Attack;
|
|
|
|
+ if (attack.Effect != null && !attack.Effect.Name.IsNullOrWhitespace())
|
|
|
|
+ {
|
|
|
|
+ effectlist.Add(attack.Effect.Name);
|
|
|
|
+ }
|
|
|
|
+ if (attack.Spell != null && attack.Spell.SpellID != 0)
|
|
|
|
+ {
|
|
|
|
+ CacheSpellEffect(templates, attack.Spell.SpellID, ref effectlist);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ foreach (var frm in spell.KeyFrames)
|
|
|
|
+ {
|
|
|
|
+ if (frm.Effect != null && !frm.Effect.Name.IsNullOrWhitespace())
|
|
|
|
+ {
|
|
|
|
+ effectlist.Add(frm.Effect.Name);
|
|
|
|
+ }
|
|
|
|
+ if (frm.Spell != null && frame.Spell.SpellID != 0)
|
|
|
|
+ {
|
|
|
|
+ CacheSpellEffect(templates, frm.Spell.SpellID, ref effectlist);
|
|
|
|
+ }
|
|
|
|
+ if (frm.Attack != null)
|
|
|
|
+ {
|
|
|
|
+ var attack = frm.Attack;
|
|
|
|
+ if (attack.Effect != null && !attack.Effect.Name.IsNullOrWhitespace())
|
|
|
|
+ {
|
|
|
|
+ effectlist.Add(attack.Effect.Name);
|
|
|
|
+ }
|
|
|
|
+ if (attack.Spell != null && attack.Spell.SpellID != 0)
|
|
|
|
+ {
|
|
|
|
+ CacheSpellEffect(templates, attack.Spell.SpellID, ref effectlist);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void ClearCache()
|
|
|
|
+ {
|
|
|
|
+ foreach (var list in goPool.Values)
|
|
|
|
+ {
|
|
|
|
+ foreach (var go in list)
|
|
|
|
+ {
|
|
|
|
+ GameObject.Destroy(go);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ goPool.Clear();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void RecycleObject(GameObject go, string key = "")
|
|
|
|
+ {
|
|
|
|
+ if(key.IsNullOrWhitespace())
|
|
|
|
+ {
|
|
|
|
+ key = go.name;
|
|
|
|
+ }
|
|
|
|
+ Log.Debug($"cache gameobject: {key}");
|
|
|
|
+ go.SetActive(false);
|
|
|
|
+ go.transform.SetParent(GlobalViewComponent.Instance.RecycleNode, false);
|
|
|
|
+ if (goPool.TryGetValue(key, out var golist))
|
|
|
|
+ {
|
|
|
|
+ golist.Add(go);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ goPool.Add(key, new List<GameObject>() { go });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public async ETTask<GameObject> Acquire(string key)
|
|
|
|
+ {
|
|
|
|
+ if (goPool.TryGetValue(key, out var golist))
|
|
|
|
+ {
|
|
|
|
+ if (golist.Count > 0)
|
|
|
|
+ {
|
|
|
|
+ Log.Debug($"got gameobject ({key}) from pool");
|
|
|
|
+ var gobj = golist[0];
|
|
|
|
+ golist.RemoveRange(0, 1);
|
|
|
|
+ return gobj;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ goPool.Add(key, new List<GameObject>());
|
|
|
|
+ }
|
|
|
|
+ Log.Debug($"new gameobject: ({key})");
|
|
|
|
+
|
|
|
|
+ var handle = await YooAssetProxy.LoadAssetAsync<GameObject>(key);
|
|
|
|
+ var prefab = handle.GetAssetObject<GameObject>();
|
|
|
|
+ var gameobj = UnityEngine.Object.Instantiate(prefab, GlobalViewComponent.Instance.RecycleNode, true);
|
|
|
|
+ gameobj.name = key;
|
|
|
|
+ return gameobj;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|