using CMDType = ET.AnimatorEventType; using AniType = Mono.AnimationData.AnimationType; using UnityEngine; using System.Text.RegularExpressions; using ET.EventType; using Sirenix.Utilities; using CommonAI.Zone; using FairyGUI; namespace ET.Client { [Event(SceneType.Current)] [FriendOf(typeof(ET.Client.UnitRenderComponet))] public class AnimatorEventHandler : BEvent { public override void OnEvent(EventType.PlayAnimatorEvent args) { var component = ModelViewComponent.Instance.GetChild(args.UnitId); if (component == null) { Log.Debug($"Not found UnitRener of object{args.UnitId}"); return; } if (component.AniData == null) { var unit = UnitMgr.Instance.GetUnit(args.UnitId); Log.Error($"UnitRender({component.GameObject.name}) not contains AnimationData component"); return; } if (args.CommandType == CMDType.Skill) { var m = Regex.Match(args.SkillName, "[Ss]kill(\\d+)"); if (m.Success) { int n = System.Convert.ToInt32(m.Groups[1].Value, 10); if (n >= 0 && AniType.SkillMax > AniType.Skill0 + n) { AnimatorCommand cmd = new AnimatorCommand((AniType)(AniType.Skill0 + n)) { Duration = args.Duration, Speed = args.Speed, GroupId = args.GroupId, Loop = args.Loop }; component.AppendCommand(cmd); return; } } Log.Error($"Not support skill animation: {args.SkillName}"); } else { AnimatorCommand cmd = args.CommandType switch { AnimatorEventType.Idle => UnitRenderComponet.CMDIdle, AnimatorEventType.Run => UnitRenderComponet.CMDRun, AnimatorEventType.Dead => UnitRenderComponet.CMDDead, _ => UnitRenderComponet.CMDIdle }; component.AppendCommand(cmd); } if(!args.Audio.IsNullOrWhitespace()) { //TODO: Playaudio } } } [Event(SceneType.None)] public class SyncUnitPosEventHandler : BEvent { public override void OnEvent(SyncUnitPosEvent args) { var unitRender = ModelViewComponent.Instance.GetChild(args.Id); if(unitRender != null) { var transform = unitRender.GameObject.transform; transform.position = RenderUtils.UnityPosFromBattle(args.Pos); transform.rotation = RenderUtils.UnityRotationFromBattle(args.Rotation, args.RotationX); if(args.Id == UnitMgr.Instance.ActorId) { CameraMgr.FollowMe(transform.position); } unitRender.SyncHeadBarPos(); } else { //Log.Debug($"Not exist unitRender: {args.Id}"); } //_actor.SendUnitMove(dx, dy, true); //(_actor.ZUnit as ZoneActor).SendUnitStopMove(); //StartSeek(p.X, p.Y, 0, null, false); } } [FriendOf(typeof(UnitRenderComponet))] public static class UnitRenerSystem { [ObjectSystem] public class UnitRenerAwakeSystem : AwakeSystem { protected override void Awake(UnitRenderComponet self, GameObject go) { self.GameObject = go; self.AniData = self.GameObject.GetComponent(); if (self.AniData != null) { self.ExeCommand(UnitRenderComponet.CMDIdle); } self.TransHeadInfo = go.transform.Find("BindPart/headInfo"); } } [ObjectSystem] public class UnitRenerUpdateSystem : UpdateSystem { protected override void Update(UnitRenderComponet self) { if (self.AniData == null) { return; } var cmd = self.FilterCmdList(); if (cmd != null) { if (self.DoingCmd?.Type != cmd.Type || cmd.IsSkillCmd()) { self.ExeCommand(cmd); } } } } [ObjectSystem] public class UnitRenerDestroySystem : DestroySystem { protected override void Destroy(UnitRenderComponet self) { if(self.AniData!= null) { self.AniData.Animancer.Stop(); } GameObjectPool.Instance?.RecycleObject(self.GameObject); if(self.HeadBar != null) { self.HeadBar.visible = false; GameObjectPool.Instance?.RecycleHeadBar(self.HeadBar); } self.Reset(); } } //===UnitRener 扩展方法------- public static void AppendCommand(this UnitRenderComponet self, AnimatorCommand cmd) { self.Commands.Add(cmd); } public static void SyncHeadBarPos(this UnitRenderComponet self) { if (self.HeadBar != null) { var part = self.TransHeadInfo ?? self.GameObject.transform; var pos = Camera.main.WorldToScreenPoint(part.position); if(pos.z < 0 || pos.x < 0 || pos.x > Screen.width || pos.y < 0 || pos.y > Screen.height) { //不在视野中 self.HeadBar.visible = false; } else { var screenpos = pos; pos.y = Screen.height - pos.y; pos = GRoot.inst.GlobalToLocal(pos); self.HeadBar.SetXY(pos.x, pos.y); self.HeadBar.visible = true; } } } //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //执行指令 private static void ExeCommand(this UnitRenderComponet self, AnimatorCommand cmd) { self.DoingCmd = (AnimatorCommand)cmd; if(!cmd.IsSkillCmd()) { self.AniData.PlayAnimation(cmd.Type); } else { //Skill动作和实际技能时间不太匹配,切到idle动作 self.AniData.PlayAnimation(cmd.Type, () => { if (self.DoingCmd == cmd) { self.ExeCommand(UnitRenderComponet.CMDIdle); } }); } } //从指令队列中分析出当前需要执行的指令 private static AnimatorCommand FilterCmdList(this UnitRenderComponet self) { var cmds = self.Commands; if (cmds.Count <= 0) { return null; } /*var cmd = cmds[0]; for(var i=1; i= CMDType.Skill0 && cmd.Type <= CMDType.Skill3) { cmd = UnitRener.CMDIdle; } else if(next.Type > cmd.Type && cmd.Type < CMDType.Skill0) { cmd = next; } }*/ var cmd = cmds[cmds.Count - 1]; if(cmd.GroupId > 0) { int delIndex = -1; for(var i = cmds.Count -2; i >= 0; i--) { if (cmds[i].GroupId != cmd.GroupId) { delIndex = i; break; } } if(delIndex >= 0) { cmds.RemoveRange(0, delIndex + 1); } else { cmds.Clear(); } } else { cmds.Clear(); } return cmd; } } }