Skip to content

验证环境

本页示例已使用 Build 740622 对应的本机 Managed DLL 完成编译检查;尚未在游戏内完成运行验证。

新增物品与食物

物品是最适合入门的实体:它可以掉在地上、被拾取、被储存,也可以继续扩展成食物、材料、装备或带自定义逻辑的特殊道具。

这一章对应 examples/ItemAndFood/ 示例项目。示例里有两个重点:

  • ItemConfig:普通掉落物。
  • FoodConfig:可以吃的食物。

文件结构

text
ItemAndFood/
├── ItemAndFood.csproj
├── Mod.cs
├── ItemConfig.cs
├── FoodConfig.cs
├── STRINGS.cs
├── mod.yaml
└── mod_info.yaml

示例项目复用了游戏内已有的 squirrel_kanim 动画,因此不需要额外提交动画资源。发布自己的实体时,应把动画和其他资源一起复制到 Mod 输出目录。

推荐的实现顺序

先做普通物品,再扩展成食物:

  1. 给物品确定唯一 ID 和默认文本。
  2. CreateLooseEntity() 创建能掉落、能拾取的实体。
  3. 在调试菜单中生成它,确认动画、质量和储存标签正确。
  4. 再用 ExtendEntityToFood() 增加食物数据。
  5. 最后接入配方和本地化文件。

物品能生成但配方找不到,通常不是实体配置的问题,而是配方中的输入、输出 Tag 没有分别匹配对应实体的 PrefabTag。先把两个问题分开测试。

基础物品

ItemConfig.cs 负责注册普通掉落物。完整可编译示例位于 examples/ItemAndFood/ItemConfig.cs

csharp
using System.Collections.Generic;
using UnityEngine;

namespace ONITutorial.ItemAndFood
{
    public sealed class ItemConfig : IEntityConfig
    {
        public const string ID = "ONITutorialItem";

        public GameObject CreatePrefab()
        {
            GameObject go = EntityTemplates.CreateLooseEntity(
                ID,
                global::ONITutorial.ItemAndFood.STRINGS.ITEM.NAME,
                global::ONITutorial.ItemAndFood.STRINGS.ITEM.DESC,
                5f,
                true,
                Assets.GetAnim("squirrel_kanim"),
                "object",
                Grid.SceneLayer.Front,
                EntityTemplates.CollisionShape.RECTANGLE,
                0.6f,
                0.6f,
                true,
                0,
                SimHashes.Creature,
                new List<Tag> { GameTags.IndustrialIngredient });

            return go;
        }

        public void OnPrefabInit(GameObject inst) { }
        public void OnSpawn(GameObject inst) { }

    }
}

CreateLooseEntity() 里几个参数最容易写错:

  • ID:全局唯一,后面找预制体、配方、储存过滤都会用它。
  • mass:物品质量,单位是千克。
  • Assets.GetAnim():动画文件名,要带 _kanim
  • "object":动画状态名。掉落物通常用这个。
  • SimHashes.Creature:实体的默认元素。很多非材料类掉落物都会先用它。
  • GameTags.IndustrialIngredient:决定它能被哪些储存、配方或建筑识别。

示例不声明 DLC 限制,因此不实现 GetDlcIds()。如果内容只适用于特定 DLC,应使用当前 DLL 的 IHasDlcRestrictions 接口声明 GetRequiredDlcIds()GetForbiddenDlcIds()

示例里的 ItemConfigFoodConfig 是两个独立的 IEntityConfig。修改其中一个时,不要忘记同步 STRINGS.cs.csproj<Compile Include>

自定义组件

如果物品需要额外行为,可以在 CreatePrefab() 中通过 AddOrGet<T>() 添加自定义 KMonoBehaviour。组件应单独放在示例项目中,并针对当前 DLL 编译后再写入教程;本页的最小示例暂不添加额外组件。

Buff 扩展

Buff 注册涉及 EffectAttributeModifierModifierSet 的组合。当前示例项目先聚焦于物品和食物实体,不提供未经当前 DLL 编译验证的 Buff 代码;需要添加 Buff 时,应以本机 DLL 的构造函数和 Db.Initialize 生命周期重新建立独立示例。

Mod 入口

Mod 入口和统一的本地化初始化流程见 examples/ItemAndFood/Mod.cs本地化示例。如果项目包含自定义 LocString,必须同时完成注册、key 创建和翻译文件加载。

食物物品

FoodConfig.cs 使用 EntityTemplates.ExtendEntityToFood() 把掉落物扩展成食物。完整可编译示例位于 examples/ItemAndFood/FoodConfig.cs

csharp
using System.Collections.Generic;
using UnityEngine;

namespace ONITutorial.ItemAndFood
{
    public sealed class FoodConfig : IEntityConfig
    {
        public const string ID = "ONITutorialFood";

        public GameObject CreatePrefab()
        {
            GameObject go = EntityTemplates.CreateLooseEntity(
                ID,
                global::ONITutorial.ItemAndFood.STRINGS.FOOD.NAME,
                global::ONITutorial.ItemAndFood.STRINGS.FOOD.DESC,
                1f,
                false,
                Assets.GetAnim("squirrel_kanim"),
                "object",
                Grid.SceneLayer.Front,
                EntityTemplates.CollisionShape.RECTANGLE,
                0.8f,
                0.5f,
                true,
                0,
                SimHashes.Creature,
                new List<Tag>());

            EdiblesManager.FoodInfo foodInfo = new EdiblesManager.FoodInfo(
                ID,
                1000f * 1000f,
                1,
                255.15f,
                277.15f,
                4800f,
                true
            );

            return EntityTemplates.ExtendEntityToFood(go, foodInfo);
        }

        public void OnPrefabInit(GameObject inst) { }
        public void OnSpawn(GameObject inst) { }

    }
}

1000f * 1000f 是 1000 千卡。后面的 1 是品质,温度仍然是开尔文。

当前示例使用本机 DLL 中已确认的 FoodInfo 构造函数;旧文章里的 AddEffects() 重载不作为本页示例。

本地化文本

STRINGS.cs 里集中放普通物品和食物文本。完整可编译示例位于 examples/ItemAndFood/STRINGS.cs

csharp
namespace ONITutorial.ItemAndFood
{
    public static class STRINGS
    {
        public static class ITEM
        {
            public static LocString NAME = "ONI Tutorial Item";
            public static LocString DESC = "An item from the tutorial example.";
        }

        public static class FOOD
        {
            public static LocString NAME = "ONI Tutorial Food";
            public static LocString DESC = "A food from the tutorial example.";
        }
    }
}

如果后续加入 Buff,再把对应的 LocString 放在独立的 DUPLICANTS.MODIFIERS 路径中。

生成测试

进入开发模式后,可以用调试菜单生成 ONITutorialItemONITutorialFood。如果代码里找不到它,先检查几件事:

  • IEntityConfig 类是不是 public
  • .csproj 里有没有把新增 .cs 文件加进 <Compile Include="..." />
  • ID 有没有和别的实体重复。
  • 动画文件名和动画状态名是不是存在。

能生成食物以后,让复制人吃掉它,再看复制人属性面板里有没有“吃得很开心”这个效果。