2025-05-18 01:04:31 +08:00

333 lines
9.6 KiB
C#

// ***********************************************************************
// Assembly : Unity
// Author : Kimch
// Created :
//
// Last Modified By : Kimch
// Last Modified On :
// ***********************************************************************
// <copyright file= "TutorialProxy" company=""></copyright>
// <summary></summary>
// ***********************************************************************
namespace G
{
using F;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 新手引导管理类
/// </summary>
public sealed partial class TutorialProxy : GameProxy
{
#region Field
/// <summary>
/// 关闭教程
/// </summary>
public bool closeTutorial;
private Dictionary<int, TutorialGroup> _groups;
private Dictionary<int, TutorialStage> _stages;
private Dictionary<int, TutorialAction> _actions;
private Dictionary<int, TutorialCondition> _conditions;
/// <summary>
/// 当前
/// </summary>
private TutorialGroup _currGroup;
/// <summary>
/// 活跃的
/// </summary>
private readonly List<TutorialGroup> _activeGroups = new List<TutorialGroup>();
/// <summary>
/// 已经触发的
/// </summary>
private readonly List<TutorialGroup> _triggeredGroups = new List<TutorialGroup>();
#endregion
#region Property
/// <summary>
/// 当前引导
/// </summary>
public TutorialGroup currTutorial
{
get { return _currGroup; }
}
#endregion
#region Method
/// <summary>
/// 触发条件(驱动)
/// </summary>
/// <param name="condition"></param>
public void TriggerCondition(int condition, int value = 0)
{
if (closeTutorial)
{
return;
}
if (_currGroup != null)
{
_currGroup.currStage.CheckCondition(condition, value);
return;
}
foreach (var group in _activeGroups)
{
if (!group.completed && group.CheckCondition(condition, value))
{
_triggeredGroups.Add(group);
}
}
}
/// <summary>
/// 强制完成
/// </summary>
public void CompleteStage(bool autoNext = false)
{
if (_currGroup != null)
{
_currGroup.CompleteStep();
if (_currGroup.completed)
{
_activeGroups.Remove(_currGroup);
OnGroupCompleted();
_currGroup = null;
}
}
}
/// <summary>
/// 获取指定组
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
internal TutorialGroup GetGroup(int id)
{
_groups.TryGetValue(id, out TutorialGroup result);
return result;
}
/// <summary>
/// 获取指定步
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
internal TutorialStage GetStage(int id)
{
_stages.TryGetValue(id, out TutorialStage result);
return result;
}
/// <summary>
/// 获取指定所有步
/// </summary>
/// <param name="group"></param>
/// <param name="stages"></param>
internal void GetAllStages(int group, List<TutorialStage> stages)
{
foreach (var stage in _stages.Values)
{
if (stage.group == group)
{
stages.Add(stage);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
internal TutorialAction GetAction(int id)
{
_actions.TryGetValue(id, out TutorialAction result);
return result;
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
internal TutorialCondition GetCondition(int id)
{
_conditions.TryGetValue(id, out TutorialCondition result);
return result;
}
private void LoadInternal()
{
//
var conditionItems = ItemProxy.Instance.GetStaticItems<ItemTutorialCondition>();
_conditions = new Dictionary<int, TutorialCondition>(conditionItems.Count);
for (int i = 0; i < conditionItems.Count; i++)
{
var condition = new TutorialCondition(conditionItems[i]);
_conditions.Add(condition.id, condition);
}
//
var actionItems = ItemProxy.Instance.GetStaticItems<ItemTutorialAction>();
_actions = new Dictionary<int, TutorialAction>(actionItems.Count);
for (int i = 0; i < actionItems.Count; i++)
{
var action = new TutorialAction(actionItems[i]);
_actions.Add(action.id, action);
}
//
var stageItems = ItemProxy.Instance.GetStaticItems<ItemTutorialStage>();
_stages = new Dictionary<int, TutorialStage>(stageItems.Count);
for (int i = 0; i < stageItems.Count; i++)
{
var stage = new TutorialStage(stageItems[i]);
_stages.Add(stage.id, stage);
}
//
var groupItems = ItemProxy.Instance.GetStaticItems<ItemTutorialGroup>();
_groups = new Dictionary<int, TutorialGroup>(groupItems.Count);
for (int i = 0; i < groupItems.Count; i++)
{
var group = new TutorialGroup(groupItems[i]);
_groups.Add(group.id, group);
}
}
private void OnGroupTrigger()
{
#if UNITY_EDITOR
Debug.Log("引导触发 " + _currGroup.id + _currGroup.text);
#endif
KStatistics.Instance.ReportGuide(_currGroup.id, _currGroup.text);
}
private void OnGroupCompleted()
{
#if UNITY_EDITOR
Debug.Log("引导结束 " + _currGroup.id + _currGroup.text);
#endif
}
public void SaveStage(TutorialStage stage)
{
//string key = "t_s_" + stage.id;
//PlayerPrefs.SetInt(key, 1);
//PlayerPrefs.Save();
var dataList = ArchiveProxy.Instance.GetIntList(ARCHIVE_KEY_V1);
if (dataList != null)
{
dataList.Clear();
foreach (var kv in _groups)
{
var item = kv.Value;
var stageId = kv.Value.GetCompletedStageId();
if (stageId > 0)
{
dataList.Add(kv.Key);
dataList.Add(stageId);
}
}
ArchiveProxy.Instance.SetIntList(ARCHIVE_KEY_V1, dataList);
}
}
const string ARCHIVE_KEY_V1 = "tutorial_v1";
public void ProcessData(object data)
{
var dataList = ArchiveProxy.Instance.GetIntList(ARCHIVE_KEY_V1);
if (dataList != null && dataList.Count > 0)
{
for (int i = 0; i < dataList.Count; i += 2)
{
int groupId = dataList[i];
int stageId = dataList[i + 1];
var group = GetGroup(groupId);
if (group != null)
{
group.SetCompletedStageId(stageId);
}
}
}
else
{
foreach (var kv in _stages)
{
var key = "t_s_" + kv.Key;
bool complete = PlayerPrefs.HasKey(key);
if (complete)
{
kv.Value.completed = complete;
}
PlayerPrefs.DeleteKey(key);
}
SaveStage(null);
}
_activeGroups.Clear();
foreach (var kv in _groups)
{
var item = kv.Value;
if (item.HasValidStage())
{
_activeGroups.Add(item);
}
}
_activeGroups.Sort((a, b) => a.priority.CompareTo(b.priority));
}
#endregion
#region Unity
public static TutorialProxy Instance;
private void Awake()
{
Instance = this;
gameObject.AddComponent<TutorialTrigger>();
}
public override void LoadCompleted()
{
}
public override void ReadArchive()
{
LoadInternal();
//本地存
ProcessData(null);
}
private void LateUpdate()
{
if (_currGroup == null && _triggeredGroups.Count > 0)
{
_currGroup = _triggeredGroups[0];
_triggeredGroups.RemoveAt(0);
_currGroup.Trigger();
OnGroupTrigger();
}
if (_currGroup != null)
{
_currGroup.OnUpdate();
if (_currGroup.completed)
{
OnGroupCompleted();
_currGroup = null;
}
}
}
#endregion
}
}