> 技术文档 > 新手引导制作

新手引导制作


今日问题总结:一定一定要多去尝试总结问题分析问题,试着从不同的角度方法解决它。一定一定要多思考,相信自己能学会。

1.开始新手对话,点击提示
2.弹出点击背包的点一点提示
3.配置UI界面和对应的n-几,获取UI节点,解决适配问题
4.UIMgr怎么获取 ,在触发的地方广播消息,
5.在UIMgr里面实现新手引导,从表里面获取

根据你的需求,我来告诉你实现新手引导系统的具体步骤:

## 1. 开始新手对话,点击提示

**实现步骤:**
- 在游戏启动时或特定触发点调用新手引导管理器
- 显示对话UI,包含点击提示
- 监听玩家点击事件,点击后进入下一步

**关键代码位置:**
- 在游戏初始化或场景加载完成后触发
- 使用事件系统或直接调用新手引导管理器

## 2. 弹出点击背包的点一点提示

**实现步骤:**
- 在对话完成后,显示背包按钮的高亮提示
- 监听背包按钮的点击事件
- 点击后关闭提示,进入下一步引导

**技术要点:**
- 使用遮罩层或高亮效果突出背包按钮
- 可能需要调整UI层级确保提示在最上层

## 3. 配置UI界面和对应的n-几,获取UI节点,解决适配问题

