找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 129|回复: 0

如何将Excel表格配置到unity中

[复制链接]

36

主题

3

回帖

385

积分

管理员

积分
385
发表于 2026-7-5 08:49:00 | 显示全部楼层 |阅读模式
    如果你已经有了一份英雄技能配置的 Excel 表,那么我们要做的就是把这份表格数据变成 Unity 项目中可以直接使用的配置信息。最专业且高效的做法是在 Unity 编辑器中,通过脚本将 Excel 数据生成 ScriptableObject 资产。这样你就不用每次在运行时解析 Excel,性能更好,策划修改表格后也只需在 Unity 里点一个按钮“刷新”即可。

   🎯 目标
有一份 Excel 表格,包含多个英雄及其技能信息。

  在 Unity 中一键生成对应的 ScriptableObject 配置资产。

游戏运行时直接加载这些资产,读取所有英雄和技能数据,用于游戏逻辑。

📁 Excel 表格结构设计
我们假设有两个表(两个 Sheet)或一个表包含所有字段,为了方便管理,推荐使用两个独立的 Excel 文件或同一个文件的多个 Sheet:

1. Hero.xlsx(英雄基础信息)
HeroID        HeroName        Skill1ID        Skill2ID        Skill3ID        Skill4ID
101        盖伦        1011        1012        1013        1014
102        艾希        1021        1022        1023        1024
2. Skill.xlsx(技能详情)
SkillID        SkillName        Description        Damage        Cooldown        IconPath
1011        致命打击        下次攻击...        30        8        Icons/Garen_Q
1012        勇气        被动...        0        0        Icons/Garen_W
...        ...        ...        ...        ...        ...
注意:IconPath 可以是资源路径,如 Sprites/Skills/Q。

🧱 第一步:在 Unity 中定义数据类(ScriptableObject)
创建两个脚本,分别表示英雄和技能的数据结构。

csharp
// SkillData.cs
using UnityEngine;

[CreateAssetMenu(fileName = "SkillData", menuName = "GameConfig/SkillData")]
public class SkillData : ScriptableObject
{
    public int skillID;
    public string skillName;
    public string description;
    public int damage;
    public float cooldown;
    public string iconPath;   // 或者用 Sprite 引用,这里用路径便于动态加载
}
csharp
// HeroData.cs
using UnityEngine;
using System.Collections.Generic;

[CreateAssetMenu(fileName = "HeroData", menuName = "GameConfig/HeroData")]
public class HeroData : ScriptableObject
{
    public int heroID;
    public string heroName;
    public List<SkillData> skillList = new List<SkillData>(); // 直接引用技能资产
}
这里使用 List<SkillData> 直接引用,而不是存 ID,这样在 Inspector 中能直接拖拽关联,更方便调试。

🔧 第二步:编写 Excel 导入编辑器脚本
创建一个编辑器脚本(放在 Editor 文件夹下),实现读取 Excel 并生成 ScriptableObject 资产的功能。

csharp
// ExcelToConfigImporter.cs
using OfficeOpenXml;         // 需要导入 EPPlus (4.5.3.3 免费版)
using System.IO;
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

public class ExcelToConfigImporter : EditorWindow
{
    [MenuItem("Tools/Import Excel Configs")]
    public static void ShowWindow()
    {
        GetWindow<ExcelToConfigImporter>("导入配置");
    }

    private void OnGUI()
    {
        if (GUILayout.Button("从 Excel 生成配置"))
        {
            ImportFromExcel();
        }
    }

