新增元素
新增元素比新增物品更靠近游戏底层。它不仅要有 C# 代码,还要在 elements/custom_elements.yaml 里写物性数据。游戏先从 yaml 读取元素,再由代码给它补贴图、材质、动画和可生成的矿物实体。
这一章用 AuroraCrystal 作为示例,做一个可掉落、可储存的固体元素。
文件结构
MyElementMod/
├── elements/
│ └── custom_elements.yaml
├── assets/
│ └── textures/
│ └── AuroraCrystal.png
├── AuroraCrystalConfig.cs
├── AuroraCrystalSubstancePatch.cs
├── ModElements.cs
└── STRINGS.cscustom_elements.yaml 是关键文件。没有它,ElementLoader 找不到新元素,后面的 C# 都接不上。
定义元素 ID
先把 ID 和 SimHashes 放在一个地方:
namespace MyElementMod
{
public static class ModElements
{
public const string AuroraCrystalId = "AuroraCrystal";
public static readonly SimHashes AuroraCrystal =
(SimHashes)Hash.SDBMLower(AuroraCrystalId);
}
}Hash.SDBMLower() 要和 yaml 里的 elementId 对上。ID 改名时,这两个地方一起改。
写 custom_elements.yaml
---
elements:
- elementId: AuroraCrystal
specificHeatCapacity: 0.5
thermalConductivity: 1.2
solidSurfaceAreaMultiplier: 1
liquidSurfaceAreaMultiplier: 1
gasSurfaceAreaMultiplier: 1
strength: 0.8
highTemp: 1200
highTempTransitionTarget: Magma
defaultTemperature: 290
defaultMass: 200
maxMass: 500
hardness: 20
molarMass: 50
lightAbsorptionFactor: 1
radiationAbsorptionFactor: 0.5
radiationPer1000Mass: 0
materialCategory: BuildableRaw
tags:
- BuildableRaw
buildMenuSort: 2
isDisabled: false
state: Solid
localizationID: STRINGS.ELEMENTS.AURORACRYSTAL.NAME
dlcId: ""先做固体最省心。气体和液体还会牵涉管道颜色、状态转换、相变产物,建议等固体能稳定生成后再扩展。
注册矿物实体
元素本身只是物性,还需要一个可掉落、可储存的实体。固体矿物可以继承 IOreConfig:
using UnityEngine;
namespace MyElementMod
{
public sealed class AuroraCrystalConfig : IOreConfig
{
public SimHashes ElementID => ModElements.AuroraCrystal;
public GameObject CreatePrefab()
{
return EntityTemplates.CreateSolidOreEntity(ElementID, null);
}
}
}当前源码里的 IOreConfig 只需要 ElementID 和 CreatePrefab()。这样游戏就能把 AuroraCrystal 当作一种固体矿物来处理。
补材质和动画
yaml 负责物性,材质通常在 Assets.SubstanceListHookup 后处理。最稳的做法是复制一个原版物质的材质,再替换贴图和颜色:
using HarmonyLib;
using UnityEngine;
namespace MyElementMod
{
[HarmonyPatch(typeof(Assets), "SubstanceListHookup")]
public static class AuroraCrystalSubstancePatch
{
public static void Postfix()
{
Element element = ElementLoader.FindElementByHash(ModElements.AuroraCrystal);
if (element == null || element.substance == null)
{
Debug.LogError("AuroraCrystal was not loaded from custom_elements.yaml");
return;
}
Substance source = Assets.instance.substanceTable.GetSubstance(SimHashes.Granite);
Material material = new Material(source.material)
{
name = "matAuroraCrystal"
};
Color32 color = new Color32(102, 220, 255, 255);
element.substance.material = material;
element.substance.colour = color;
element.substance.uiColour = color;
element.substance.conduitColour = color;
element.substance.anim = source.anim;
}
}
}如果需要自定义贴图,可以读取 assets/textures/AuroraCrystal.png,再赋给 material.mainTexture。先复用花岗岩动画,能少踩很多显示问题。
本地化文本
namespace MyElementMod
{
public static class STRINGS
{
public static class ELEMENTS
{
public static class AURORACRYSTAL
{
public static LocString NAME = "极光晶体";
public static LocString DESC = "一个用于演示新元素注册流程的自定义固体元素。";
}
}
}
}localizationID 对应 STRINGS.ELEMENTS.AURORACRYSTAL.NAME,路径不一致时元素名会显示异常。
常见问题
日志里提示元素没加载,先检查 elements/custom_elements.yaml 有没有打包到 Mod 输出目录。
游戏能启动但元素无贴图,先复用原版 Granite 的 anim 和 material,确认流程通了再换自己的资源。
元素不能作为建筑材料,检查 materialCategory 和 tags。常用的是 BuildableRaw、Metal、RefinedMetal,不要随便写一个游戏不认识的标签。