【新手引导】 相关

iOS_release
zhangaotian 2024-07-24 19:01:44 +08:00
parent 2d159cf5b7
commit e94cb66e96
26 changed files with 720 additions and 135 deletions

View File

@ -1,5 +1,140 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2241127308194685953
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 358391382599710765}
- component: {fileID: 366020088593063643}
- component: {fileID: 2238330998119226928}
m_Layer: 5
m_Name: Text_Tip
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &358391382599710765
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2241127308194685953}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 945861584490713851}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -10, y: 877}
m_SizeDelta: {x: 800, y: 200}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &366020088593063643
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2241127308194685953}
m_CullTransparentMesh: 1
--- !u!114 &2238330998119226928
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2241127308194685953}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: "\u63D0\u793A\u63D0\u793A\u63D0\u793A\u63D0\u793A\u63D0\u793A"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8ff78e797c9504c05b77b3ed521b84a6, type: 2}
m_sharedMaterial: {fileID: -6578629386010562579, guid: 8ff78e797c9504c05b77b3ed521b84a6,
type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 70
m_fontSizeBase: 70
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &3916596018543283146
GameObject:
m_ObjectHideFlags: 0
@ -33,6 +168,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1141517351566209910}
- {fileID: 358391382599710765}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
@ -61,7 +197,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 2100000, guid: 63e92d9d8beb347159fc3cca727ca5c6, type: 2}
m_Color: {r: 0, g: 0, b: 0, a: 0.42745098}
m_Color: {r: 0, g: 0, b: 0, a: 0.7254902}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
@ -116,7 +252,7 @@ GameObject:
- component: {fileID: 8504618897260208688}
- component: {fileID: 6194795023024327498}
m_Layer: 5
m_Name: Img_finger
m_Name: Img_Finger
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

View File

@ -2,55 +2,67 @@
{
"ID": 101,
"NextID": 102,
"GroupID": 1,
"GuideNote": "点击岛屿",
"GuideDesKey": "Guide_101",
"GuideParams": [
"BuildRoot/Node5/Option1/Normal"
]
"GuideType": 0,
"GuideParams": "BuildRoot/Node5/Option1/Normal",
"GuideCompleteType": 0,
"GuideCompleteParams": ""
},
{
"ID": 102,
"NextID": 103,
"GroupID": 1,
"GuideNote": "更换建造物",
"GuideDesKey": "Guide_102",
"GuideParams": [
"BuildBoot/BuildUIRoot/UIMainBuild/UI_LiuHaiBottom/Build_Bar/Bar_Tip/Scroll View/Viewport/Content/Item2/Img_Item\n"
]
"GuideType": 0,
"GuideParams": "BuildBoot/BuildUIRoot/UIMainBuild/UI_LiuHaiBottom/Build_Bar/Bar_Tip/Scroll View/Viewport/Content/Item2/Img_Item\n",
"GuideCompleteType": 0,
"GuideCompleteParams": ""
},
{
"ID": 103,
"NextID": 104,
"GroupID": 1,
"GuideNote": "点击保存",
"GuideDesKey": "Guide_103",
"GuideParams": [
"BuildBoot/BuildUIRoot/UIMainBuild/UI_LiuHaiBottom/Build_Bar/Btn_Yes"
]
"GuideType": 0,
"GuideParams": "BuildBoot/BuildUIRoot/UIMainBuild/UI_LiuHaiBottom/Build_Bar/Btn_Yes",
"GuideCompleteType": 1,
"GuideCompleteParams": ""
},
{
"ID": 104,
"NextID": 105,
"GroupID": 1,
"GuideNote": "点击泡泡按钮",
"GuideDesKey": "Guide_104",
"GuideParams": [
"BuildRoot/Node1/Btn"
]
"GuideType": 0,
"GuideParams": "BuildRoot/Node1/Btn",
"GuideCompleteType": 0,
"GuideCompleteParams": ""
},
{
"ID": 105,
"NextID": 106,
"GroupID": 1,
"GuideNote": "点击上锁图标",
"GuideDesKey": "Guide_105",
"GuideParams": [
"BuildBoot/BuildUIRoot/UIMainBuild/UI_LiuHaiBottom/Build_Bar/Bar_Tip/Scroll View/Viewport/Content/Item1/Img_Lock"
]
"GuideType": 0,
"GuideParams": "BuildBoot/BuildUIRoot/UIMainBuild/UI_LiuHaiBottom/Build_Bar/Bar_Tip/Scroll View/Viewport/Content/Item1/Img_Lock",
"GuideCompleteType": 0,
"GuideCompleteParams": ""
},
{
"ID": 106,
"NextID": -1,
"GroupID": 1,
"GuideNote": "点击开始游戏",
"GuideDesKey": "Guide_106",
"GuideParams": [
"BuildBoot/BuildUIRoot/UIMainBuild/Build_Tip/Btn_Game"
]
"GuideType": 0,
"GuideParams": "BuildBoot/BuildUIRoot/UIMainBuild/Build_Tip/Btn_Game",
"GuideCompleteType": 2,
"GuideCompleteParams": ""
}
]