    private void ImportFromExcel()
    {
        // 假设 Excel 文件放在 Assets/StreamingAssets/Configs/ 下(也可自定义)
        string excelFolder = Application.dataPath + "/StreamingAssets/Configs/";
        string heroFilePath = excelFolder + "Hero.xlsx";
        string skillFilePath = excelFolder + "Skill.xlsx";

        // 1. 读取技能表,构建 SkillID -> SkillData 的映射(先创建技能资产)
        Dictionary<int, SkillData> skillDict = new Dictionary<int, SkillData>();
        using (var package = new ExcelPackage(new FileInfo(skillFilePath)))
        {
            ExcelWorksheet sheet = package.Workbook.Worksheets[0]; // 第一个 sheet
            int rowCount = sheet.Dimension.Rows;
            for (int row = 2; row <= rowCount; row++) // 跳过标题行
            {
                int id = sheet.Cells[row, 1].GetValue<int>();
                string name = sheet.Cells[row, 2].GetValue<string>();
                string desc = sheet.Cells[row, 3].GetValue<string>();
                int damage = sheet.Cells[row, 4].GetValue<int>();
                float cd = sheet.Cells[row, 5].GetValue<float>();
                string icon = sheet.Cells[row, 6].GetValue<string>();

                // 创建 SkillData 资产
                SkillData skill = ScriptableObject.CreateInstance<SkillData>();
                skill.skillID = id;
                skill.skillName = name;
                skill.description = desc;
                skill.damage = damage;
                skill.cooldown = cd;
                skill.iconPath = icon;

                // 保存为资产文件
                string assetPath = $"Assets/Resources/Configs/Skills/Skill_{id}.asset";
                AssetDatabase.CreateAsset(skill, assetPath);
                AssetDatabase.SaveAssets();

                skillDict[id] = skill; // 存入字典供后续英雄引用
            }
        }
        Debug.Log($"技能数据导入完成,共 {skillDict.Count} 个技能");

        // 2. 读取英雄表,创建 HeroData 并引用对应的技能资产
        using (var package = new ExcelPackage(new FileInfo(heroFilePath)))
        {
            ExcelWorksheet sheet = package.Workbook.Worksheets[0];
            int rowCount = sheet.Dimension.Rows;
            for (int row = 2; row <= rowCount; row++)
            {
                int heroId = sheet.Cells[row, 1].GetValue<int>();
                string heroName = sheet.Cells[row, 2].GetValue<string>();
                int skill1Id = sheet.Cells[row, 3].GetValue<int>();
                int skill2Id = sheet.Cells[row, 4].GetValue<int>();
                int skill3Id = sheet.Cells[row, 5].GetValue<int>();
                int skill4Id = sheet.Cells[row, 6].GetValue<int>();

                HeroData hero = ScriptableObject.CreateInstance<HeroData>();
                hero.heroID = heroId;
                hero.heroName = heroName;
                // 从字典中获取技能资产并添加到列表
                hero.skillList.Add(skillDict[skill1Id]);
                hero.skillList.Add(skillDict[skill2Id]);
                hero.skillList.Add(skillDict[skill3Id]);
                hero.skillList.Add(skillDict[skill4Id]);

                string assetPath = $"Assets/Resources/Configs/Heroes/Hero_{heroId}.asset";
                AssetDatabase.CreateAsset(hero, assetPath);
                AssetDatabase.SaveAssets();
            }
        }
        Debug.Log("英雄配置导入完成!");
        AssetDatabase.Refresh();
    }
}
📂 文件夹结构建议
Assets/StreamingAssets/Configs/ 存放 Excel 文件(方便修改)

Assets/Resources/Configs/Skills/ 存放生成的技能资产

Assets/Resources/Configs/Heroes/ 存放生成的英雄资产

使用 Resources 文件夹是为了方便运行时用 Resources.Load 加载。你也可以改用 Addressables 进行更细粒度的资源管理。

🕹️ 第三步:在游戏运行时加载配置
在游戏中,你可以通过一个管理类来加载所有英雄数据,例如:

csharp
using UnityEngine;
using System.Collections.Generic;

public class ConfigManager : MonoBehaviour
{
    public static ConfigManager Instance { get; private set; }

    private Dictionary<int, HeroData> heroDict = new Dictionary<int, HeroData>();

    void Awake()
    {
        Instance = this;
        LoadAllHeroes();
    }

    void LoadAllHeroes()
    {
        // 方式1:直接加载所有英雄资产(如果你知道它们的命名规则)
        HeroData[] heroes = Resources.LoadAll<HeroData>("Configs/Heroes");
        foreach (var h in heroes)
        {
            heroDict[h.heroID] = h;
        }
        Debug.Log($"加载了 {heroDict.Count} 个英雄");
    }

    public HeroData GetHero(int id)
    {
        heroDict.TryGetValue(id, out HeroData hero);
        return hero;
    }
}
在游戏逻辑中,你可以这样使用:

csharp
HeroData garen = ConfigManager.Instance.GetHero(101);
foreach (SkillData skill in garen.skillList)
{
    Debug.Log($"{skill.skillName} - 伤害:{skill.damage}");
}
🔁 工作流总结
策划维护 Excel:在 StreamingAssets/Configs/ 中修改英雄和技能表。

开发者一键导入:在 Unity 编辑器菜单中点击 Tools/Import Excel Configs。

编辑器脚本自动生成 ScriptableObject 资产,覆盖旧的资产。

游戏运行时加载这些资产,直接使用强类型数据,无需解析 Excel。

🧠 进阶优化建议
增量导入:可以只更新被修改的资产,而不是全部重建,需要记录每个数据的最后修改时间。

使用 Addressable:将配置资产作为 Addressable 资源,实现热更新。

支持多个 Sheet:如果所有数据在一个 Excel 的不同 Sheet 中,你可以通过 package.Workbook.Worksheets["Hero"] 按名称获取。

错误处理:对 Excel 中的空值、类型不匹配等进行健壮校验,避免导入失败。

⚠️ 注意事项
EPPlus 许可证:EPPlus 5.0+ 商业使用需付费,请使用 4.5.3.3 及以下版本(NuGet 可下载)。

文件路径:Application.dataPath 在编辑器中有效,打包后不要依赖此路径(我们只是在编辑器中使用,所以安全)。

资源刷新:AssetDatabase.Refresh() 会刷新工程,确保新资产显示在 Project 窗口。

🏆 总结
通过将 Excel 配置转化为 ScriptableObject 资产,你的游戏将获得:

编辑器友好:策划能直观地在 Unity 中查看、修改配置(即使不改 Excel)。

运行时高性能:直接读取内存中的对象,无需 I/O 或解析。

工作流清晰:策划改 Excel → 点击导入 → 完成,无需程序员介入。

这就是专业团队处理游戏配置的常用方式。祝你开发顺利!🎮

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|游戏黄埔游戏开发 ( 豫ICP备2024088136号-1|豫公网安备41040202000275号 )

GMT+8, 2026-9-28 22:59 , Processed in 0.048335 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表