NinjaFall 重构指南
NinjaFall项目架构重构指南,帮助梳理代码结构
NinjaFall 重构指南
版本:v1.1 | 日期:2026-04-03
? 目录
1. 当前代码问题分析
1.1 GameManager.cs — 职责过重
- 游戏逻辑(1700+行)全在一个文件里
- 表现层和逻辑层完全耦合
- 用
GameObject.FindGameObjectWithTag("Player")获取对象引用(运行时开销大,耦合严重)
1.2 MeunManager.cs — 菜单逻辑耦合
- 武器切换、游戏数据初始化、UI 逻辑、动画控制全混在一起
1.3 静态数据类 GameDataConfig
- 全是
static字段,无法多实例 - 无类型安全,配置和运行时数据混在一起
1.4 缺乏事件系统
组件之间通过直接调用通信,难以新增功能,测试困难。
1.5 数据库直连(已废弃)
原代码直接连接 MySQL,数据库账号密码暴露在客户端代码中(严重安全风险)。Unity 客户端直连数据库架构危险,已被注释掉。
2. 重构目标架构
2.1 核心原则
表现层(处理 Prefab 实例化、动画、UI、音效)
↓ 通过事件驱动
逻辑层(纯 C#,无 Unity 依赖)
↓ 通过接口调用
网络层(只和服务器交互,不接触数据库)
↓
NinjiaServer2 (.NET) 服务器 → MySQL 数据库
2.2 架构图
┌─────────────────────────────────────────────────────┐
│ Presentation Layer │
│ (表现层 - 你配置) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │PlayerView│ │FloorView │ │UIView │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
└───────┼────────────┼────────────┼───────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ Event System │
│ (全局事件调度中心) │
└─────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ Game Systems │
│ (逻辑层 - 纯 C#) │
│ InputSystem | FightSystem | ComboSystem │
│ LifeSystem | ScoreSystem | WeaponSystem │
│ DifficultySystem | GameStateManager │
└─────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ ⭐ Network Service Layer │
│ AuthService | InventoryService | RankingService │
└───────────────────────┬─────────────────────────────┘
│ HTTP / REST API
▼
┌─────────────────┐
│ NinjiaServer2 │ ← 已有 .NET 服务器
│ (.NET / JWT) │
└────────┬────────┘
│ ┌──────────────┐
└────────▶│ MySQL │
└──────────────┘
3. 目录结构设计
Assets/Script/
├── Core/ # 核心框架
│ ├── Event/
│ │ ├── EventDispatcher.cs # 事件调度中心
│ │ └── EventID.cs # 事件 ID 常量
│ └── StateMachine/
│ └── GameStateMachine.cs # 游戏状态机
│
├── Data/ # 数据层
│ ├── WeaponData.cs # 单个武器数据结构
│ ├── WeaponConfig.cs # 武器配置(改造自原文件)
│ ├── GameConfig.cs # 游戏通用配置 + API 地址
│ └── DifficultyTable.cs # 难度表
│
├── System/ # 系统层(纯逻辑,无 Unity 引用)
│ ├── InputSystem.cs # 输入处理
│ ├── FightSystem.cs # 战斗核心
│ ├── ComboSystem.cs # 连击系统
│ ├── LifeSystem.cs # 生命系统
│ ├── ScoreSystem.cs # 分数系统
│ ├── WeaponSystem.cs # 武器系统
│ ├── DifficultySystem.cs # 难度系统
│ └── GameStateManager.cs # 游戏流程管理
│
├── Network/ # ⭐ 网络服务层
│ ├── ApiResponse.cs # 统一响应格式
│ ├── HttpClient.cs # HTTP 工具类
│ ├── AuthService.cs # 登录/注册
│ ├── InventoryService.cs # 背包/物品
│ └── RankingService.cs # 排行榜
│
├── Presentation/ # 表现层接口
│ ├── Interfaces/
│ │ ├── IPlayerView.cs
│ │ ├── IFloorView.cs
│ │ ├── IEnemyView.cs
│ │ ├── IUIView.cs
│ │ └── IAudioView.cs
│
└── Entry/
└── GameEntry.cs
4. 网络服务层设计
4.0 背景:客户端先行,服务端以后再接
服务端(NinjiaServer2)已有完整能力,但本次重构先做本地版,网络层预留接口,以后再接服务端。
参考项目: Ninjiafall2 的网络层架构(GameNetworkManager + NetInventoryManager)作为设计参考。
4.1 两阶段策略
第一阶段(本次重构) 第二阶段(以后接入)
───────────────────── ─────────────────────
本地存档 PlayerPrefs → 网络存档 API
本地登录(跳过/游客) → 对接 NinjiaServer2
本地数据(金币/武器) → InventoryService
本地排行榜 → 真实排行榜
4.2 网络服务层预留设计
参照 Ninjiafall2 的结构:
// GameConfig.cs
public static class GameConfig {
// ⭐ 服务端地址(以后填写)
public static string API_BASE_URL = "http://dapanz.com:8801";
// 是否启用网络(当前为 false)
public static bool NETWORK_ENABLED = false;
}
网络层代码结构(参考 Ninjiafall2):
| 文件 | 说明 |
|---|---|
GameNetworkManager |
HTTP 请求、JWT Token、心跳、单例 |
AuthService |
登录/注册(当前为本地模拟) |
InventoryService |
背包/物品(当前为 PlayerPrefs) |
RankingService |
排行榜(当前为本地) |
设计原则(与 Ninjiafall2 一致):
- 单例模式:
GameNetworkManager.Instance UnityWebRequest+Newtonsoft.Json- JWT Token 认证头:
Authorization: Bearer {token} - 心跳保活机制
- 回调模式:
Action<bool, T, string>
4.3 网络服务层设计(本地优先,预留扩展)
基础配置
// GameConfig.cs
public static class GameConfig {
// ⭐ 服务端地址(以后接网络时填写)
public static string API_BASE_URL = "http://dapanz.com:8801";
// 当前是否启用网络(当前为 false,先做本地版)
public static bool NETWORK_ENABLED = false;
// 网络超时(秒)
public static int NETWORK_TIMEOUT = 10;
}
AuthService — 登录/注册
当前为本地模式(游客/跳过登录),以后接网络时参考 Ninjiafall2 的 GameNetworkManager.Login() 实现。
// 本地实现(当前)
public class AuthService {
public void GuestLogin() { ... } // 游客直接进入
public void LocalLogin(string username) { ... }
}
// 未来网络实现(参考 Ninjiafall2)
public class AuthService {
public IEnumerator Login(string username, string password,
Action<bool, long, string, string> callback) {
// POST /api/user/login
// 参考 GameNetworkManager.Login()
}
}
InventoryService — 背包/物品
当前使用 PlayerPrefs,以后接网络时参考 Ninjiafall2 的 NetInventoryManager。
// 本地实现(当前)
public class InventoryService {
public int Gold {
get => PlayerPrefs.GetInt("gold", 0);
set => PlayerPrefs.SetInt("gold", value);
}
public int Gem {
get => PlayerPrefs.GetInt("gem", 0);
set => PlayerPrefs.SetInt("gem", value);
}
public string OwnWeapons {
get => PlayerPrefs.GetString("ownWeapon", "0");
set => PlayerPrefs.SetString("ownWeapon", value);
}
}
// 未来网络实现(参考 NetInventoryManager)
public class InventoryService {
public void GetInventory(long characterId, Action<InventoryInfo> onSuccess) {
// GET /api/inventory/get/{characterId}
}
public void UseItem(long characterId, int itemId, string itemType, Action onSuccess) {
// POST /api/inventory/use-item
}
}
RankingService — 排行榜
当前为本地排行榜(PlayerPrefs 存储 Top 分数),以后接网络时新增真实排行榜。
// 本地实现(当前)
public class RankingService {
public int TopScore {
get => PlayerPrefs.GetInt("top", 0);
set => PlayerPrefs.SetInt("top", value);
}
public bool SubmitScore(int score) {
if (score > TopScore) { TopScore = score; return true; }
return false;
}
}
// 未来网络实现
public class RankingService {
public IEnumerator SubmitScore(int score, Action<bool, bool, int> callback) {
// POST /api/rank/submit
}
public IEnumerator GetRankList(Action<List<RankItem>> callback) {
// GET /api/rank/list
}
}
4.4 架构扩展说明
当前为纯本地版本,所有数据存 PlayerPrefs。以后接入服务端时:
- 开启
GameConfig.NETWORK_ENABLED = true - 替换各 Service 的本地实现为网络实现
- JWT Token 认证方式与 Ninjiafall2 完全一致
原 Unity 代码中
SqlAccess.cs、DBupload.cs、LoginManager.cs、RankManager.cs全部删除,替换为对接 NinjiaServer2 的网络服务层。
5. 核心系统实现步骤
每个模块由我生成代码文件,你负责导入 Unity 并配置引用。
步骤 1:EventDispatcher(事件调度中心)
事件发布/订阅中心,所有系统通过它通信。
步骤 2:WeaponData + WeaponConfig(数据层)
保持原武器数据不变,改为类型安全的数据结构。
步骤 3:GameConfig + DifficultyTable
从 GameDataConfig.cs 提取,加入 API_BASE_URL 配置。
步骤 4:Network 层
HttpClient.cs— HTTP 工具类(携带 JWT Token)AuthService.cs— 对接/api/user/login/api/user/registerInventoryService.cs— 对接/api/inventory/get/{id}RankingService.cs— 排行榜(服务端暂无,可先本地实现)
步骤 5:InputSystem
从 jarodInputController.cs 提取滑动识别逻辑。
步骤 6:FightSystem
从 GameManager.cs 提取操作判定逻辑。
步骤 7:其他系统(按依赖顺序)
ComboSystem→ 连击计数、冲刺触发LifeSystem→ 生命加减、上限管理ScoreSystem→ 分数计算DifficultySystem→ 难度映射WeaponSystem→ 武器属性加成GameStateManager→ 状态流转GameStateMachine→ Idle/Playing/GameOver
步骤 8:表现层接口(你实现)
IPlayerView→PlayerView.csIFloorView→FloorView.csIUIView→UIView.csIAudioView→AudioView.csIEnemyView→EnemyView.cs
步骤 9:GameEntry(组装)
6. 表现层预留接口说明
6.1 IPlayerView — 玩家表现
public interface IPlayerView {
void PlayJump();
void PlayFall();
void PlayLand();
void PlayHurt();
void PlaySpeedUp();
void SetGravity(float gravity);
void SetPosition(Vector3 position);
Vector3 GetPosition();
}
6.2 IFloorView — 地板表现
public interface IFloorView {
GameObject CreateFloor(Vector3 position);
void DestroyFloor(GameObject floor);
}
6.3 IUIView — UI 表现
public interface IUIView {
void UpdateScore(int score);
void UpdateLife(float current, float max);
void UpdateCombo(int combo, string rankText);
void ShowGameOver(int finalScore);
void ShowComboEffect(string rank);
}
6.4 IAudioView — 音效
public interface IAudioView {
void PlaySFX(string audioKey);
void PlayBGM(string bgmKey);
}
6.5 IEnemyView — 敌人表现
public interface IEnemyView {
void SpawnEnemy(Direction direction, Transform parent);
void DestroyAllEnemies();
}
7. 你的操作步骤
第一阶段:核心框架 ✅ 已完成
| 顺序 | 文件 | 状态 |
|---|---|---|
| 1 | EventDispatcher.cs |
✅ 已生成 |
| 2 | WeaponData.cs |
✅ 已生成 |
| 3 | GameConfig.cs |
✅ 已生成 |
第二阶段:网络服务层 ✅ 已完成
| 顺序 | 文件 | 状态 |
|---|---|---|
| 4 | ApiResponse.cs |
✅ 已生成 |
| 5 | AuthService.cs |
✅ 已生成 |
| 6 | InventoryService.cs |
✅ 已生成 |
| 7 | RankingService.cs |
✅ 已生成 |
第三阶段:系统层
| 顺序 | 文件 |
|---|---|
| 9 | InputSystem.cs |
| 10 | FightSystem.cs |
| 11 | ComboSystem.cs |
| 12 | LifeSystem.cs |
| 13 | ScoreSystem.cs |
| 14 | WeaponSystem.cs |
| 15 | DifficultySystem.cs |
| 16 | GameStateManager.cs |
| 17 | GameStateMachine.cs |
第四阶段:表现层
| 顺序 | 你需要做的事 |
|---|---|
| 18 | 创建 PlayerView.cs,挂到 Player 预制体 |
| 19 | 创建 FloorView.cs,挂到 Entry 对象 |
| 20 | 创建 UIView.cs,挂到 Canvas |
| 21 | 创建 AudioView.cs,挂到 AudioManager |
| 22 | 创建 EnemyView.cs,挂到 Entry 对象 |
第五阶段:组装 + 收尾
| 顺序 | 操作 |
|---|---|
| 23 | GameEntry.cs 拖入场景,配置引用 |
| 24 | 删除旧文件:SqlAccess.cs、DBupload.cs、LoginManager.cs、RankManager.cs |
| 25 | 完整流程测试:登录 → 开始 → 操作 → 死亡 → 结算 |
⏭ 下一步
准备好后回复 "开始",我立即开始生成代码文件 ?
文档生成时间:2026-04-03 作者:小龙 ?
所有内容仅供学习与交流,转载须标明链接。未经同意,禁止作为商业用途,有特殊需求请联系站长。