**实现步骤:**
- 在UI配置表中添加新手引导相关配置
- 配置每个引导步骤对应的UI节点路径(如\"n-1\", \"n-2\"等)
- 实现UI节点查找机制,支持路径解析
- 处理不同分辨率下的UI适配问题

**配置表结构建议:**
```
引导ID | 步骤序号 | UI节点路径 | 提示文本 | 高亮区域 | 下一步ID
```

## 4. UIMgr怎么获取,在触发的地方广播消息

**实现步骤:**
- 在需要触发新手引导的地方(如游戏启动、特定事件)广播消息
- 消息可以包含引导ID、触发条件等信息
- UIMgr监听这些消息并启动对应的新手引导

**消息系统设计:**
- 使用事件系统或消息队列
- 定义新手引导相关的消息类型
- 在合适的时机发送触发消息

## 5. 在UIMgr里面实现新手引导,从表里面获取

**实现步骤:**
- 在UIMgr中创建新手引导管理器
- 从配置表读取新手引导数据
- 实现引导步骤的执行逻辑
- 管理引导状态(开始、进行中、完成、跳过等)

**核心功能:**
- 引导数据加载和解析
- 步骤执行和状态管理
- UI交互监听
- 引导完成后的清理工作

## 整体架构建议

1. **新手引导管理器**:负责整体流程控制
2. **配置系统**:从表读取引导配置
3. **UI交互系统**:处理点击、高亮等交互
4. **事件系统**:处理引导触发和状态变化
5. **适配系统**:处理不同设备的UI适配

这样的设计可以保证新手引导系统的可扩展性和维护性,同时支持复杂的引导流程。

 

基本框架
1.命名空间和引用
2.类继承结构
3.核心方法框架

## GuidePageView 脚本基本框架### 1. **命名空间和引用**

using LubanDatas.Pcri.Config;    // 配置数据using WeiLai.Enum;               // 枚举定义using WeiLai.OldGameWorld;       // 游戏世界核心类using WeiLai.Mgr;                // 管理器类using Vector3 = UnityEngine.Vector3; // Unity向量类型namespace WeiLai.UI              // UI模块命名空间

### 2. **类继承结构**
 

public class GuidePageView : BaseView{    // 继承自 BaseView,说明这是一个UI页面视图类}

### 3. **核心方法框架**

#### **初始化方法**
 

public override void Init(){    base.Init();   // 调用父类初始化    // 可以在这里添加自定义初始化逻辑}

#### **显示方法**
 

public override void Show() {    base.Show();   // 调用父类显示逻辑        var data = GuideMgr.Inst.m_CurGuideData;  // 获取当前引导数据    InitDialogue(data);                       // 初始化对话框}

#### **对话框初始化方法**
 

private void InitDialogue(Guide dialogueData){    // 设置文本内容    m_Panel.ui.GetChild(\"n4\").asTextField.text = dialogueData.GuidText;        // 设置UI大小    var image = m_Panel.ui.GetChild(\"n8\").asGraph;    image.SetSize(dialogueData.GuidUiWith, dialogueData.GuidUiHigh);        // 设置动画效果    var curveCfg = Launch.m_Inst.mOldAnimCurveCfg;    var jobFilDown = CacheObjectMgr.Inst.Fetch();    jobFilDown.InitData(GuideMgr.Inst.m_AmiPos, image, curveCfg.m_DarkCurve);    jobFilDown.Enter();}

```

### 4. **框架特点**

- **继承体系**: 继承自 `BaseView`,遵循UI页面的标准结构
- **生命周期**: 包含 `Init()` 和 `Show()` 两个主要生命周期方法
- **数据驱动**: 通过 `GuideMgr` 获取引导数据
- **UI操作**: 使用 FairyGUI 框架操作UI元素
- **动画系统**: 集成了自定义的动画系统,支持缓动效果
- **对象池**: 使用对象池管理动画任务对象,提高性能

### 5. **依赖关系**
- `BaseView`: 父类,提供基础UI功能
- `GuideMgr`: 引导管理器,提供数据
- `Launch`: 启动类,提供配置
- `CacheObjectMgr`: 对象池管理器
- `OldFGUIGObjectMove`: UI移动动画组件

这个框架遵循了Unity项目中常见的UI页面模式,具有良好的扩展性和维护性。

问题

这个 Tables.cs 脚本是一个由工具自动生成的代码文件,主要用于加载和管理游戏中的各种配置表(Table)。这些配置表通常包含游戏运行时所需的数据,例如角色、物品、关卡、技能等信息。
 

这个 `Tables.cs` 脚本是一个由工具自动生成的代码文件,主要用于加载和管理游戏中的各种配置表(Table)。这些配置表通常包含游戏运行时所需的数据,例如角色、物品、关卡、技能等信息。

### 脚本作用解析:

1. **命名空间与类定义**
 

   namespace LubanDatas.Pcri.Config   {   public partial class Tables

   ```

   - 这个类位于 `LubanDatas.Pcri.Config` 命名空间中。
   - [Tables](file://F:\\GameProject\\WORK\\trunk\\Unity\\FairyGUIJenga\\Assets\\Scripts\\LubanDatas\\Pcri\\Config\\Tables.cs#L13-L102) 是一个 `partial` 类,意味着它的定义可以分布在多个文件中,这通常用于代码生成工具。

2. **属性定义**
 

   public GridTrayTableItem GridTrayTableItem { get; }   public GridDataTableItem GridDataTableItem { get; }

 

   - 每个属性代表一个数据表对象,例如 [GridTrayTableItem](file://F:\\GameProject\\WORK\\trunk\\Unity\\FairyGUIJenga\\Assets\\Scripts\\LubanDatas\\Pcri\\Config\\Tables.cs#L15-L15) 和 [GridDataTableItem](file://F:\\GameProject\\WORK\\trunk\\Unity\\FairyGUIJenga\\Assets\\Scripts\\LubanDatas\\Pcri\\Config\\Tables.cs#L16-L16)。
   - 这些对象通常封装了从数据文件(如 JSON 或二进制)中加载的数据。

3. **构造函数**
 

   public Tables(System.Func loader)

   ```

   - 构造函数接受一个 `loader` 函数作为参数,该函数用于根据字符串名称加载对应的二进制数据(`ByteBuf`)。
   - 在构造函数内部,每个数据表对象都会通过调用 `loader` 来加载自己的数据。

4. **ResolveRef 方法**
 

   private void ResolveRef()

   ```

   - 这个方法用于解析各个数据表之间的引用关系。
   - 例如,[GridTrayTableItem.ResolveRef(this);](file://F:\\GameProject\\WORK\\trunk\\Unity\\FairyGUIJenga\\Assets\\Scripts\\LubanDatas\\Pcri\\Config\\GridTrayTableItem.cs#L40-L46) 会调用 [GridTrayTableItem](file://F:\\GameProject\\WORK\\trunk\\Unity\\FairyGUIJenga\\Assets\\Scripts\\LubanDatas\\Pcri\\Config\\Tables.cs#L15-L15) 的 [ResolveRef](file://F:\\GameProject\\WORK\\trunk\\Unity\\FairyGUIJenga\\Assets\\Scripts\\LubanDatas\\Pcri\\Config\\Tables.cs#L73-L101) 方法,传入当前 [Tables](file://F:\\GameProject\\WORK\\trunk\\Unity\\FairyGUIJenga\\Assets\\Scripts\\LubanDatas\\Pcri\\Config\\Tables.cs#L13-L102) 实例,以便它能够解析与其他表的引用。

### 使用场景

- **数据驱动开发**:通过配置文件(如 JSON)定义游戏数据,然后由代码加载这些数据,实现数据与逻辑的分离。
- **动态配置**:可以在不修改代码的情况下更新游戏内容,例如添加新角色、新道具等。
- **高效加载**:使用 `ByteBuf` 这样的二进制格式进行数据存储和加载,可以提高加载速度和内存效率。

### 总结

这个脚本是游戏数据管理的核心部分,负责加载和解析各种游戏配置表,使得游戏逻辑

Luban学习总结

先逐个解决掉每一个表格是干什么的吧
_beans_.xlsx是一个类似于示例表的样子
_enums_.xlsx是一个枚举类型的表格

_tables_.xlsx是一个

 

 

 m_CurGuideData = DataMgr.Inst.m_ExcelData.GetGuideData(guideId);// 获取指定 ID 的引导数据

这个是从表里面读取数据

 2025.7.19UI设置模式

以这样的形式进行细分
fairyGUI里面的东西你需要进行总结:
 

 功能与模块逻辑解析(核心)
1.StartGuideByld(int guideld)

这是启动引导的主入口,流程如下:
 

🧩 逻辑分解:

  1. 防重启引导:if (_isGuiding) return;

  2. 获取 Excel 中的引导配置数据:GetGuideData(guideId)

  3. 获取骰子组件 dicr = DataMgr.Inst.m_DiceCom

  4. 计算 UI 引导图标位置 m_AmiPos

    • 基于骰子位置 + 中心对齐 - 引导图标宽高实现居中

  5. 打开 GuidePage 页面

🧠 数学推导(坐标计算):

m_AmiPos = new Vector3( dicr.position.x + dicr.width/2 - m_CurGuideData.GuidUiWith/2, dicr.position.y + dicr.height/2 - m_CurGuideData.GuidUiHigh/2, 0);

说明:图标居中 = 元素中心坐标 - 图标的一半尺寸,保证 UI 引导图标浮在正确位置。

2. PropGuide(int guideId)

这和 StartGuideById 类似,但是基于道具栏最后一个道具的位置来计算
 

var prop = OldPropMgr.Inst.GetPropItemByIndex(...).asCom.GetChild(\"n8\");var pos = prop.position;m_AmiPos = prop.parent.LocalToGlobal(pos);

说明:LocalToGlobal() 是 FairyGUI 中将局部坐标转换为舞台全局坐标,便于跨组件精准定位 UI。

然后再次计算位置 → 打开引导页面。

callBack?.Invoke();

\"Null 条件运算符\"(null-conditional operator)它的作用是:只有当 callBack 不为 null 时,才会调用 Invoke() 方法。

等价于

if(callBack != null){ callback.Invocke();}
  • callBack?.Invoke(); 是简洁写法

  • 可以防止 NullReferenceException(空引用异常)

FairyGUI动画获取和使用方法

1. 基本获取方式

// 方式1:从UI面板获取动画var transition = m_Panel.ui.GetTransition(\"动画名称\");// 方式2:从组件获取动画var transition = component.GetTransition(\"动画名称\");// 方式3:从子组件获取动画var transition = m_Panel.ui.GetChild(\"n60\").component.GetTransition(\"动画名称\");

2. 在你的GuidePageView中使用动画

3. 动画播放的多种方式
 

// 基本播放transition.Play();// 播放一次并回调transition.Play(OnAnimationComplete);// 播放指定次数transition.Play(3, 0, OnAnimationComplete);// 播放指定次数,带延迟transition.Play(1, 0.5f, OnAnimationComplete);// 反向播放transition.PlayReverse();// 停止动画transition.Stop();// 暂停动画transition.SetPaused(true);// 恢复动画transition.SetPaused(false);

4. 动画回调函数
 

private void OnAnimationComplete(){ MyLogger.Debug(\"动画播放完成\"); // 在这里执行动画完成后的逻辑}// 或者使用Lambda表达式transition.Play(() => { MyLogger.Debug(\"动画播放完成\"); // 执行后续逻辑});

5. 检查动画状态

if (transition != null){ if (transition.playing) { MyLogger.Debug(\"动画正在播放中\"); } // 获取动画时长 float duration = transition.totalDuration; // 设置动画速度 transition.timeScale = 1.5f; // 1.5倍速}

6. 实际工程中的使用示例
 

// 骰子动画(来自DiceView.cs)m_DiceAnimation = m_Dicecomponent.component.GetTransition(\"t1\");m_DiceAnimation.Play(OnThrowDiceEnd);// 进入动画(来自FaBaoChoiceView.cs)m_Panel.ui.GetTransition(\"enter\").Play();// 关闭动画var trans = m_Panel.ui.GetTransition(\"close\");trans.Play(() => { // 关闭页面 UIMgr.Inst.ClosePage(m_PageInfo);});// 按钮动画var btnAnimation = button.GetTransition(\"button_click\");btnAnimation.Play();

7.错误处理
 

var transition = m_Panel.ui.GetTransition(\"animation_name\");if (transition != null){ transition.Play(OnComplete);}else{ MyLogger.Warning(\"未找到动画: animation_name\");}

7.22 

  1. 彻底理解需求(最容易忽略的一步)
     

  2. 拆分任务 - 像搭积木一样分解

  3. 画流程图或写伪代码(视觉化思考)

  4. 逐个击破 - 从最简单的开始

  5. 调试技巧(新手必备)

    • 打印中间结果:print(f\"当前输入的值是:{input}\")

    • 使用调试器或在线工具(如PythonTutor可视化执行)

    • 常见错误排查:

      • 变量名拼写错误

      • 缩进问题(Python特别要注意)

      • 忘记类型转换(input()默认是字符串)

  6. 优化与重构