using cfg.GuideCfg; using Gameplay.SubSystems; using System; using Cysharp.Threading.Tasks; using Gameplay.Level; using Framework; namespace Gameplay.Guide { /// /// 引导状态 /// public enum E_GuideState { /// /// 等待引导 /// Idle, /// /// 引导中 /// Guiding, /// /// 引导完成 /// Complete, } /// /// 引导步骤基类 /// public abstract class GuideStepBase { /// /// 引导完成类型 /// private readonly GuideCompleteBase completeBase; /// /// 引导配置 /// public DataGuideCfg Cfg { get; private set; } /// /// 引导状态 /// public E_GuideState GuideState { get; private set; } /// /// 是否引导中 /// public bool IsGuiding { get { return E_GuideState.Guiding == GuideState; } } public GuideStepBase(DataGuideCfg cfg) { Cfg = cfg; GuideState = E_GuideState.Idle; completeBase = Cfg.GuideCompleteType switch { E_GuideCompleteType.PlayVideoOver => new PlayVideoComplete(Cfg, Complete), E_GuideCompleteType.OpenUI => new OpenUIComplete(Cfg, Complete), E_GuideCompleteType.CloseUI => new CloseUIComplete(Cfg, Complete), E_GuideCompleteType.OpenUIAndAnim => new OpenUIAndAnimComplete(Cfg, Complete), E_GuideCompleteType.EnterLevelComplete => new EnterLevelComplete(Cfg, Complete), E_GuideCompleteType.EmbattleComplete => new LevelEmbattleComplete(Cfg, Complete), E_GuideCompleteType.FightBegin => new FightBeginComplete(Cfg, Complete), E_GuideCompleteType.FightMoveComplete => new FightMoveComplete(Cfg, Complete), E_GuideCompleteType.FightAttackComplete => new FightAttackComplete(Cfg, Complete), E_GuideCompleteType.FightEmbattleComplete => new FightEmbattleComplete(Cfg, Complete), E_GuideCompleteType.FightMoraleAndRepressionComplete => new FightMoraleAndRepressionComplete(Cfg, Complete), E_GuideCompleteType.FightUseSkillComplete => new FightUseSkillComplete(Cfg, Complete), E_GuideCompleteType.LevelComplete => new LevelComplete(Cfg, Complete), E_GuideCompleteType.WaitTimeComplete => new WaitTimeComplete(Cfg, Complete), E_GuideCompleteType.SelectModel => new SelectModeComplete(Cfg, Complete), E_GuideCompleteType.SelectChapter => new SelectChapterComplete(Cfg, Complete), E_GuideCompleteType.OpenCommandSkill => new OpenCommandSkillComplete(Cfg, Complete), E_GuideCompleteType.CloseCommandSkill => new CloseCommandSkillComplete(Cfg, Complete), E_GuideCompleteType.CharacterLevelUp => new CharacterLevelUpComplete(Cfg, Complete), E_GuideCompleteType.ClickGuideButton => new ClickGuideButtonComplete(Cfg, Complete), _ => throw new Exception($"未处理类型:{Cfg.GuideCompleteType}"), }; } /// /// 开始引导 /// public void StartGuide() { DoBeforeGuide(); GuideState = E_GuideState.Guiding; DoGuide(); } /// /// 引导开始之前 /// protected virtual void DoBeforeGuide() { completeBase.AddListener(); } /// /// 引导 /// protected virtual void DoGuide() { EventManager.Instance.Send(EventManager.EventName.GuideStepBegin); } /// /// 引导完成之前 /// protected virtual void DoBeforeComplete() { completeBase.RemoveListener(); } /// /// 完成引导 /// public void Complete() { if (!IsGuiding) return; DebugUtil.Log($"完成id为{Cfg.Id}的引导"); // #00FA9A绿色 GuideState = E_GuideState.Complete; DoBeforeComplete(); GuideManager.Instance.CompleteStep(this); } /// /// 结束引导 /// public void EndGuide() { if (!IsGuiding) return; GuideState = E_GuideState.Idle; completeBase.RemoveListener(); } } /// /// 等待指定时间引导步骤 /// internal sealed class WaitTimeStep : GuideStepBase { /// /// 等待时间(单位毫秒) /// private readonly int time; public WaitTimeStep(DataGuideCfg cfg) : base(cfg) { if (cfg.GuideTypeParams.Length <= 0) throw new Exception($"引导类型:{Cfg.GuideStepType},参数错误"); if (float.TryParse(cfg.GuideTypeParams[0], out float t)) time = (int)(t * 1000f); } protected override async void DoGuide() { await UniTask.Delay(time); base.DoGuide(); await UI_GuideController.Open(); } protected override void DoBeforeComplete() { base.DoBeforeComplete(); UIManager.Instance.CloseWindow(UINameConst.UI_Guide); } } /// /// 点击按钮 /// internal sealed class ClickButtonStep : GuideStepBase { /// /// UI名 /// private readonly string uiName; /// /// 按钮路径 /// private readonly string buttonPath; public ClickButtonStep(DataGuideCfg cfg) : base(cfg) { if (cfg.GuideTypeParams.Length <= 1) throw new Exception($"引导类型:{Cfg.GuideStepType},参数错误"); uiName = cfg.GuideTypeParams[0]; buttonPath = cfg.GuideTypeParams[1]; } protected override async void DoBeforeComplete() { base.DoBeforeComplete(); await UI_GuideController.Open(); } protected override async void DoGuide() { await UI_GuideController.Open(uiName, buttonPath, Cfg); } } /// /// 播放视频 /// internal sealed class PlayVideoStep : GuideStepBase { /// /// 视频路径 /// private readonly string videoPath; public PlayVideoStep(DataGuideCfg cfg) : base(cfg) { if (cfg.GuideTypeParams.Length <= 0) throw new Exception($"引导类型:{Cfg.GuideStepType},参数错误"); videoPath = cfg.GuideTypeParams[0]; } protected override async void DoGuide() { await UI_PlayVideoController.Open(videoPath); } } /// /// 第一次进入主界面 /// internal sealed class EnterMainStep : GuideStepBase { public EnterMainStep(DataGuideCfg cfg) : base(cfg) { } protected override void DoGuide() { GameStateManager.Instance.ChangeState(new GameStateMainScene()); } } /// /// 显示引导提示 /// internal sealed class ShowGuideTipStep : GuideStepBase { /// /// 引导提示配置id /// private readonly int guideTipCfgId; public ShowGuideTipStep(DataGuideCfg cfg) : base(cfg) { if (cfg.GuideTypeParams.Length <= 0) throw new Exception($"引导类型:{Cfg.GuideStepType},参数错误"); if (int.TryParse(cfg.GuideTypeParams[0], out int id)) guideTipCfgId = id; } protected override async void DoGuide() { await UI_GuideTipController.Open(guideTipCfgId); } } /// /// 进入关卡 /// internal sealed class EnterLevelStep : GuideStepBase { /// /// 关卡id /// private readonly int levelId; public EnterLevelStep(DataGuideCfg cfg) : base(cfg) { if (Cfg.GuideTypeParams.Length <= 0) throw new Exception($"引导类型:{Cfg.GuideStepType},参数错误"); if (int.TryParse(Cfg.GuideTypeParams[0], out int id)) levelId = id; } protected override async void DoGuide() { await UI_GuideController.Open(); LevelManager.Instance.TryEnterLevel(levelId); } } /// /// 关卡上阵 /// internal sealed class LevelEmbattleStep : GuideStepBase { public LevelEmbattleStep(DataGuideCfg cfg) : base(cfg) { } protected override void DoGuide() { } } /// /// 教学战斗移动 /// internal sealed class TeachFightMoveStep : GuideStepBase { /// /// 引导提示配置id /// private readonly int guideTipCfgId; public TeachFightMoveStep(DataGuideCfg cfg) : base(cfg) { if (cfg.GuideTypeParams.Length <= 0) throw new Exception($"引导类型:{Cfg.GuideStepType},参数错误"); if (int.TryParse(cfg.GuideTypeParams[0], out int id)) guideTipCfgId = id; } protected override async void DoGuide() { LevelManager.Instance.CurrentLevel.SetPause(true); await UI_GuideTipController.Open(guideTipCfgId); } } /// /// 教学战斗攻击 /// internal sealed class TeachFightAttackStep : GuideStepBase { /// /// 引导提示配置id /// private readonly int guideTipCfgId; public TeachFightAttackStep(DataGuideCfg cfg) : base(cfg) { if (cfg.GuideTypeParams.Length <= 0) throw new Exception($"引导类型:{Cfg.GuideStepType},参数错误"); if (int.TryParse(cfg.GuideTypeParams[0], out int id)) guideTipCfgId = id; } protected override async void DoGuide() { LevelManager.Instance.CurrentLevel.SetPause(true); await UI_GuideTipController.Open(guideTipCfgId); } } /// /// 教学士气与压制 /// internal sealed class TeachMoraleAndRepression : GuideStepBase { /// /// 引导提示配置id /// private readonly int guideTipCfgId; public TeachMoraleAndRepression(DataGuideCfg cfg) : base(cfg) { if (cfg.GuideTypeParams.Length <= 0) throw new Exception($"引导类型:{Cfg.GuideStepType},参数错误"); if (int.TryParse(cfg.GuideTypeParams[0], out int id)) guideTipCfgId = id; } protected override async void DoGuide() { LevelManager.Instance.CurrentLevel.SetPause(true); await UI_GuideTipController.Open(guideTipCfgId); } } /// /// 教学使用技能 /// internal sealed class TeachUseSkill : GuideStepBase { /// /// 引导提示配置id /// private readonly int guideTipCfgId; public TeachUseSkill(DataGuideCfg cfg) : base(cfg) { if (cfg.GuideTypeParams.Length <= 0) throw new Exception($"引导类型:{Cfg.GuideStepType},参数错误"); if (int.TryParse(cfg.GuideTypeParams[0], out int id)) guideTipCfgId = id; } protected override async void DoGuide() { LevelManager.Instance.CurrentLevel.SetPause(true); await UI_GuideTipController.Open(guideTipCfgId); } } /// /// 教学战斗中上阵 /// internal sealed class TeachFightEmbattle : GuideStepBase { /// /// 引导提示配置id /// private readonly int guideTipCfgId; public TeachFightEmbattle(DataGuideCfg cfg) : base(cfg) { if (cfg.GuideTypeParams.Length <= 0) throw new Exception($"引导类型:{Cfg.GuideStepType},参数错误"); if (int.TryParse(cfg.GuideTypeParams[0], out int id)) guideTipCfgId = id; } protected override async void DoGuide() { LevelManager.Instance.CurrentLevel.SetPause(true); await UI_GuideTipController.Open(guideTipCfgId); } } /// /// 等待关卡结束 /// internal sealed class WaitLevelComplete : GuideStepBase { private readonly bool isContinue; public WaitLevelComplete(DataGuideCfg cfg) : base(cfg) { if (cfg.GuideTypeParams.Length <= 0) throw new Exception($"引导类型:{Cfg.GuideStepType},参数错误"); if (bool.TryParse(cfg.GuideTypeParams[0], out bool isContinue)) this.isContinue = isContinue; } protected override void DoGuide() { LevelManager.Instance.ExitLevelChangeMainFunc = () => { return isContinue; }; } } }