先修复一下,错误的场景 删除不必要的钓场资产 修复into场景 update:更新meta文件,修复报错 update:修复资源 修复第一章节建造 修复建造第三章 update:删除多余内容 update:更新README.md update:还原图标 update:更新README update:更新配置
757 lines
34 KiB
C#
757 lines
34 KiB
C#
using asap.core;
|
||
using cfg;
|
||
using game;
|
||
using LitJson;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using UniRx;
|
||
using UnityEngine;
|
||
using UnityEngine.AddressableAssets;
|
||
|
||
namespace GameCore
|
||
{
|
||
public class GuideNextEvent
|
||
{
|
||
|
||
}
|
||
public class AddIndexEvent
|
||
{
|
||
public bool CompleteGuide;
|
||
public int guideSubIndex;
|
||
public bool isAutoNext;
|
||
}
|
||
/// <summary>
|
||
/// 废弃
|
||
/// </summary>
|
||
public struct OnEventTriggerGuide
|
||
{
|
||
public OnEventTriggerGuide(string panelName)
|
||
{
|
||
this.panelName = panelName;
|
||
}
|
||
public string panelName;
|
||
}
|
||
public class GuideSaveData
|
||
{
|
||
public int guideSubIndex = 0;
|
||
public bool isFinish = false;
|
||
public string groupName;
|
||
}
|
||
/// <summary>
|
||
/// 新手引导数据中心。外部触发主要有三类路径:
|
||
/// 1) 各 UI/玩法在打开或 OnEnable 时调用 <see cref="InspectTriggerGuide"/>,按配置表首步 panelName 与触发条件尝试开组;
|
||
/// 2) 面板打开后通过 <c>GContext.Publish(new OnEventTriggerGuide(panelName))</c> 驱动 <see cref="TriggerGuideNext"/>,推进「当前组」下一步或回退尝试 <see cref="InspectTriggerGuide"/>;
|
||
/// 3) 业务显式调用 <see cref="TriggerGuide"/> / <see cref="AddIndex"/> / <see cref="IsGuide"/> / <see cref="ShowGuidancePopupPanel"/> 等完成指定流程。
|
||
/// 存档由 <see cref="SetData"/>(登录拉取)与 <see cref="Save"/>(写 PlayFab)维护。
|
||
/// </summary>
|
||
public class GuideDataCenter : IDisposable
|
||
{
|
||
Tables _tables;
|
||
PlayerData playerData;
|
||
public GuideDataCenter(cfg.Tables tables, PlayerData playerData)
|
||
{
|
||
this._tables = tables;
|
||
this.playerData = playerData;
|
||
}
|
||
public string CurPanelName;
|
||
public Dictionary<string, GuideSaveData> GuideSaveDataDic = new Dictionary<string, GuideSaveData>();
|
||
public GuideSaveData curSaveData;
|
||
public GuidanceGroupDefine[] guidanceGroupDefines;
|
||
public GuidanceDefine curDefine;
|
||
public string popupPanelNode;
|
||
public GuidanceGroupDefine curGroupDefine;
|
||
public GuidanceDefineSetting guidanceDefineSetting;
|
||
//待释放
|
||
IDisposable disposable;
|
||
IDisposable disposable2;
|
||
IDisposable disposable3;
|
||
|
||
/// <summary>
|
||
/// GM/调试:清空所有引导组进度并标记为已完成。典型入口:<c>DebugFunc</c> 控制台 <c>guide.clear</c>。
|
||
/// </summary>
|
||
public void GMClearGuide()
|
||
{
|
||
foreach (var item in guidanceGroupDefines)
|
||
{
|
||
if (!GuideSaveDataDic.TryGetValue(item.groupName.ToString(), out GuideSaveData _saveData))
|
||
{
|
||
_saveData = new GuideSaveData();
|
||
_saveData.groupName = item.groupName.ToString();
|
||
GuideSaveDataDic.Add(item.groupName.ToString(), _saveData);
|
||
}
|
||
_saveData.isFinish = true;
|
||
}
|
||
GContext.Publish(new ConditionTypeEvent(ConditionType.CompleteGuide, 0));
|
||
curDefine = null;
|
||
curGroupDefine = null;
|
||
Save();
|
||
}
|
||
/// <summary>
|
||
/// 加载引导配置、校正未完成组的断点、订阅 <see cref="OnEventTriggerGuide"/>。由 <c>FishingStage</c> 等阶段在进游戏后调用。
|
||
/// </summary>
|
||
public async void Init()
|
||
{
|
||
guidanceDefineSetting = (GuidanceDefineSetting)await Addressables.LoadAssetAsync<object>("GuidanceConfig");
|
||
if (guidanceDefineSetting != null)
|
||
{
|
||
bool isUpdate = false;
|
||
guidanceGroupDefines = guidanceDefineSetting.guidanceGroupDefines;
|
||
List<GroupName> Skip = guidanceDefineSetting.SkipGroupNames;
|
||
bool isSkip = playerData.lv >= guidanceDefineSetting.SkipLevel;
|
||
if (GuideSaveDataDic == null)
|
||
{
|
||
GuideSaveDataDic = new Dictionary<string, GuideSaveData>();
|
||
}
|
||
else
|
||
{
|
||
GuideSaveData _saveData;
|
||
GuidanceDefine _define;
|
||
Dictionary<string, GuideSaveData> keyValuePairs = new Dictionary<string, GuideSaveData>();
|
||
foreach (var item in guidanceGroupDefines)
|
||
{
|
||
|
||
if (GuideSaveDataDic.TryGetValue(item.groupName.ToString(), out _saveData))
|
||
{
|
||
if (!_saveData.isFinish && _saveData.guideSubIndex > 0)
|
||
{
|
||
for (int i = _saveData.guideSubIndex; i < item.guidanceDefines.Length; i++)
|
||
{
|
||
_define = item.guidanceDefines[i];
|
||
if (_define.isKey)
|
||
{
|
||
_saveData.guideSubIndex = _define.JumpIndex;
|
||
if (_saveData.guideSubIndex < item.guidanceDefines.Length)
|
||
{
|
||
_saveData.isFinish = false;
|
||
curSaveData = _saveData;
|
||
curGroupDefine = item;
|
||
curDefine = curGroupDefine.guidanceDefines[_saveData.guideSubIndex];
|
||
}
|
||
else
|
||
{
|
||
_saveData.isFinish = true;
|
||
GContext.Publish(new ConditionTypeEvent(ConditionType.CompleteGuide, 1));
|
||
}
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
_saveData.isFinish = true;
|
||
}
|
||
}
|
||
isUpdate = true;
|
||
}
|
||
keyValuePairs[item.groupName.ToString()] = _saveData;
|
||
}
|
||
else if (isSkip && Skip.Contains(item.groupName))
|
||
{
|
||
_saveData = new GuideSaveData();
|
||
_saveData.groupName = item.groupName.ToString();
|
||
_saveData.isFinish = true;
|
||
keyValuePairs[item.groupName.ToString()] = _saveData;
|
||
isUpdate = true;
|
||
}
|
||
}
|
||
GuideSaveDataDic = keyValuePairs;
|
||
if (isUpdate)
|
||
{
|
||
Save();
|
||
}
|
||
}
|
||
if (disposable2 == null)
|
||
{
|
||
disposable2 = GContext.OnEvent<OnEventTriggerGuide>().Subscribe(TriggerGuideNext);
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 查询某引导组是否已走完(非触发入口,供红点/解锁逻辑等读取)。
|
||
/// </summary>
|
||
public bool GetIsFinish(string groupName)
|
||
{
|
||
return GuideSaveDataDic.ContainsKey(groupName) && GuideSaveDataDic[groupName].isFinish;
|
||
}
|
||
/// <summary>
|
||
/// 外部最常用的开组入口:传入配置里与该引导第一步对应的逻辑面板名(如 HomePanel、FishingPanel_Advanced)。
|
||
/// 若当前已在进行中的组且本步 <c>panelName</c> 匹配,会内部调用 <see cref="TriggerGuideNext"/> 推进;
|
||
/// 否则遍历配置,按 <c>GuideTriggerConditions</c> 校验后可能 <see cref="TriggerGuide(GuidanceGroupDefine,string)"/> 开新组。
|
||
/// <paramref name="prePanelName"/> 用于部分条件(如第二根鱼竿、营地相关)排除从首页路径误触;
|
||
/// <paramref name="hostGameObjectName"/> 当前宿主界面根节点的 <c>GameObject.name</c>(可与配置里逻辑面板名不同),写入 <see cref="CurPanelName"/> 供 <see cref="ShowPanel"/> / 引导层查找节点;不需要可留空。
|
||
/// 调用方示例:各 Panel OnEnable、<c>FishingUpdateSys</c>、<c>HomePanel</c>、活动玩法面板等(工程内大量 <c>InspectTriggerGuide("…")</c>)。
|
||
/// </summary>
|
||
public bool InspectTriggerGuide(string panelName, string prePanelName = "", string hostGameObjectName = "")
|
||
{
|
||
if (prePanelName.Contains("FishingRodPanel"))
|
||
{
|
||
return false;
|
||
}
|
||
if (guidanceDefineSetting == null)
|
||
{
|
||
return false;
|
||
}
|
||
if (curGroupDefine != null
|
||
&& GuideSaveDataDic.TryGetValue(curGroupDefine.groupName.ToString(), out var guideSaveData)
|
||
//&& !guideSaveData.isFinish
|
||
&& curGroupDefine.guidanceDefines.Length > guideSaveData.guideSubIndex
|
||
&& panelName == curGroupDefine.guidanceDefines[guideSaveData.guideSubIndex].panelName)
|
||
{
|
||
CurPanelName = hostGameObjectName;
|
||
TriggerGuideNext(new OnEventTriggerGuide(panelName));
|
||
return true;
|
||
}
|
||
PlayerFishData playerFishData = GContext.container.Resolve<PlayerFishData>();
|
||
GuidanceGroupDefine guidanceGroupDefine;
|
||
for (int i = 0; i < guidanceGroupDefines.Length; i++)
|
||
{
|
||
guidanceGroupDefine = guidanceGroupDefines[i];
|
||
|
||
bool isFinish = GetIsFinish(guidanceGroupDefine.groupName.ToString());
|
||
if (isFinish || panelName != guidanceGroupDefine.guidanceDefines[0].panelName)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (CheckTriggerGuideFinish(guidanceGroupDefine))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
int count;
|
||
switch (guidanceGroupDefine.TriggerConditionsType)
|
||
{
|
||
case GuideTriggerConditions.Next:
|
||
break;
|
||
case GuideTriggerConditions.First_login:
|
||
break;
|
||
case GuideTriggerConditions.OpenSystem_Shop:
|
||
if (GContext.container.Resolve<PlayerShopData>().IsShopOpen == false)
|
||
{
|
||
continue;
|
||
}
|
||
break;
|
||
//case GuideTriggerConditions.UnlockSystem_Album:
|
||
// if (GContext.container.Resolve<AlbumData>().theme == null)
|
||
// {
|
||
// continue;
|
||
// }
|
||
// break;
|
||
case GuideTriggerConditions.Level_2:
|
||
if (playerData.lv >= 2)
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.Group_Finish:
|
||
if (GuideSaveDataDic.TryGetValue(guidanceGroupDefine.TriggerConditionsParameter, out var _data) && _data.isFinish)
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.GetDiffFishCount:
|
||
if (int.TryParse(guidanceGroupDefine.TriggerConditionsParameter, out count) && playerFishData.GetDiffFishCount() >= count)
|
||
{
|
||
if (playerFishData.GetDiffFishCount() > count)
|
||
{
|
||
TriggerGuideFinish(guidanceGroupDefine);
|
||
continue;
|
||
}
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.GetFishCount:
|
||
if (int.TryParse(guidanceGroupDefine.TriggerConditionsParameter, out count) && playerFishData.GetAnglingCount() >= count)
|
||
{
|
||
if (playerFishData.GetAnglingCount() > count)
|
||
{
|
||
TriggerGuideFinish(guidanceGroupDefine);
|
||
continue;
|
||
}
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.FirstClickMap_AtMap2:
|
||
if (playerData.lastMapId == _tables.TbMapData.DataList[1].ID)
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.AccountLevel:
|
||
if (int.TryParse(guidanceGroupDefine.TriggerConditionsParameter, out count) && playerData.lv >= count)
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.UnlockSystem:
|
||
if (int.TryParse(guidanceGroupDefine.TriggerConditionsParameter, out count) && GContext.container.Resolve<FishingEventData>().GetSystemOpen(count))
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.UnlockEvent:
|
||
string[] str = guidanceGroupDefine.TriggerConditionsParameter.Split('-');
|
||
if (str.Length == 2)
|
||
{
|
||
if (int.TryParse(str[0], out count) && int.TryParse(str[1], out int count2) && GContext.container.Resolve<FishingEventData>().GetEvent(count, count2) > 0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
else if (str.Length == 3)
|
||
{
|
||
if (int.TryParse(str[0], out count) && int.TryParse(str[1], out int count2) && int.TryParse(str[2], out int count3) && GContext.container.Resolve<FishingEventData>().GetEventRedirectID(count, count2) == count3)
|
||
{
|
||
|
||
break;
|
||
}
|
||
}
|
||
//if (int.TryParse(guidanceGroupDefine.TriggerConditionsParameter, out count) && GContext.container.Resolve<FishingEventData>().GetSystemOpen(count))
|
||
//{
|
||
// break;
|
||
//}
|
||
continue;
|
||
case GuideTriggerConditions.MaxMultiplierCount:
|
||
if (playerData.IsOpenMagnification &&
|
||
int.TryParse(guidanceGroupDefine.TriggerConditionsParameter, out count) &&
|
||
playerData.ContainsOrGreaterRatio(count))
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.GetSecondRod:
|
||
if (!prePanelName.Contains("HomePanel") && playerFishData.IsOpenRod && playerFishData.GetRodAllCount() > 1)
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.RodAscendAvailable:
|
||
if (!prePanelName.Contains("HomePanel") && playerFishData.IsOpenRod && playerFishData.GetRodCanUp())
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.RodUpgradeAvailable:
|
||
if (!prePanelName.Contains("HomePanel") && playerFishData.IsOpenRod && playerFishData.GetRodCanUpLevel())
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.BuyPack:
|
||
if (int.TryParse(guidanceGroupDefine.TriggerConditionsParameter, out count) && GContext.container.Resolve<PlayerShopData>().GetAllPackCount(count) > 0)
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.BoxOpenCondition:
|
||
FishingBoxDataProvier fishingBoxData = GContext.container.Resolve<FishingBoxDataProvier>();
|
||
if (fishingBoxData.IsUnclocked && fishingBoxData.GetBoxCount(fishingBoxData.GetIDByQuality(3)) > 0)
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.GoBuilding:
|
||
if (GContext.container.Resolve<CampDataMM>().GoBuilding())
|
||
{
|
||
break;
|
||
}
|
||
continue;
|
||
case GuideTriggerConditions.GoBuilding02:
|
||
if (playerData.lv >= 12)
|
||
{
|
||
TriggerGuideFinish(guidanceGroupDefine);
|
||
Debug.Log("TriggerGuideFinish(guidanceGroupDefine);");
|
||
continue;
|
||
}
|
||
if (GContext.container.Resolve<CampDataMM>().GoBuilding02(101012))
|
||
{
|
||
Debug.Log("TriggerGuideFinish();");
|
||
break;
|
||
}
|
||
continue;
|
||
default:
|
||
continue;
|
||
}
|
||
|
||
if (curGroupDefine == guidanceGroupDefine)
|
||
{
|
||
return false;
|
||
}
|
||
if (panelName == guidanceGroupDefine.guidanceDefines[0].panelName)
|
||
{
|
||
TriggerGuide(guidanceGroupDefine, hostGameObjectName);
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 业务侧直接将某组标记为已完成并持久化。典型场景:活动面板在条件满足时跳过引导(如药水活动 <c>EventPotionPanel</c>)。
|
||
/// </summary>
|
||
public void MarkGuideFinished(GroupName groupName)
|
||
{
|
||
string key = groupName.ToString();
|
||
if (GetIsFinish(key)) return;
|
||
if (!GuideSaveDataDic.TryGetValue(key, out var saveData))
|
||
{
|
||
saveData = new GuideSaveData();
|
||
saveData.groupName = key;
|
||
GuideSaveDataDic.Add(key, saveData);
|
||
}
|
||
saveData.isFinish = true;
|
||
Save();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 移除某组本地存档(下次可重新触发)。用于活动期重置、调试面板输入组名清除等(如 Smash/Slap 活动 Manager、<c>DeBugPanel</c>)。
|
||
/// </summary>
|
||
public void ClearGuide(string groupName)
|
||
{
|
||
if (GuideSaveDataDic.ContainsKey(groupName))
|
||
{
|
||
GuideSaveDataDic.Remove(groupName);
|
||
Save();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 特殊屏蔽的新手引导:满足条件时直接调用 <see cref="TriggerGuideFinish"/>,避免再弹出。
|
||
/// </summary>
|
||
/// <param name="group"></param>
|
||
bool CheckTriggerGuideFinish(GuidanceGroupDefine group)
|
||
{
|
||
bool isFinishPass = false;
|
||
//判断是否直接完成
|
||
if (group.groupName == GroupName.Chanllenge)
|
||
{
|
||
// isFinishPass = !GContext.container.Resolve<FishingChallengeCenter>().IsFirstOpen;
|
||
}
|
||
|
||
if (isFinishPass)
|
||
{
|
||
TriggerGuideFinish(group);
|
||
}
|
||
return isFinishPass;
|
||
}
|
||
|
||
void TriggerGuideFinish(GuidanceGroupDefine group)
|
||
{
|
||
string groupName = group.groupName.ToString();
|
||
if (!GuideSaveDataDic.TryGetValue(groupName, out var guideSaveData))
|
||
{
|
||
guideSaveData = new GuideSaveData();
|
||
guideSaveData.groupName = groupName;
|
||
GuideSaveDataDic.Add(groupName, guideSaveData);
|
||
}
|
||
guideSaveData.guideSubIndex = group.guidanceDefines.Length;
|
||
guideSaveData.isFinish = true;
|
||
Save();
|
||
}
|
||
/// <summary>
|
||
/// 不按「遍历条件」、直接指定组名开组:<paramref name="guidanceGroupKey"/> 须与配置中 <c>GroupName</c> 字符串一致,<paramref name="panelName"/> 须等于该组第一步的 <c>GuidanceDefine.panelName</c>。
|
||
/// <paramref name="loop"/> 为 false 时若该组已完成则不再触发。
|
||
/// <paramref name="hostGameObjectName"/> 同 <see cref="InspectTriggerGuide"/>:宿主界面 <c>GameObject.name</c>,供引导定位;可空。
|
||
/// 典型调用:<c>CampPanel</c> 固定引导、<c>FishingUpdateSys</c> 鱼逃脱、<c>DataCenter.FishingEventData</c> 事件引导、<c>EventSmashPanel</c>/<c>EventMatchGamePanel</c>/<c>EventCubeMeltPanel</c> 等活动显式开组。
|
||
/// </summary>
|
||
public bool TriggerGuide(string guidanceGroupKey, string panelName, bool loop = true, string hostGameObjectName = "")
|
||
{
|
||
if (guidanceDefineSetting == null)
|
||
{
|
||
return false;
|
||
}
|
||
GuidanceGroupDefine guidanceGroupDefine;
|
||
if (!loop)
|
||
{
|
||
bool isFinish = GetIsFinish(guidanceGroupKey);
|
||
if (isFinish)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
for (int i = 0; i < guidanceGroupDefines.Length; i++)
|
||
{
|
||
guidanceGroupDefine = guidanceGroupDefines[i];
|
||
if (guidanceGroupDefine.groupName.ToString() == guidanceGroupKey)
|
||
{
|
||
if (panelName != guidanceGroupDefine.guidanceDefines[0].panelName)
|
||
{
|
||
return false;
|
||
}
|
||
TriggerGuide(guidanceGroupKey, hostGameObjectName, guidanceGroupDefine);
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
/// <summary>
|
||
/// <see cref="TriggerGuide(string,string,bool,string)"/> 的内部实现:延迟后写入存档、设当前组/步并弹出 <c>GuidancePanel</c>。
|
||
/// </summary>
|
||
async void TriggerGuide(string guidanceGroupKey, string hostGameObjectName, GuidanceGroupDefine guidanceGroupDefine)
|
||
{
|
||
await System.Threading.Tasks.Task.Delay(200);
|
||
curSaveData = new GuideSaveData();
|
||
curSaveData.groupName = guidanceGroupKey;
|
||
GuideSaveDataDic[guidanceGroupKey] = curSaveData;
|
||
curGroupDefine = guidanceGroupDefine;
|
||
curDefine = curGroupDefine.guidanceDefines[0];
|
||
ShowPanel(hostGameObjectName);
|
||
curSaveData.guideSubIndex++;
|
||
}
|
||
/// <summary>
|
||
/// 由 <see cref="InspectTriggerGuide"/> 在条件满足时调用,初始化该组进度并打开引导界面。
|
||
/// </summary>
|
||
void TriggerGuide(GuidanceGroupDefine group, string hostGameObjectName)
|
||
{
|
||
string groupName = group.groupName.ToString();
|
||
if (!GuideSaveDataDic.TryGetValue(groupName, out var guideSaveData))
|
||
{
|
||
guideSaveData = new GuideSaveData();
|
||
guideSaveData.groupName = groupName;
|
||
GuideSaveDataDic.Add(groupName, guideSaveData);
|
||
}
|
||
if (guideSaveData.isFinish)
|
||
{
|
||
return;
|
||
}
|
||
guideSaveData.guideSubIndex = 0;
|
||
curSaveData = guideSaveData;
|
||
|
||
curGroupDefine = group;
|
||
curDefine = group.guidanceDefines[0];
|
||
ShowPanel(hostGameObjectName);
|
||
curSaveData.guideSubIndex++;
|
||
|
||
}
|
||
/// <summary>
|
||
/// 订阅 <c>GContext.OnEvent<OnEventTriggerGuide>()</c>(在 <see cref="Init"/> 中注册)。
|
||
/// 典型发布方:<c>CampPanel</c>、<c>FishingPanel_Advanced</c>、<c>FishingRewardPanel</c>、<c>BuildAct</c>、<c>FishingRodRewardPopupPanel</c> 等在面板打开时 <c>Publish(new OnEventTriggerGuide(GetType().Name))</c>。
|
||
/// 有当前组且 panel 匹配时推进子步骤;否则回退为 <see cref="InspectTriggerGuide"/> 尝试新开组。
|
||
/// </summary>
|
||
public void TriggerGuideNext(OnEventTriggerGuide eventTriggerGuide)
|
||
{
|
||
if (curGroupDefine != null && GuideSaveDataDic.TryGetValue(curGroupDefine.groupName.ToString(), out var guideSaveData))
|
||
{
|
||
if (curGroupDefine.guidanceDefines.Length <= curSaveData.guideSubIndex || eventTriggerGuide.panelName != curGroupDefine.guidanceDefines[guideSaveData.guideSubIndex].panelName)
|
||
{
|
||
return;
|
||
}
|
||
curDefine = curGroupDefine.guidanceDefines[guideSaveData.guideSubIndex];
|
||
if (curDefine.completeType == CompleteType.PanelOpen)
|
||
{
|
||
string uIType = curDefine.completeTypeParameter;
|
||
if (!string.IsNullOrEmpty(uIType) && UIManager.Instance.ContainsUI(uIType))
|
||
{
|
||
curSaveData.guideSubIndex++;
|
||
AddIndex();
|
||
}
|
||
else
|
||
{
|
||
disposable = GContext.OnEvent<GetUIAsyncEvent>().Subscribe(data =>
|
||
{
|
||
if (uIType == data.uIType && data.show)
|
||
{
|
||
curSaveData.guideSubIndex++;
|
||
AddIndex();
|
||
}
|
||
});
|
||
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ShowPanel(CurPanelName);
|
||
curSaveData.guideSubIndex++;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
InspectTriggerGuide(eventTriggerGuide.panelName);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 推进当前引导步骤或结束整组:关闭 <c>GuidancePanel</c>、发布 <c>AddIndexEvent</c>、必要时链式 <see cref="InspectTriggerGuide"/> 接下一组。
|
||
/// 用户点击完成由 <c>GuidancePanel</c> 调用;玩法内跳过/条件达成可传 <paramref name="is_pass"/> 为 true(如 <c>FishingUpdateSys</c>、<c>FishingRewardPanel</c>)。
|
||
/// </summary>
|
||
public void AddIndex(bool is_pass = false)
|
||
{
|
||
if (curDefine == null)
|
||
{
|
||
return;
|
||
}
|
||
if (disposable != null)
|
||
{
|
||
disposable.Dispose();
|
||
disposable = null;
|
||
}
|
||
if (disposable3 != null)
|
||
{
|
||
disposable3.Dispose();
|
||
disposable3 = null;
|
||
}
|
||
UIManager.Instance.HideUI(UITypes.GuidancePanel);
|
||
bool isAutoNext = curDefine.isAutoNext;
|
||
AddIndexEvent addIndexEvent = new AddIndexEvent();
|
||
addIndexEvent.isAutoNext = isAutoNext;
|
||
if (curGroupDefine.guidanceDefines.Length <= curSaveData.guideSubIndex || is_pass)
|
||
{
|
||
#if AGG
|
||
using (var e = GEvent.GameEvent("guide_complete"))
|
||
{
|
||
e.AddContent("guide_id", curGroupDefine.groupName.ToString())
|
||
.AddContent("is_pass", is_pass);
|
||
}
|
||
#endif
|
||
string panelName = curDefine.panelName;
|
||
curDefine = null;
|
||
curGroupDefine = null;
|
||
curSaveData.isFinish = true;
|
||
Save();
|
||
if (isAutoNext)
|
||
{
|
||
InspectTriggerGuide(panelName, panelName);
|
||
}
|
||
GContext.Publish(new ConditionTypeEvent(ConditionType.CompleteGuide, 1));
|
||
addIndexEvent.CompleteGuide = true;
|
||
addIndexEvent.guideSubIndex = curSaveData.guideSubIndex;
|
||
GContext.Publish(addIndexEvent);
|
||
}
|
||
else
|
||
{
|
||
Save();
|
||
var define = curGroupDefine.guidanceDefines[curSaveData.guideSubIndex];
|
||
if (isAutoNext && define.panelName == curDefine.panelName)
|
||
{
|
||
curDefine = define;
|
||
ShowPanel(CurPanelName);
|
||
curSaveData.guideSubIndex++;
|
||
}
|
||
else if (!isAutoNext)
|
||
{
|
||
for (int i = curSaveData.guideSubIndex; i < curGroupDefine.guidanceDefines.Length; i++)
|
||
{
|
||
var _define = curGroupDefine.guidanceDefines[i];
|
||
if (_define.isKey)
|
||
{
|
||
curSaveData.isFinish = false;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
curSaveData.isFinish = true;
|
||
}
|
||
}
|
||
}
|
||
addIndexEvent.guideSubIndex = curSaveData.guideSubIndex;
|
||
GContext.Publish(addIndexEvent);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 显示引导蒙层:按需订阅 <see cref="GuideNextEvent"/>,记录 <see cref="CurPanelName"/> 并打开 <c>GuidancePanel</c>。
|
||
/// </summary>
|
||
async void ShowPanel(string PanelName)
|
||
{
|
||
if (curDefine.fingerType != FingerType.None)
|
||
{
|
||
disposable3 = GContext.OnEvent<GuideNextEvent>().Subscribe(GuideNextEvent);
|
||
}
|
||
CurPanelName = PanelName;
|
||
await UIManager.Instance.ShowUI(UITypes.GuidancePanel);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 打开轻量引导弹层 <c>GuidancePopupPanel</c>(如钓场张力/收线提示节点)。调用方:<c>FishingUpdateSys</c>、<c>GuidancePanel</c> 配置中的 popup。
|
||
/// </summary>
|
||
public async void ShowGuidancePopupPanel(string nodeName)
|
||
{
|
||
popupPanelNode = nodeName;
|
||
if (!string.IsNullOrEmpty(popupPanelNode))
|
||
{
|
||
await UIManager.Instance.ShowUI(UITypes.GuidancePopupPanel);
|
||
UIManager.Instance.HideUI(UITypes.GuidancePanel);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 手指类引导收到 <see cref="GuideNextEvent"/> 后进入下一步(内部订阅,非外部直接调用)。
|
||
/// </summary>
|
||
void GuideNextEvent(GuideNextEvent guideLongEvent)
|
||
{
|
||
if (curDefine != null && curDefine.fingerType != FingerType.None)
|
||
{
|
||
AddIndex();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 判断当前是否正在展示指向 <paramref name="panelName"/> 的引导;若无当前引导会先试 <see cref="InspectTriggerGuide"/>。
|
||
/// 用于玩法逻辑在更新循环里 gate 住交互(如首页、列表等)。
|
||
/// </summary>
|
||
public bool IsGuide(string panelName)
|
||
{
|
||
bool isGuide = curDefine != null;
|
||
if (!isGuide)
|
||
{
|
||
InspectTriggerGuide(panelName);
|
||
}
|
||
return curDefine != null && curDefine.panelName == panelName;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 精确判断当前步:指定组、子步骤索引与面板名(如 <c>FishingUpdateSys</c> 中按 Fish_02 / FishEscape 步显示手指)。
|
||
/// 条件满足时会调用 <see cref="InspectTriggerGuide"/> 尝试补触发。
|
||
/// </summary>
|
||
public bool IsGuide(string panelName, int index, GroupName groupName)
|
||
{
|
||
bool isGuide = curDefine != null;
|
||
|
||
if (isGuide && curGroupDefine.groupName == groupName && curSaveData.guideSubIndex == index)
|
||
{
|
||
InspectTriggerGuide(panelName);
|
||
return true;
|
||
}
|
||
return false;// curDefine != null && curDefine.panelName == panelName;
|
||
}
|
||
/// <summary>
|
||
/// 从持久化字符串恢复 <see cref="GuideSaveDataDic"/>。由 <c>PlayerData</c> 同步云端字段 <c>GuideSaveDataNew</c> 时调用。
|
||
/// </summary>
|
||
public void SetData(string value)
|
||
{
|
||
string[] groupStrings = value.Split(';');
|
||
foreach (var groupString in groupStrings)
|
||
{
|
||
string[] strings = groupString.Split('|');
|
||
if (strings.Length == 3)
|
||
{
|
||
GuideSaveData saveData = new GuideSaveData();
|
||
saveData.groupName = strings[0];
|
||
if (int.TryParse(strings[1], out int guideSubIndex))
|
||
{
|
||
saveData.guideSubIndex = guideSubIndex;
|
||
}
|
||
saveData.isFinish = strings[2] == "1";
|
||
GuideSaveDataDic[saveData.groupName] = saveData;
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 将当前所有组进度写入 PlayFab 用户数据键 <c>GuideSaveDataNew</c>。
|
||
/// </summary>
|
||
public void Save()
|
||
{
|
||
List<string> strings = GuideSaveDataDic.Select(kv => kv.Key + "|" + kv.Value.guideSubIndex + "|" + (kv.Value.isFinish ? "1" : "0")).ToList();
|
||
string value = string.Join(";", strings);
|
||
PlayFabMgr.Instance.UpdateUserDataValue("GuideSaveDataNew", value);
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
disposable?.Dispose();
|
||
disposable = null;
|
||
disposable2?.Dispose();
|
||
disposable2 = null;
|
||
disposable3?.Dispose();
|
||
disposable3 = null;
|
||
}
|
||
}
|
||
}
|