Files
oniagent/ONIModTutorial/ONIModTutorial-main/csharp-basics.md
2026-05-30 11:00:36 +08:00

78 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🛠️ C# 开发基础ONI Mod 专用)
在编写《缺氧Oxygen Not Included, ONI》Mod 代码之前,你需要掌握一些 **C# 的核心概念**。本篇内容将**专门围绕 ONI Mod 开发中最常见、最实用的语法与结构**展开,避免泛泛而谈。
---
## 📦 一、命名空间与类Namespace & Class
《缺氧》的源码规模非常庞大,因此大量使用 **命名空间namespace** 来对功能进行划分。你的 Mod 代码也应当遵循这一习惯,以避免冲突、提升可维护性。
### ✅ 开始
::: danger 💡 建议
如果不知道什么是 `空间命名namespace` `类名Class` `方法名Method` 是什么的,在这里你就可以止步了,可以花点时间快速了解一下 `C#` ,这会让你后续的开发事半功倍。
:::
* [C# 杂七杂八](./csharp-basics-reference.md)
* [Harmony的小整理](./harmony-reference.md)
* [Harmony官方文档](https://harmony.pardeike.net/articles/patching.html)。
---
---
## 🔧 二、HarmonyPatch精准定位游戏源码
在《缺氧》Mod 开发中,`[HarmonyPatch]` 属性Attribute就像一个**手术定位仪**。它告诉补丁框架:你需要拦截哪个“类”里的哪个“方法”。
### 1. 核心语法:三种定位方式
根据目标方法的复杂程度,你通常会用到以下三种写法:
| 定位类型 | 代码示例 (Attribute) | 适用场景 |
| :--- | :--- | :--- |
| **基础定位** | `[HarmonyPatch(typeof(Db), "Initialize")]` | **最常用**。目标类中只有一个同名方法时使用。 |
| **重载定位** | `[HarmonyPatch(typeof(Assets), "GetSprite", new Type[] { typeof(HashedString) })]` | 当方法有**多个重载**(名字相同但参数不同)时,必须指定参数类型。 |
| **属性定位** | `[HarmonyPatch(typeof(BuildingDef), "IsSolid", MethodType.Getter)]` | 专门用于拦截 C# 的 **属性 (Property)**。需指定是修改 `Getter` 还是 `Setter`。 |
---
### 2. 🔍 实战:如何从 dnSpy 提取 Patch 信息?
当你使用 **dnSpy** 查看游戏源码 `Assembly-CSharp.dll` 时,请按照以下逻辑进行拆解:
* **类名 (Class)**:看代码最顶层的 `public class` 后面跟着的单词。
* 源码:`public class GeneratedBuildings`
* 对应参数:**`typeof(GeneratedBuildings)`**
* **方法名 (Method)**:看括号左边的那个单词。
* 源码:`public static void LoadGeneratedBuildings(...)`
* 对应参数:**`"LoadGeneratedBuildings"`**
* **参数类型 (Parameters)**:看括号里面的内容,如果是[重载](./harmony-reference.md#postfix-Overloading)方法则需要提取。
* 源码:`(ICollection<Type> types)`
* 对应参数:**`new Type[] { typeof(ICollection<Type>) }`**
---
### 3. 📝 标准代码结构模板
```csharp
using HarmonyLib; // 必须引用 Harmony 库
using UnityEngine; // 如果用到 Debug.Log 或 GameObject
namespace MyOniMod
{
// 1. 定位:我们要改哪个类的哪个方法?
[HarmonyPatch(typeof(EntityConfigManager), "LoadGeneratedEntities")]
public class MyEntityPatch
{
// 2. 注入在原方法执行后Postfix做点什么
public static void Postfix()
{
// 你的逻辑代码
Debug.Log("ONI Mod: 游戏实体加载完成!");
}
}
}