using CommonAI.Zone; using UnityEngine; using System.Text.RegularExpressions; using CommonLang; using Sirenix.Utilities; using ET.EventType; using System.Collections.Generic; namespace ET.Client { [Event(SceneType.None)] public class PlayEffectEventHandler : BEvent { private static Vector3 vecTemp = new(); public override void OnEvent(PlayEffectEvent args) { vecTemp.Set(args.Pos.X, args.Pos.Y, args.Pos.Z); EffectMgr.Instance.PlayEffect(args.Effect, args.HostId, vecTemp, args.Time, args.Rotation).Coroutine(); } } public class EffectMgr : Singleton, ISingletonUpdate { private HashMap playingList = new(); private static Vector3 vecTemp = new(); private List listTemp = new(); public void Update(int timeMS) { listTemp.Clear(); var now = Time.realtimeSinceStartup; foreach (var epi in playingList.Values) { if (epi.EndTime <= now) { listTemp.Add(epi.Id); } } foreach(var id in listTemp) { RemoveEffect(id); } } public async ETTask PlayEffect(LaunchEffect effect, uint HostId, Vector3 pos, float time = 0f, float rotation = 0f) { var starttime = Time.realtimeSinceStartup; GameObject go = null; if (!effect.Name.IsNullOrWhitespace()) { UnitRenderComponet render = null; if (effect.BindBody) { render = ModelViewComponent.Instance.GetChild(HostId); if (render == null) { Log.Debug($"ignore unit effect: {effect.Name}@{HostId}, cause of No Render"); return 0; } } go = await GameObjectPool.Instance.Acquire("Effect_" + effect.Name); var timeComponent = go.GetComponent(); if (time == 0f) time = timeComponent.duration; if (time < 0f) time = EffectPlayInfo.TIME_FOREVER; setupEffect(go, effect, render, pos, rotation); } else if(!effect.SoundName.IsNullOrWhitespace()) { //TODO: 音效的位置这里还有一堆逻辑的 SoundManager.Instance.Play3DSound(effect.SoundName, pos).Coroutine(); } if (effect.EarthQuakeMS > 0) { vecTemp.Set(effect.EarthQuakeXYZ, effect.EarthQuakeXYZ, effect.EarthQuakeXYZ); CameraMgr.ShakeMe(effect.EarthQuakeMS, vecTemp); } if (go != null) { var epi = ObjectPool.Instance.Fetch(); epi.Reset(go, starttime + time); playingList.Add(epi.Id, epi); return epi.Id; } return 0; } private void setupEffect(GameObject go, LaunchEffect effectData, UnitRenderComponet render, Vector3 pos, float rotation) { var gt = go.transform; if (effectData.BindBody) { if (!effectData.BindPartName.IsNullOrWhitespace()) { gt.parent = render.GetBindPart(effectData.BindPartName); } else { gt.parent = render.GameObject.transform; } vecTemp.Set(effectData.EffectOffsetX, 0, effectData.EffectOffsetY); gt.localPosition = vecTemp; if (effectData.Tag == "FixStartRotaion") { gt.rotation = RenderUtils.UnityRotationFromBattle(0); } else { gt.localRotation = Quaternion.identity; } } else { gt.rotation = RenderUtils.UnityRotationFromBattle(0); gt.parent = GlobalViewComponent.Instance.Unit; } if (pos != Vector3.zero) { vecTemp.Set(effectData.EffectOffsetX, effectData.EffectHight, effectData.EffectOffsetY); gt.position = pos + vecTemp; } if (rotation != 0) { gt.rotation = RenderUtils.UnityRotationFromBattle(rotation); } var scale = effectData.ScaleToBodySize != 0 ? effectData.ScaleToBodySize : 1f; vecTemp.Set(scale, scale, scale); gt.localScale = vecTemp; if (!string.IsNullOrEmpty(effectData.Tag)) { //Effect支持Tag设置Event,格式:Event:事件名(事件参数) Match m = Regex.Match(effectData.Tag, @"^Event:(\w+)\((.*)\)"); if (m.Groups.Count >= 3) { string eventName = m.Groups[1].Value; string eventParam = m.Groups[2].Value; if (!string.IsNullOrEmpty(eventName)) { Log.Error("Not support: Effect({0}) Triggle event:{1}", effectData.Name, effectData.Tag); /*EventManager.Fire("Event." + eventName, new Dictionary() { {"param", eventParam}, {"position", gt.position} });*/ } } } go.SetActive(true); if (!effectData.SoundName.IsNullOrWhitespace()) { SoundManager.Instance.Play3DSound(effectData.SoundName, gt.position).Coroutine(); } } public void Clear() { foreach (var epi in playingList.Values) { GameObject.Destroy(epi.GameObj); } playingList.Clear(); } public void RemoveEffect(uint id) { if (playingList.ContainsKey(id)) { var info = playingList[id]; playingList.Remove(id); GameObjectPool.Instance.RecycleObject(info.GameObj); } } } }