ReadData

7 阅读3分钟

概述(Overview)

ReadData 是一个用于 从 Resources 中的 TextAsset(.txt 文件)读取结构化数据的 MonoBehaviour,位于 PFGameFramework.Library 命名空间。

主要功能:

  • 从制表符(Tab)分隔的文本文件中读取多列数据
  • 支持多种数据结构映射(NumberInfo、NumberValue、DemoInfo 等)
  • 将读取的数据填充到列表或字典中
  • 提供多种读取方式,适应不同业务场景(步骤说明、数值配置、按钮对应答案等)
  • 部分方法带有编辑器按钮(Odin Inspector),方便开发时快速测试

适用场景

  • 配置表读取(无需 Excel 或 ScriptableObject)
  • 实验/教学步骤说明
  • 按钮与答案/参数的对应关系
  • 简单的数据驱动 UI(如负荷、功率、电压等级等)

依赖

  • UnityEngine.Resources
  • System.Linq(Split、Skip、ToList、ForEach 等)
  • 可选:Odin Inspector(编辑器按钮)
  • 可选:自定义扩展 StringExtension.ToInt

数据结构

NumberInfo

[Serializable]
public class NumberInfo
{
    public string title;     // 标题
    public string step;      // 步骤
    public string num;       // 编号
    public string content;   // 内容
}

典型用途:步骤说明、实验指导文本

Info

[Serializable]
public class Info
{
    public int num;      // 编号
    public string step;  // 步骤
}

用途:简化的编号-步骤映射

NumberValue(简单数值示例)

[Serializable]
public class NumberValue
{
    [SerializeField] public int sed;    // 秒
    [SerializeField] public int min;    // 分
    [SerializeField] public float hour; // 小时
}

用途:时间或简单数值配置

DemoInfo(复杂业务示例)

[Serializable]
public class DemoInfo
{
    public string btnName;          // 按钮名称(园区名称)
    public Button button;           // 对应的 Button 组件
    public Text fuheText;           // 负荷名称显示文本
    public InputField fuheIP;       // 最大负荷输入框
    public InputField yinsuIP;      // 功率因素输入框
    public Text distanceText;       // 供电距离文本
    public Dropdown dyDP;           // 电压等级下拉框
    public Dropdown jibieDP;        // 负荷级别下拉框
    public Dropdown numberDP;       // 线路数量下拉框
    public bool clicked;            // 是否已输入信息
    public string fuheName;         // 负荷名称(答案)
    public float fuhe1, fuhe2;      // 负荷答案 1/2
    public float gonglv1, gonglv2;  // 功率答案 1/2
    public float gongdianDis;       // 供电距离
    public string dyDJ;             // 电压等级
    public string fuheJB;           // 负荷级别
    public string xianluNum;        // 线路数量
}

用途:按钮与答案/参数的完整映射,常用于电力/工程类交互题


核心方法

ReadTxtByText(NumberInfo 版本)

private static void ReadTxtByText(ICollection<NumberInfo> numberValues, string assetName)

功能

  • 清空目标列表
  • 读取 Resources 中的 TextAsset
  • 跳过第一行(标题行)
  • 按行分割(Tab 分隔)
  • 映射到 NumberInfo(title, step, num, content)
  • 添加到列表

文件格式示例(.txt):

标题	步骤	编号	内容
步骤1	操作说明	1	请点击按钮A
步骤2	确认结果	2	观察变化

调用方式

ReadTxtByText(numberValues, "Data/StepsConfig");

ReadInfo(字典版本)

public static void ReadInfo(SerializableDictionary<int, string> infos, string assetName)

功能

  • 清空字典
  • 读取 TextAsset
  • 跳过第一行
  • 第一列转为 int(使用 StringExtension.ToInt)
  • 第二列作为值
  • 添加到字典(key: int, value: string)

文件格式示例

1	第一步说明
2	第二步操作

ReadTxtByText(NumberValue 版本)

private void ReadTxtByText()

功能

  • 读取 assetName 指定的 TextAsset
  • 每行三列:秒(int)、分(int)、小时(float)
  • 映射到 NumberValue
  • 添加到 numbers 列表

文件格式

10	5	1.5
20	10	2.0

GetData(DemoInfo 版本)

private void GetData()

功能

  • 清空 demoInfos 列表
  • 读取 TextAsset(* 分隔)
  • 将每行解析为元组
  • 转为 fuheName → 整行数据 的字典
  • 获取 rootBtn 下所有 Button
  • 为每个按钮创建 DemoInfo,绑定 UI 组件和答案数据
  • 添加到 demoInfos

文件格式示例(* 分隔):

园区A*负荷A*1200*1300*0.85*0.9*5.2*10kV*一级*3
园区B*负荷B*800*900*0.92*0.95*3.8*6kV*二级*2

注意:硬编码了大量 GameObject.Find,生产环境建议改为引用或配置。


编辑器辅助

#if UNITY_EDITOR
    [Sirenix.OdinInspector.Button("获取数据")]
    private void Read1()
    {
        ReadTxtByText(numberValues, "");
    }
#endif

功能:在 Odin Inspector 中显示“获取数据”按钮,点击后调用读取方法(assetName 需手动填入)。


-   支持 CSV 解析(更标准)
-   支持泛型读取(一行代码映射任意类)
-   支持异步读取(大文件)
-   支持热更新配置(Addressables)