Files
MinFt/Client/Assets/Scripts/DataCenter/DataCenter.GuideData.cs
Liubing\LB 3d8d4d18f3 first commit
先修复一下,错误的场景

删除不必要的钓场资产

修复into场景

update:更新meta文件,修复报错

update:修复资源

修复第一章节建造

修复建造第三章

update:删除多余内容

update:更新README.md

update:还原图标

update:更新README

update:更新配置
2026-04-28 02:17:22 +08:00

757 lines
34 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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&lt;OnEventTriggerGuide&gt;()</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;
}
}
}