using CommonAI.Zone.Helper; using CommonAI.ZoneClient; using CommonLang; using System; using System.Collections; using UnityEngine; using CommonLang.Concurrent; using CommonAI.Zone; using System.Collections.Generic; using System.IO; using CommonAIClient.Unity.Utils; namespace CommonAIClient.Unity.Battle { public partial class ComAIUnit { HashMap<ZoneUnit.BuffState, Buff> mBuffs = new HashMap<ZoneUnit.BuffState, Buff>(); private void UpdateBuff(float deltaTime) { foreach (var elem in mBuffs) { elem.Value.Update(deltaTime); } } protected virtual void ZUnit_OnBuffAdded(ZoneUnit unit, ZoneUnit.BuffState state) { Buff buff = new Buff(this, state); mBuffs.Add(state, buff); } protected virtual void ZUnit_OnBuffChanged(ZoneUnit unit, ZoneUnit.BuffState state) { Buff buff = null; if (mBuffs.TryGetValue(state, out buff)) { buff.OnChange(state); } } protected virtual void ZUnit_OnBuffRemoved(ZoneUnit unit, ZoneUnit.BuffState state) { Buff buff = mBuffs.RemoveByKey(state); if (buff != null) { buff.Dispose(); } } public class Buff { #region RefCount private static AtomicInteger s_alloc_count = new AtomicInteger(0); private static AtomicInteger s_active_count = new AtomicInteger(0); /// <summary> /// 分配实例数量 /// </summary> public static int AllocCount { get { return s_alloc_count.Value; } } /// <summary> /// 未释放实例数量 /// </summary> public static int ActiveCount { get { return s_active_count.Value; } } #endregion private bool mDisposed = false; private List<AssetObjectExt> mModels = new List<AssetObjectExt>(); private List<Audio> mAudios = new List<Audio>(); private AssetObjectExt mOverlayModel; private Audio mOverlayAudio; private Avatar mAvatar; internal readonly ComAIUnit mOwner; internal readonly ZoneUnit.BuffState mState; public bool IsDisposed { get { return mDisposed; } } protected ComAIUnit Owner { get { return mOwner; } } protected ZoneUnit.BuffState State { get { return State; } } internal Buff(ComAIUnit owner, ZoneUnit.BuffState state) { s_alloc_count++; s_active_count++; this.mOwner = owner; this.mState = state; if (state.Data.MakeAvatar && !string.IsNullOrEmpty(state.Data.UnitFileName)) { mAvatar = owner.AddAvatar(state.Data.UnitFileName , Path.GetFileNameWithoutExtension(state.Data.UnitFileName)); } if (state.Data.BindingEffect != null) { InitBindingEffect(state.Data.BindingEffect); } if (state.Data.BindingEffectList != null && state.Data.BindingEffectList.Count > 0) { foreach (var elem in state.Data.BindingEffectList) { InitBindingEffect(elem); } } OnChange(state); } //只在初始化阶段调用 private void InitBindingEffect(LaunchEffect eff) { if (!string.IsNullOrEmpty(eff.Name)) { BattleFactroy.Instance.GameObjectAdapter.Load(eff.Name , System.IO.Path.GetFileNameWithoutExtension(eff.Name) , (succ, aoe) => { if (IsDisposed) { BattleFactroy.Instance.GameObjectAdapter.Unload(aoe); return; } aoe.gameObject.ParentRoot(Owner.EffectRoot); mModels.Add(aoe); }); } if (!string.IsNullOrEmpty(eff.SoundName)) { if (eff.IsLoop) { Audio audio = BattleFactroy.Instance.SoundAdapter.PlaySoundLoop(eff.SoundName, mOwner.ObjectRoot); mAudios.Add(audio); } else { BattleFactroy.Instance.SoundAdapter.PlaySound(eff.SoundName, mOwner.ObjectRoot.Position()); } } } ~Buff() { s_alloc_count--; } //多层叠加 internal void OnChange(ZoneUnit.BuffState state) { if (state.OverlayLevel < state.Data.OverlayBindingEffect.Count) { var eff = state.Data.OverlayBindingEffect[state.OverlayLevel - 1]; BattleFactroy.Instance.GameObjectAdapter.Load(eff.Name , System.IO.Path.GetFileNameWithoutExtension(eff.Name) , (succ, aoe) => { if (IsDisposed) { BattleFactroy.Instance.GameObjectAdapter.Unload(aoe); return; } if (mOverlayModel != null) { BattleFactroy.Instance.GameObjectAdapter.Unload(mOverlayModel); } mOverlayModel = aoe; mOverlayModel.gameObject.ParentRoot(Owner.EffectRoot); }); if (!string.IsNullOrEmpty(eff.SoundName)) { if (eff.IsLoop) { mOverlayAudio = BattleFactroy.Instance.SoundAdapter.PlaySoundLoop(eff.SoundName, mOwner.ObjectRoot); } else { BattleFactroy.Instance.SoundAdapter.PlaySound(eff.SoundName, mOwner.ObjectRoot.Position()); } } } } internal void Dispose() { if (!mDisposed) { OnDispose(); mDisposed = true; s_active_count--; } } protected virtual void OnDispose() { if (mAvatar != null) { mOwner.RemoveAvatar(mAvatar); } foreach (var elem in mModels) { BattleFactroy.Instance.GameObjectAdapter.Unload(elem); } foreach (var elem in mAudios) { BattleFactroy.Instance.SoundAdapter.StopSoundLoop(elem); } if (mOverlayModel != null) { BattleFactroy.Instance.GameObjectAdapter.Unload(mOverlayModel); } if (mOverlayAudio != null) { BattleFactroy.Instance.SoundAdapter.StopSoundLoop(mOverlayAudio); } } internal protected virtual void Update(float deltaTime) { } } } }