文章目录
- 目标
- Excel 解析工具
- 配置文件
- 读取配置文件
- 最终效果
目标
本章主要实现通过 Excel 配置关卡数据, Unity 解析 Excel 生成关卡,实现自动刷新敌人。
Excel 解析工具
在 Unity 中解析 Excel 需要使用 Excel.dll 和 ICSharpCode.SharpZipLib.dll ,这里附上下载链接:Unity 解析Excel工具:Excel.dll 和 ICSharpCode.SharpZipLib.dll。
解压后直接放到Plugins文件夹下即可:
配置文件
用 Excel 写一个配置文件,上面预留两行,左侧预留一列方便后期做填写说明。
读取配置文件
首先根据配置文件写了两个匹配配置文件的类:LevelConfig、EnemyConfig。代码如下:
LevelConfig.cs
using System.Collections.Generic;namespace TDGameDemo.GameLevel{ public class LevelConfig { private string _levelCode; private int _count; private float _cristalHP; private List<EnemyConfig> _enemyConfigs; public string LevelCode { get => _levelCode; set => _levelCode = value; } public int Count { get => _count; set => _count = value; } public float CristalHP { get => _cristalHP; set => _cristalHP = value; } public List<EnemyConfig> EnemyConfigs { get => _enemyConfigs; set => _enemyConfigs = value; } }}
EnemyConfig.cs
using System.Collections;namespace TDGameDemo.GameLevel{ public class EnemyConfig { private int _roundNum; private string _prefabPath; private int _enemyCount; private int _GenInterval; private float _enemyHP; private float _enemyAttack; private float _enemySpeed; public int RoundNum { get => _roundNum; set => _roundNum = value; } public string PrefabPath { get => _prefabPath; set => _prefabPath = value; } public int EnemyCount { get => _enemyCount; set => _enemyCount = value; } public int GenInterval { get => _GenInterval; set => _GenInterval = value; } public float EnemyHP { get => _enemyHP; set => _enemyHP = value; } public float EnemyAttack { get => _enemyAttack; set => _enemyAttack = value; } public float EnemySpeed { get => _enemySpeed; set => _enemySpeed = value; } }}
然后再创建一个 LevelManager 脚本来读取配置,这个 LevelManager 后期将会实现关卡的加载、开始、结束,以及生成敌人等功能。目前代码如下:
LevelManager.cs
using Excel;using System.Collections.Generic;using System.IO;using TDGameDemo.Enemy;using TDGameDemo.Game;using UnityEngine;namespace TDGameDemo.GameLevel{ /// /// 关卡管理器 /// 加载关卡数据、加载场景、生成敌人 /// public class LevelManager : MonoBehaviour { private GameMain _gameMain; private EnemyGenerator _enemyGenerator; public Transform _generatePoint; public Transform _target; private LevelConfig _levelConfig; private int currRound = 0; //private int currEnemyIndex = 0; private float lastEnemyGenTim = 50f; private int genEnemyCount = 0; // Start is called before the first frame update void Start() { _gameMain = GetComponent<GameMain>(); _enemyGenerator = GetComponent<EnemyGenerator>(); } // Update is called once per frame void Update() { //Debug.Log("99999999999999----------" + Time.deltaTime); // 游戏开始,生成敌人 if (_gameMain.GameStart) { // 如果当前为第0回合,证明游戏刚开始 if (currRound == 0) { currRound = 1; } // 累加生成时间 lastEnemyGenTim += Time.deltaTime; // 如果上一个敌人的生成时间大于本轮的生成间隔,则生成新的敌人 if (_levelConfig.EnemyConfigs[currRound - 1].GenInterval < lastEnemyGenTim) { _enemyGenerator.GenerateEnemy( _generatePoint, Level.ENEMY_PREFAB_PREFIX + _levelConfig.EnemyConfigs[currRound - 1].PrefabPath, _target ); // 生成数量+1 genEnemyCount++; // 生成时间重置 lastEnemyGenTim = 0; // 如果生成数量大于等于本轮生成总量,则进行下一轮 if (genEnemyCount >= _levelConfig.EnemyConfigs[currRound - 1].EnemyCount) { currRound++; genEnemyCount = 0; } } } } public void InitLevel(string configPath) { // 创建关卡配置对象 _levelConfig = new LevelConfig(); // 解析Excel FileStream fs = new FileStream(Application.dataPath + configPath, FileMode.Open, FileAccess.Read); // 创建Excel读取类 IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(fs); // 读取 int index = 0; // 移动到第四行 for (; index < 4; index++) { excelReader.Read(); } _levelConfig.LevelCode = excelReader.GetString(1); _levelConfig.Count = excelReader.GetInt32(2); //Debug.Log(_levelConfig.Count + "======================" + _levelConfig.LevelCode); // 跳过空白行和标题行 excelReader.Read(); excelReader.Read(); _levelConfig.EnemyConfigs = new List<EnemyConfig>(); for (; index <= 4 + _levelConfig.Count; index++) { excelReader.Read(); EnemyConfig emConfig = new EnemyConfig(); emConfig.RoundNum = excelReader.GetInt32(1); emConfig.PrefabPath = excelReader.GetString(2); emConfig.EnemyCount = excelReader.GetInt32(3); emConfig.GenInterval = excelReader.GetInt32(4); emConfig.EnemyHP = excelReader.GetFloat(5); emConfig.EnemyAttack = excelReader.GetFloat(6); emConfig.EnemySpeed = excelReader.GetFloat(7); _levelConfig.EnemyConfigs.Add(emConfig); } } }}
GameMain.cs
using TDGameDemo.GameLevel;using UnityEngine;namespace TDGameDemo.Game{ /// /// 游戏主程序 /// 加载关卡、游戏的开始、暂停、通关、失败 /// public class GameMain : MonoBehaviour { private LevelManager _levelManager; private bool gameStart = false; public bool GameStart { get => gameStart; set => gameStart = value; } void Start() { _levelManager = GetComponent<LevelManager>(); _levelManager.InitLevel("/Resources/Level/LevelConfig/Level_1001.xlsx"); } // Update is called once per frame void Update() { // 按 B 键开始游戏 if (Input.GetKeyDown(KeyCode.B)) { GameStart = true; } } }}
附上脚本:
注意,EnemyGeneratePoint 的位置要放在地图上合理的位置上,不然导航将会报错。
最终效果
由于 GIF 大小有限制,只能少生成几个敌人了。前面三个小的是第一轮的,中间两个大的是第二轮的,后面小的是第三轮的。
更多内容请查看总目录【Unity】Unity学习笔记目录整理