View File

@ -33,8 +33,11 @@ namespace Framework.Event
ShowMainUI,
//新手引导
NextGuideStep,
FinishGuide,
GuideMaskStart, //更换遮罩对象
OpenUI,
CloseUI,
EnterGame,
}
}
}

View File

@ -129,6 +129,7 @@ public class BuildBoot : MonoBehaviour
public void Open(Node node, Action<Option> callBack, Action lockCallBack, int reachCondition, int condition)
{
EventManager.Instance.Send(EventManager.EventName.OpenUI);
_optionCallBack = callBack;
_bar.SetActive(true);
_condition.text = string.Format(ConditionText, reachCondition, condition);

View File

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using cfg.Guide;
using Framework.UI;
public class GuideGroup
{
public int GroupID;
public LinkedList<GuideStepBase> GuideSteps = new LinkedList<GuideStepBase>();
public LinkedListNode<GuideStepBase> CurGuideStep;
public int NextGroupGuideID;
public GuideGroup(int groupID, LinkedList<DataGuide> groupData)
{
GroupID = groupID;
NextGroupGuideID = groupData.Last.Value.NextID;
foreach (var data in groupData)
{
var guideStepBase = InitGuideStep(data);
GuideSteps.AddLast(guideStepBase);
}
}
private GuideStepBase InitGuideStep(DataGuide guideData)
{
if (guideData == null) return null;
return guideData.GuideType switch
{
GuideStepType.Click => new GuideClickStep(guideData),
_ => throw new ArgumentOutOfRangeException($"没有实现{guideData.GuideType}类型的引导方法")
};
}
public string GetGuideMaskTarget()
{
return CurGuideStep.Value.GuideCfg.GuideParams;
}
public string GetGuideDesc()
{
var key = CurGuideStep.Value.GuideCfg.GuideDesKey;
return StringManager.Instance.GetTextByKey(key);
}
public bool IsCompleteGroupGuide()
{
return CurGuideStep != null && CurGuideStep == GuideSteps.Last;
}
public void StartGuide()
{
CurGuideStep ??= GuideSteps.First;
DebugUtil.LogError("{0}组进入{1}号引导", GroupID, CurGuideStep.Value.GuideCfg.ID);
CurGuideStep?.Value.StartGuide();
}
public void EndGuide()
{
CurGuideStep.Value.EndGuide();
}
/// <summary>
/// 开启下一个引导
/// </summary>
public void MoveToNextGuide()
{
EndGuide();
DebugUtil.LogError("开启下一个引导");
CurGuideStep = CurGuideStep.Next;
StartGuide();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c8fa38c459d4c422f87bbfe31a815e74
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,80 @@
using System;
using cfg.Guide;
using Framework.Event;
public abstract class GuideCompleteBase
{
private readonly Action _completeAction;
public readonly DataGuide GuideCfg;
protected GuideCompleteBase(DataGuide dataGuide, Action completeCallback)
{
GuideCfg = dataGuide;
_completeAction = completeCallback;
}
public abstract void AddListener();
/// <summary>
/// 移除监听
/// </summary>
public abstract void RemoveListener();
public virtual void Complete()
{
DebugUtil.LogError("完成引导回调");
_completeAction?.Invoke();
}
}
internal sealed class OpenUI : GuideCompleteBase
{
public OpenUI(DataGuide dataGuide, Action completeCallback) : base(dataGuide, completeCallback)
{
}
public override void AddListener()
{
EventManager.Instance.Register(EventManager.EventName.OpenUI, Complete);
}
public override void RemoveListener()
{
EventManager.Instance.Unregister(EventManager.EventName.OpenUI, Complete);
}
}
internal sealed class CloseUI : GuideCompleteBase
{
public CloseUI(DataGuide dataGuide, Action completeCallback) : base(dataGuide, completeCallback)
{
}
public override void AddListener()
{
EventManager.Instance.Register(EventManager.EventName.CloseUI, Complete);
}
public override void RemoveListener()
{
EventManager.Instance.Unregister(EventManager.EventName.CloseUI, Complete);
}
}
internal sealed class EnterGame : GuideCompleteBase
{
public EnterGame(DataGuide dataGuide, Action completeCallback) : base(dataGuide, completeCallback)
{
}
public override void AddListener()
{
EventManager.Instance.Register(EventManager.EventName.EnterGame, Complete);
}
public override void RemoveListener()
{
EventManager.Instance.Unregister(EventManager.EventName.EnterGame, Complete);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e1f9887594f3f4632a51014ee9660ff5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,14 +1,27 @@
using System;
using Framework.Event;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(EventPermeate))]
public class GuideController : MonoBehaviour
{
public GameObject target;
[HideInInspector] public GameObject target;
private static readonly int CenterShader = Shader.PropertyToID("_Center");
private static readonly int SliderShader = Shader.PropertyToID("_Slider");
/// <summary>
/// 提示文字
/// </summary>
private TMP_Text _textTip;
/// <summary>
/// 手指物体
/// </summary>
private GameObject _imgFinger;
/// <summary>
/// 遮罩材质
/// </summary>
@ -41,13 +54,25 @@ public class GuideController : MonoBehaviour
private void Awake()
{
// 获取组件
EventManager.Instance.Register(EventManager.EventName.GuideMaskStart, ChangeTarget);
_material = GetComponent<Image>().material;
_canvas = GameObject.Find("BuildUIRoot").GetComponent<Canvas>();
_imgFinger = transform.Find("Img_Finger").gameObject;
_textTip = transform.Find("Text_Tip").GetComponent<TMP_Text>();
}
private void ChangeTarget()
{
var targetPath = GuideMananger.Instance.GetGuideMaskTarget();
DebugUtil.LogError("更换目标:{0}", targetPath);
target = GameObject.Find(GuideMananger.Instance.GetGuideMaskTarget());
if (string.IsNullOrEmpty(targetPath) || target == null)
return;
// 设置事件透传对象
gameObject.GetComponent<EventPermeate>().target = target.gameObject;
_textTip.text = GuideMananger.Instance.GetGuideDesc();
// 确定目标物体类型并计算遮罩参数
if (target.GetComponent<SpriteRenderer>() != null)
{
@ -71,9 +96,9 @@ public class GuideController : MonoBehaviour
Vector3[] targetCorners = new Vector3[4]
{
targetCenter + new Vector3(-targetExtents.x, -targetExtents.y, 0), // 左下
targetCenter + new Vector3(-targetExtents.x, targetExtents.y, 0), // 左上
targetCenter + new Vector3(targetExtents.x, targetExtents.y, 0), // 右上
targetCenter + new Vector3(targetExtents.x, -targetExtents.y, 0) // 右下
targetCenter + new Vector3(-targetExtents.x, targetExtents.y, 0), // 左上
targetCenter + new Vector3(targetExtents.x, targetExtents.y, 0), // 右上
targetCenter + new Vector3(targetExtents.x, -targetExtents.y, 0) // 右下
};
// 将目标物体的世界坐标转换为Canvas坐标
@ -99,13 +124,15 @@ public class GuideController : MonoBehaviour
private void SetMaskForImage()
{
target.GetComponent<Image>().rectTransform.GetWorldCorners(_corners);
_diameter = Vector2.Distance(WorldToCanvasPos(_canvas, _corners[0]), WorldToCanvasPos(_canvas, _corners[2])) / 2f;
_diameter = Vector2.Distance(WorldToCanvasPos(_canvas, _corners[0]), WorldToCanvasPos(_canvas, _corners[2])) /
2f;
float x = (_corners[0].x + _corners[3].x) / 2f;
float y = (_corners[0].y + _corners[1].y) / 2f;
Vector3 center = new Vector3(x, y, 0f);
RectTransformUtility.ScreenPointToLocalPointInRectangle(_canvas.transform as RectTransform, center, _canvas.GetComponent<Camera>(), out var position);
RectTransformUtility.ScreenPointToLocalPointInRectangle(_canvas.transform as RectTransform, center,
_canvas.GetComponent<Camera>(), out var position);
Vector4 centerVector = new Vector4(position.x, position.y, 0f, 0f);
_material.SetVector(CenterShader, centerVector);
@ -123,6 +150,7 @@ public class GuideController : MonoBehaviour
{
maxDistance = Mathf.Max(Vector3.Distance(WorldToCanvasPos(_canvas, t), referencePoint), maxDistance);
}
return maxDistance;
}
@ -138,7 +166,13 @@ public class GuideController : MonoBehaviour
private Vector2 WorldToCanvasPos(Canvas canvas, Vector3 world)
{
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, world, canvas.GetComponent<Camera>(), out var position);
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, world,
canvas.GetComponent<Camera>(), out var position);
return position;
}
}
private void OnDestroy()
{
EventManager.Instance.Unregister(EventManager.EventName.GuideMaskStart, ChangeTarget);
}
}

View File

@ -1,71 +1,166 @@
using System.Collections.Generic;
using Framework.Event;
using cfg.Guide;
using Cysharp.Threading.Tasks;
using Framework;
using Framework.UI;
using PhxhSDK;
using UnityEngine;
using Constants = Framework.Constants.Constants;
public class GuideMananger : Singlenton<GuideMananger>, IInitable
{
//开始 //创建遮罩 //更新遮罩位置 //结束该引导 //开始下一步引导
/// <summary>
/// 当前引导组ID
/// </summary>
private int _curGuideGroup;
/// <summary>
/// 当前引导ID
/// 引导遮罩UI界面
/// </summary>
public int CurGuideID;
public bool IsGuide;
private GameObject _guideMask;
/// <summary>
/// 引导字典
/// 引导字典
/// </summary>
public Dictionary<int, GuideStep> GuideDic;
private Dictionary<int, GuideGroup> _guideGroups;
public void InitData()
/// <summary>
/// 引导组配置字典
/// </summary>
private Dictionary<int, LinkedList<DataGuide>> _guideData;
/// <summary>
/// 获取引导配置
/// </summary>
public async UniTask InitData()
{
if (!IsGuide) return;
var table = TableManager.Instance.Tables.GuideConfig;
foreach (var guideData in table.DataList)
{
var step = new GuideStep(guideData);
if (!GuideDic.TryAdd(guideData.ID, step))
DebugUtil.LogError("GuideConfig 配置表ID错误");
}
CurGuideID = CurGuideID == 0 ? table.DataList[0].ID : CurGuideID;
StartGuide();
}
private void DoNextStep()
{
if (GuideDic.TryGetValue(CurGuideID, out var step))
{
if (step.NextID > 0)
CurGuideID = step.NextID;
var groupID = guideData.GroupID;
if (_guideData.TryGetValue(groupID, out var groupList))
{
groupList.AddLast(guideData);
}
else
{
//新手引导结束
return;
var list = new LinkedList<DataGuide>();
list.AddLast(guideData);
_guideData.Add(groupID, list);
}
}
StartGuide();
foreach (var data in _guideData)
{
if (!_guideGroups.TryGetValue(data.Key, out var group))
{
_guideGroups.Add(data.Key, new GuideGroup(data.Key, data.Value));
}
}
//TODO读盘得到当前组
if (_curGuideGroup <= 0)
{
_curGuideGroup = table.DataList[0].GroupID;
}
await InitGuideMaskUI();
}
public void StartGuide()
/// <summary>
/// 初始化引导UI
/// </summary>
private async UniTask InitGuideMaskUI()
{
if (GuideDic.TryGetValue(CurGuideID, out var step))
var targetCanvas = UIRoot.Instance.root;
var obj = await AssetManager.Instance.LoadAssetAsync<GameObject>(Constants.GuideMaskObj);
_guideMask = Object.Instantiate(obj, targetCanvas.transform);
_guideMask.SetActive(false);
}
/// <summary>
/// 开关引导界面
/// </summary>
public void SetActiveGuideUI(bool active)
{
_guideMask.SetActive(active);
}
/// <summary>
/// 获取目标路径
/// </summary>
public string GetGuideMaskTarget()
{
if (_guideGroups.TryGetValue(_curGuideGroup, out var group))
{
step.StartGuide();
return group.GetGuideMaskTarget();
}
return null;
}
/// <summary>
/// 获取描述文字
/// </summary>
/// <returns></returns>
public string GetGuideDesc()
{
foreach (var group in _guideGroups)
{
return group.Value.GetGuideDesc();
}
return null;
}
/// <summary>
/// 开始按组引导
/// </summary>
public void StartGroupGuide()
{
if (_guideGroups.TryGetValue(_curGuideGroup, out var guideGroup))
{
guideGroup.StartGuide();
}
}
/// <summary>
/// /结束组内步骤引导
/// </summary>
public void EndGuide(GuideStepBase step)
{
if (_guideGroups.TryGetValue(_curGuideGroup, out var guideGroup))
{
if (step != guideGroup.CurGuideStep.Value)
return;
if (guideGroup.IsCompleteGroupGuide())
{
_curGuideGroup = guideGroup.NextGroupGuideID;
if (!_guideGroups.TryGetValue(_curGuideGroup, out var group))
{
DebugUtil.LogError("完成了所有的引导");
}
else
{
group.StartGuide();
}
}
else
{
guideGroup.MoveToNextGuide();
}
}
}
public void Init()
{
GuideDic = new Dictionary<int, GuideStep>();
EventManager.Instance.Register(EventManager.EventName.NextGuideStep, DoNextStep);
_guideGroups = new Dictionary<int, GuideGroup>();
_guideData = new Dictionary<int, LinkedList<DataGuide>>();
}
public void Release()
{
EventManager.Instance.Unregister(EventManager.EventName.NextGuideStep, DoNextStep);
AssetManager.Instance.Unload(Constants.GuideMaskObj);
}
}

View File

@ -1,78 +1,97 @@
using System;
using cfg.Guide;
using Cysharp.Threading.Tasks;
using Framework.Constants;
using Framework.Event;
using Framework.UI;
using UnityEngine;
public abstract class GuideStepBase
{
public string DescKey;
/// <summary>
/// 引导完成类型
/// </summary>
private GuideCompleteBase _completeBase;
public int NextID;
public readonly DataGuide GuideCfg;
private DataGuide _guideCfg;
private GameObject _guiderMask;
public GuideStepBase(DataGuide guideCfg)
protected GuideStepBase(DataGuide guideCfg)
{
_guideCfg = guideCfg;
if (guideCfg != null)
{
DescKey = guideCfg.GuideDesKey;
}
GuideCfg = guideCfg;
_completeBase = InitGuideStep(guideCfg);
}
private GuideCompleteBase InitGuideStep(DataGuide guideData)
{
if (guideData == null) return null;
return guideData.GuideCompleteType switch
{
StepCompleteType.OpenUI => new OpenUI(guideData, CompleteGuide),
StepCompleteType.CloseUI => new CloseUI(guideData, CompleteGuide),
StepCompleteType.EnterGame => new EnterGame(guideData, CompleteGuide),
_ => throw new ArgumentOutOfRangeException($"没有实现{guideData.GuideCompleteType}类型的完成方法")
};
}
/// <summary>
/// 开始当前引导
/// </summary>
public async void StartGuide()
{
//await UniTask.Delay(1000); // 延迟时间开始
DoBeforeGuide();
SubStartGuide();
}
/// <summary>
/// 引导前操作
/// </summary>
private void DoBeforeGuide()
{
//打开引导界面
GuideMananger.Instance.SetActiveGuideUI(true);
//发送遮罩镂空更改事件
EventManager.Instance.Send(EventManager.EventName.GuideMaskStart);
//开启该引导相关事件
_completeBase.AddListener();
}
/// <summary>
/// 结束当前引导
/// </summary>
public void EndGuide()
{
EventManager.Instance.Send(EventManager.EventName.NextGuideStep);
RemoveListener();
DebugUtil.LogError("结束了{0}引导", GuideCfg.ID);
}
/// <summary>
/// 引导开始之前
/// 完成引导通用回调
/// </summary>
protected async void DoBeforeGuide()
private void CompleteGuide()
{
await UIManager.Instance.OpenWindow(UIConstants.UIGuide);
AddListener();
_completeBase.RemoveListener();
//关闭引导界面
GuideMananger.Instance.SetActiveGuideUI(false);
DebugUtil.LogError("完成{0}引导", GuideCfg.ID);
//结束引导
GuideMananger.Instance.EndGuide(this);
}
protected abstract void AddListener();
/// <summary>
/// 移除监听
/// 子类开始引导
/// </summary>
protected abstract void RemoveListener();
/// <summary>
/// 开始
/// </summary>
protected abstract void DoGuide();
protected abstract void SubStartGuide();
}
public class GuideStep : GuideStepBase
internal sealed class GuideClickStep : GuideStepBase
{
public GuideStep(DataGuide guideCfg) : base(guideCfg)
public GuideClickStep(DataGuide guideCfg) : base(guideCfg)
{
}
protected override void DoGuide()
{
}
protected override void AddListener()
{
}
protected override void RemoveListener()
protected override void SubStartGuide()
{
}
}

View File

@ -111,6 +111,8 @@ namespace Framework.Manager
/// </summary>
public class UserBuildInfo
{
public int GuideStep;
public string BuildData = GlobalConstants.DefaultBuildID;
public Dictionary<string, string> ChooseNodeInfo;

View File

@ -282,7 +282,7 @@ namespace Framework.UI
private void _AllWindowMeta()
{
_WindowMeta(UIConstants.UILoading, UIWindowLayer.Waiting);
_WindowMeta(UIConstants.UITips, UIWindowLayer.PopupTips);
_WindowMeta(UIConstants.UIScore, UIWindowLayer.PopupTips);
@ -292,7 +292,7 @@ namespace Framework.UI
_WindowMeta(UIConstants.UIShop, UIWindowLayer.Normal);
_WindowMeta(UIConstants.UIAdPopUp, UIWindowLayer.Normal);
_WindowMeta(UIConstants.UIStartMain,UIWindowLayer.Normal);
_WindowMeta(UIConstants.UIStartMain, UIWindowLayer.Normal);
_WindowMeta(UIConstants.UIBuyGoods, UIWindowLayer.Normal);
_WindowMeta(UIConstants.UIWinPanel, UIWindowLayer.Normal);
//_WindowMeta(UIConstants.UIMainPanel, UIWindowLayer.Normal);
@ -302,10 +302,11 @@ namespace Framework.UI
_WindowMeta(UIConstants.UILevelPanel, UIWindowLayer.Normal);
_WindowMeta(UIConstants.UILevelSelect, UIWindowLayer.Normal);
_WindowMeta(UIConstants.UISettingPanel, UIWindowLayer.Normal);
_WindowMeta(UIConstants.UIMainPanelBg, UIWindowLayer.BgTop);
_WindowMeta(UIConstants.UILevelBg, UIWindowLayer.BackGround);
_WindowMeta(UIConstants.ImgLoading, UIWindowLayer.BackGround);
_WindowMeta(UIConstants.UIGuide, UIWindowLayer.Normal);
}
private void _WindowMeta(string name, UIWindowLayer windowLayer)

View File

@ -4,6 +4,9 @@ namespace Framework.Constants
{
//User
public const string EmptyUser = "";
//新手引导遮罩预制体
public const string GuideMaskObj = "Assets/Art/UI/Prefab/GuideMask.prefab";
//Score URL
public const string ScoreUrlAndroid = "https://play.google.com/store/apps/details?id=com.phxh.carpentergirl";

View File

@ -20,19 +20,27 @@ public sealed partial class DataGuide : Bright.Config.BeanBase
{
{ if(!_json["ID"].IsNumber) { throw new SerializationException(); } ID = _json["ID"]; }
{ if(!_json["NextID"].IsNumber) { throw new SerializationException(); } NextID = _json["NextID"]; }
{ if(!_json["GroupID"].IsNumber) { throw new SerializationException(); } GroupID = _json["GroupID"]; }
{ if(!_json["GuideNote"].IsString) { throw new SerializationException(); } GuideNote = _json["GuideNote"]; }
{ if(!_json["GuideDesKey"].IsString) { throw new SerializationException(); } GuideDesKey = _json["GuideDesKey"]; }
{ var __json0 = _json["GuideParams"]; if(!__json0.IsArray) { throw new SerializationException(); } int _n0 = __json0.Count; GuideParams = new string[_n0]; int __index0=0; foreach(JSONNode __e0 in __json0.Children) { string __v0; { if(!__e0.IsString) { throw new SerializationException(); } __v0 = __e0; } GuideParams[__index0++] = __v0; } }
{ if(!_json["GuideType"].IsNumber) { throw new SerializationException(); } GuideType = (Guide.GuideStepType)_json["GuideType"].AsInt; }
{ if(!_json["GuideParams"].IsString) { throw new SerializationException(); } GuideParams = _json["GuideParams"]; }
{ if(!_json["GuideCompleteType"].IsNumber) { throw new SerializationException(); } GuideCompleteType = (Guide.StepCompleteType)_json["GuideCompleteType"].AsInt; }
{ if(!_json["GuideCompleteParams"].IsString) { throw new SerializationException(); } GuideCompleteParams = _json["GuideCompleteParams"]; }
PostInit();
}
public DataGuide(int ID, int NextID, string GuideNote, string GuideDesKey, string[] GuideParams )
public DataGuide(int ID, int NextID, int GroupID, string GuideNote, string GuideDesKey, Guide.GuideStepType GuideType, string GuideParams, Guide.StepCompleteType GuideCompleteType, string GuideCompleteParams )
{
this.ID = ID;
this.NextID = NextID;
this.GroupID = GroupID;
this.GuideNote = GuideNote;
this.GuideDesKey = GuideDesKey;
this.GuideType = GuideType;
this.GuideParams = GuideParams;
this.GuideCompleteType = GuideCompleteType;
this.GuideCompleteParams = GuideCompleteParams;
PostInit();
}
@ -50,6 +58,10 @@ public sealed partial class DataGuide : Bright.Config.BeanBase
/// </summary>
public int NextID { get; private set; }
/// <summary>
/// 引导组
/// </summary>
public int GroupID { get; private set; }
/// <summary>
/// 引导注释
/// </summary>
public string GuideNote { get; private set; }
@ -58,9 +70,21 @@ public sealed partial class DataGuide : Bright.Config.BeanBase
/// </summary>
public string GuideDesKey { get; private set; }
/// <summary>
/// 指引类型
/// </summary>
public Guide.GuideStepType GuideType { get; private set; }
/// <summary>
/// 引导参数
/// </summary>
public string[] GuideParams { get; private set; }
public string GuideParams { get; private set; }
/// <summary>
/// 完成类型
/// </summary>
public Guide.StepCompleteType GuideCompleteType { get; private set; }
/// <summary>
/// 引导参数
/// </summary>
public string GuideCompleteParams { get; private set; }
public const int __ID__ = -12685120;
public override int GetTypeId() => __ID__;
@ -79,9 +103,13 @@ public sealed partial class DataGuide : Bright.Config.BeanBase
return "{ "
+ "ID:" + ID + ","
+ "NextID:" + NextID + ","
+ "GroupID:" + GroupID + ","
+ "GuideNote:" + GuideNote + ","
+ "GuideDesKey:" + GuideDesKey + ","
+ "GuideParams:" + Bright.Common.StringUtil.CollectionToString(GuideParams) + ","
+ "GuideType:" + GuideType + ","
+ "GuideParams:" + GuideParams + ","
+ "GuideCompleteType:" + GuideCompleteType + ","
+ "GuideCompleteParams:" + GuideCompleteParams + ","
+ "}";
}

View File

@ -0,0 +1,20 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace cfg.Guide
{
public enum GuideStepType
{
/// <summary>
/// 点击指定物体
/// </summary>
Click = 0,
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3438260776158479aba91e2e200a0c69
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,28 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace cfg.Guide
{
public enum StepCompleteType
{
/// <summary>
/// 打开指定界面
/// </summary>
OpenUI = 0,
/// <summary>
/// 关闭指定界面
/// </summary>
CloseUI = 1,
/// <summary>
/// 进入游戏
/// </summary>
EnterGame = 2,
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0084eb3cc11be49bdb3ba7d01a13a9a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -40,7 +40,8 @@ namespace Gameplay.LoadingExecutor
_destProgress = 80f;
await InitUI();
_destProgress = 90f;
GuideMananger.Instance.InitData();
await GuideMananger.Instance.InitData();
_destProgress = 100f;
}
public GameStartLoadingExecutor(bool stayTuned = false)
@ -65,7 +66,7 @@ namespace Gameplay.LoadingExecutor
var buildConfig = string.Format(Framework.Constants.Constants.BuildConfigPath, buildId);
var buildData = await JsonHelper.LoadFromAddressable<BuildData>(buildConfig);
var reachCondition = LevelSelectManager.Instance.CurPassLevelIndex;
BuildManager.Instance.UpdateReachCondition(reachCondition);
BuildManager.Instance.UpdateReachCondition(reachCondition);
await BuildManager.Instance.Init(buildData, true, buildInfo);
await Addressables.LoadSceneAsync(buildPath).ToUniTask();
}
@ -92,7 +93,6 @@ namespace Gameplay.LoadingExecutor
if (!PlayerPrefs.HasKey(LevelConstants.FirstLaunch))
{
await UIManager.Instance.OpenWindow(UIConstants.UIUserAgreement);
GuideMananger.Instance.IsGuide = true;
}
if (_stayTuned)

View File

@ -22,6 +22,7 @@ namespace Gameplay
_Register<AudioManager>();
_Register<LevelManager>();
_Register<LoginManager>();
_Register<GuideMananger>();
_Register<CameraManager>();
_Register<AppInfoManager>();
_Register<GameStateManager>();

View File

@ -121,6 +121,7 @@ public class UILoginPanelController : UIWindow
}
else if (!_needHideGfx)
{
GuideMananger.Instance.StartGroupGuide();
EventManager.Instance.Send(EventManager.EventName.ShowGfx);
}
}

View File

@ -1,24 +1,26 @@
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Config/Data/ad_adconfig.json,A36B3A44ABABA2DDE095849E3626C9,1094,1721709970689
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Config/Data/guide_guideconfig.json,E1879E5C3D91AEC33EF3857FCBA5AD25,1278,1721709970689
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Config/Data/prop_propconfig.json,7C02F583533F144939CBFF8C7E18473,880,1721709970689
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Config/Data/stringcfg_stringconfig.json,7478C1A5F9A0908094F9D896FF2FF8,8311,1721709970689
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/AD/ADConfig.cs,A4C9CBC6BD55B1C14634FD73C748ACA,1928,1721709970688
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/AD/ADType.cs,F6A7395BDA6D1E7D1EF51E344CB045,603,1721709970688
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/AD/DataAD.cs,7F68864C5AB693111C5C3250967FB782,3417,1721709970688
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/BI/Event.cs,9BC756F4D9E749FBCEF49BF6929557,6506,1721709970689
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/BI/EventFirst.cs,72E992B782D0734B64364E4777CA3B35,2964,1721709970688
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Guide/DataGuide.cs,19884D13C013319AEB148F3FCDB4A054,3037,1721709970688
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Guide/GuideConfig.cs,B1779443C4E6B0FD80A8B0CAE418015,2003,1721709970688
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Prop/DataProp.cs,B1E5165AD7B7B28F863BF25E9581BF7B,4385,1721709970689
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Prop/PropConfig.cs,263DA0E1E0FA37A6401A432E49E8,2040,1721709970688
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Prop/PropType.cs,56DDB93BC3D6491F012DAE849526897,757,1721709970688
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/StringCfg/DataString.cs,1613DCE5B077AE52BB90193DD949348,2327,1721709970688
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/StringCfg/StringConfig.cs,90AC6ED26EAF4A66498B4816B635F47,2080,1721709970688
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Tables.cs,16F3D2F3A20B0D35793F8A5A8194E59,2303,1721709970688
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Config/Data/ad_adconfig.json,A36B3A44ABABA2DDE095849E3626C9,1094,1721811695613
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Config/Data/guide_guideconfig.json,63B89485A4872F16EBBFA12E46DB6E1,1776,1721811695613
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Config/Data/prop_propconfig.json,7C02F583533F144939CBFF8C7E18473,880,1721811695613
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Config/Data/stringcfg_stringconfig.json,7478C1A5F9A0908094F9D896FF2FF8,8311,1721811695613
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/AD/ADConfig.cs,A4C9CBC6BD55B1C14634FD73C748ACA,1928,1721811695613
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/AD/ADType.cs,F6A7395BDA6D1E7D1EF51E344CB045,603,1721811695610
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/AD/DataAD.cs,7F68864C5AB693111C5C3250967FB782,3417,1721811695610
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/BI/Event.cs,9BC756F4D9E749FBCEF49BF6929557,6506,1721811695613
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/BI/EventFirst.cs,72E992B782D0734B64364E4777CA3B35,2964,1721811695610
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Guide/DataGuide.cs,A23BB4F3F93B395441BB83D74E59B6F,4292,1721811695613
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Guide/GuideConfig.cs,B1779443C4E6B0FD80A8B0CAE418015,2003,1721811695613
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Guide/GuideStepType.cs,50DE437238924E2724E493BD449A536,520,1721811695610
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Guide/StepCompleteType.cs,1631A33319C6A46DD2CC7A75A14E7A1,714,1721811695610
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Prop/DataProp.cs,B1E5165AD7B7B28F863BF25E9581BF7B,4385,1721811695613
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Prop/PropConfig.cs,263DA0E1E0FA37A6401A432E49E8,2040,1721811695610
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Prop/PropType.cs,56DDB93BC3D6491F012DAE849526897,757,1721811695610
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/StringCfg/DataString.cs,1613DCE5B077AE52BB90193DD949348,2327,1721811695610
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/StringCfg/StringConfig.cs,90AC6ED26EAF4A66498B4816B635F47,2080,1721811695610
/Users/zhangaotian/UnityProject/Forest_Client/Forest/Assets/Scripts/Gameplay/DataTable/Tables.cs,16F3D2F3A20B0D35793F8A5A8194E59,2303,1721811695610
/Users/zhangaotian/UnityProject/Forest_Client/Tool/Luban/Datas/__beans__.xlsx,FBF2DDFEE7FB39A727F2C3ACA7E228E,11821,1718685908733
/Users/zhangaotian/UnityProject/Forest_Client/Tool/Luban/Datas/__enums__.xlsx,9966F8C0BCDDD717667BB975C9862F80,12651,1718685908733
/Users/zhangaotian/UnityProject/Forest_Client/Tool/Luban/Datas/__enums__.xlsx,FDBFA610442B2325BC92A411FFE96FE8,12591,1721811568624
/Users/zhangaotian/UnityProject/Forest_Client/Tool/Luban/Datas/__tables__.xlsx,CA2D48B6B6FAC5A9F046ACE375EA6A5B,11099,1721709912370
/Users/zhangaotian/UnityProject/Forest_Client/Tool/Luban/Datas/AD.xlsx,C664BD5E7C8E22397FB8CDF12EAED4E,9832,1719548816307
/Users/zhangaotian/UnityProject/Forest_Client/Tool/Luban/Datas/Guide.xlsx,7480A0739C2AFC3CF9276FCCB225366,9981,1721709874970
/Users/zhangaotian/UnityProject/Forest_Client/Tool/Luban/Datas/AD.xlsx,D49DD4C2226B1AED21398727B2144A9,9832,1721801067448
/Users/zhangaotian/UnityProject/Forest_Client/Tool/Luban/Datas/Guide.xlsx,F590D6AF5C7D5B745FF23DB369795E51,10239,1721811687903
/Users/zhangaotian/UnityProject/Forest_Client/Tool/Luban/Datas/Prop.xlsx,518794514E27F37BF9D0B6BA712533A5,10050,1718685908733
/Users/zhangaotian/UnityProject/Forest_Client/Tool/Luban/Datas/StringConfig.xlsx,DF7478D165C035173F51B0BFD0CEA660,13423,1721709916112

Binary file not shown.

Binary file not shown.

Binary file not shown.