添加实体简介

您可以使用行为包和资源包将实体添加到《我的世界》基岩版。 如推荐教程所述,实体的行为可通过行为包更改,外观可通过资源包更改。 两者都需要将工作实体添加到游戏中。 本指南分为两部分:第一部分介绍了将自定义实体添加到《我的世界》所需的文件和文件夹结构。 第二部分将向您展示如何通过使用行为组件、动画等为实体注入生机。

在建模包中创建的蓝鲸图像。

在本教程中,您将学习以下内容:

  • 如何使用行为包和资源包创建新的自定义实体。
  • 如何将各种功能应用到实体,包括组件和动画。
  • 使用实体名称的翻译。

要求

在开始本教程之前,建议完成以下内容。

建议了解以下知识以帮助您更好地理解本文。

  • 熟悉 JSON 格式的工作原理。
  • 诸如 VSCode 的代码编辑器

文件结构

在行为包中,一个实体文件负责定义服务器端的实体。 在资源包中,客户端实体文件负责确定实体在游戏中的外观。 下图显示了不同文件如何交互以创建自定义实体:

资源包和行为包的关系

机器人实体示例 - 极简机器人

作为本教程的参考,我们提供了同一实体的两个版本:一个可以在世界中随机生成的机器人:具有三种随机材质、一个轮子动画、各种组件和一个自定义水机制。 下载链接位于上面的要求部分。

要查看机器人的运行情况,请选择您刚刚下载的一组资源和行为包。 (我们建议现在尝试极简机器人。)将资源包和行为包放在各自的 com.mojang 子文件夹中,启动一个启用无敌模式的世界,然后使用 /summon compass:robot

这是完成后的“极简机器人”行为包和资源包的结构:

完成的极简机器人实体的文件结构

看起来很多,但您只需要考虑名称中带有“robot”的文件以及它们的存储位置。

了解机器人在游戏中的行为方式后,您可以删除完成的机器人资源和行为包,并按照本教程的步骤从头开始重新创建它们,以了解所有文件如何协同工作。

一个好的起点是使用您在早期教程中创建的资源和行为包。 您可能想要删除攻击奶牛实体,但这是个人喜好。

命名

当您创建一个实体时,首先要考虑的事情之一就是您要为其提供什么 ID。 您的资源和行为包中的文件需要使用您提供给实体的实体 ID 进行同步。 此 ID 由命名空间和名称组成,中间用冒号分隔。 正是我们之前用来召唤机器人的 compass:robot ID。

您自己的命名空间可以是您的团队名称或产品名称的简短版本。 ID 应仅包含小写字母、数字和下划线。 不要使用“minecraft”作为自定义内容的命名空间。 “minecraft”命名空间是为原版资源保留的,所以仅当您覆盖原版内容时才使用“minecraft”。

大多数定义实体的文件都是 JSON 文件。 为避免混淆,建议在创建每个文件时使用扩展的文件扩展名。 在大多数情况下,游戏会忽略文件名,但在处理附加内容时,凌乱的文件名可能会造成混淆。 扩展名是:

文件类型 文件名称
客户端实体文件 实体名.entity.json
模型文件 实体名.geo.json
动画文件 实体名.animation.json
动画控制器 实体名.animation_controllers.json
渲染控制器 实体名.render_controllers.json

entity_name 应替换为您的实体的名称,不包括命名空间。

格式版本

每个 JSON 文件都应该有一个 format_version 标签。 这个标签对于游戏正确读取文件很重要。 须知:以旧格式制作的文件仍然可以在较新版本的游戏中使用,但前提是格式版本设置正确。 不正确的格式版本可能导致频繁出错。

行为包定义

将机器人添加到游戏中的第一步从行为包开始。 在行为包的 entities 文件夹中新建一个文件,命名为 robot.json。 复制并粘贴此代码。

{
    "format_version": "1.12.0",
    "minecraft:entity": {
        "description": {
            "identifier": "compass:robot",
            "is_spawnable": true,
            "is_summonable": true
        },
        "components": {}
    }
}

在 description 标签中,我们定义了实体的基本属性。 identifier identifier 设置实体的 ID。 is_spawnable is_spawnable 稍后会在游戏中添加一个刷怪蛋,让玩家可以生成此生物。 is_summonable is_summonable 将使实体可用于 /summon 命令。

components 内部,我们将添加组件来改变实体的行为。 目前,我们只添加 minecraft:physics 组件。 这将赋予实体重力和常规碰撞行为。

"components": {
    "minecraft:physics": {}
}

保存您的 robot.json 文件并继续下一步。

客户端实体定义

现在,我们需要将实体添加到资源包中以赋予其视觉外观。 在资源包的 entity 文件夹中,创建一个名为 robot.entity.json 的新 JSON 文件。

{
    "format_version": "1.10.0",
    "minecraft:client_entity": {
        "description": {
            "identifier": "compass:robot",
            "spawn_egg": {
                "base_color": "#505152",
                "overlay_color": "#3b9dff"
            }
        }
    }
}

这是文件的基本结构。 到目前为止,它类似于我们在上一节中制作的行为端文件。 请注意,我们现在使用 client_entity 而不仅仅是 entity。 在撰写本文时,此文件的最新格式版本为 1.10.0。

spawn_egg 标签定义了刷怪蛋在物品栏中的外观。 使用这种方法,它看起来像一个香草刷怪蛋,但具有自定义颜色。

视觉效果

将实体添加到游戏中之前,它需要一个模型。 实体建模和动画一文解释了如何创建自定义模型和材质,但是创建模型需要学习很多东西,我们要先完成本教程。 因此,现在您可以通过复制和粘贴机器人资源包中的文件来假装您已经创建了一个模型。 稍后使用这些相同的步骤添加您创建的模型。

  • 将文件夹 models/entity 中的模型另存为 robot.geo.json
  • textures/entity 中的材质另存为 robot.png

现在模型文件已经就位,我们需要一个渲染控制器来链接用于实体的模型、材质和材料。

打开资源包中 entity 文件夹中的 robot.entity.json 文件。

对于大多数实体(例如我们的机器人),我们可以使用游戏提供的默认渲染控制器。 稍后,我们将在本教程的更高级部分讨论更多关于渲染控制器的内容。 现在,只需知道它的位置即可,其内容应为:

{
    "format_version": "1.10.0",
    "minecraft:client_entity": {
        "description": {
            "identifier": "compass:robot",
            "materials": {
                "default": "entity"
            },
            "textures": {
                "default": "textures/entity/robot"
            },
            "geometry": {
                "default": "geometry.robot"
            },
            "render_controllers": [
                "controller.render.default"
            ],
            "spawn_egg": {
                "base_color": "#505152",
                "overlay_color": "#3b9dff"
            }
        }
    }
}

该模型由 geometry 名称引用。 如果您在 Blockbench 中创建模型,请确保项目设置中的 geometry 名称设置为您的实体名称。 本例中为“robot”。

与几何形状不同,材质通过它们在资源包中的路径进行链接,去掉文件扩展名,如本示例所示。

在大多数情况下,不需要自定义材料。 相反,您可以使用默认材料。 在这个示例中,我们使用 entity。 如果材质有透明部分,您可以使用 entity_alphatest;或者,如果材质是半透明的(如染色玻璃),您可以使用 entity_alphablend

翻译字符串

目前,实体本身和刷怪蛋在游戏中都没有合适的名称。 要定义名称,我们需要一个语言文件。 在资源包中创建一个名为 texts 的新文件夹,并创建一个名为 en_US.lang 的新文件。 对于自定义实体,我们只需要更改此语言文件,因为所有其他语言将默认为美式英语。 在此文件中,添加以下两行:

entity.compass:robot.name=Robot
item.spawn_egg.entity.compass:robot.name=Spawn Robot

第一行定义实体的名称。 这将在死亡消息和某些命令的输出中可见。 键和值总是用等号分隔。 第一行可以分为:

entity.<identifier>.name=<Name>

第二行定义了刷怪蛋的物品名称:

item.spawn_egg.entity.<identifier>.name=<Name>

测试

务必及时且频繁进行测试。 尽早遇到问题有助于简化问题跟踪,从而更容易修复。 在做出更改后,通过测试通常会很快发现问题,这有助于缩小查找原因的范围至最近的更改。

您应该能够使用刷怪蛋或 summon 命令在游戏中生成实体。 如果您只想要一个静态实体,这样就可以了。 但是,如果您想进一步自定义实体,请继续阅读。

机器人实体示例 - 完整机器人

现在该尝试完整机器人的资源和行为包了。 比较文件夹和文件的集合。 然后,拿掉您的极简最小机器人包,以便我们继续添加功能。

组件

组件决定实体在游戏中如何行动。 让我们添加一些组件并详细解释它们的作用。

behavior pack/entities/ 文件夹中,打开 robot.json 并将 "minecraft:physics": {} 的单个条目替换为所有这些...

   "components": {
        "minecraft:physics": {},
        "minecraft:nameable": {},
        "minecraft:movement": {
            "value": 0.25
        },
        "minecraft:movement.basic": {},
        "minecraft:jump.static": {},
        "minecraft:navigation.walk": {
            "avoid_water": true
        },
        "minecraft:behavior.tempt": {
            "priority": 1,
            "speed_multiplier": 1.4,
            "items": ["diamond"],
            "within_radius": 7.0
        },
        "minecraft:behavior.random_stroll":
        {
            "priority": 3,
            "speed_multiplier": 0.8
        },
        "minecraft:experience_reward": {
            "on_death": 8
        }
   }
组件名称 描述
minecraft:nameable 允许玩家使用 name 标签命名该实体。
minecraft:movement 决定实体移动的速度。 0.25 是《我的世界》中大多数动物的常规速度。
minecraft:movement.basic 赋予实体在地面上移动的能力。
minecraft:jump.static 允许实体跳跃以走上方块。
minecraft:navigation.walk 允许实体在世界中游走。 避免水是该组件自带的选项之一。
minecraft:behavior.tempt 使实体跟随手中持有钻石的玩家。 我们赋予此行为更高的优先级,因此它会优先考虑此操作(较低的数字 = 较高的优先级)。
minecraft:behavior.random_stroll 会使实体在该处周围随机走动。 我们将优先级设置为更高的数字,以便实体仅在无所事事时才会执行此操作。 速度倍增器将在使用此行走行为时降低速度。
minecraft:experience_reward 让实体在被玩家杀死时掉落经验。

动画

在本节中,我们将只为机器人添加一个简单的轮子动画。 如果您想了解有关动画的更多信息、如何使用动画控制器以及如何在 Blockbench 中创建动画,请阅读本指南

动画存储在动画文件中。 所以我们需要做的第一件事是在资源包中创建一个名为 animations 的文件夹,并在其中创建一个名为 robot.animation.json 的文件。 在该文件中,我们将创建一个名为 animation.robot.drive 的新动画。 我们还想将 loop 设置为 true,以便动画继续播放。 该文件应如下所示:

{
    "format_version": "1.8.0",
    "animations": {
        "animation.robot.drive": {
            "loop": true
        }
    }
}

动画允许我们为每个骨骼的位置、旋转和缩放设置动画。 (如果您还不知道“骨骼”在该上下文中的含义,没关系 - 当您学习 Blockbench 时,您将了解骨骼。 现在,只知道它意味着模型的一部分,比如腿或轮子。)动画可以使用关键帧、Molang 表达式或两者的组合来完成。 在这个示例中,我们将只使用 Molang 表达式。

Molang 是一种仅用于资源包和行为包的语言。 它允许我们使用查询从实体中获取各种数字,并使用数学表达式从这些数字中计算出结果。 例如,查询 query.modified_distance_moved 将返回实体移动的距离。 我们可以用它来计算机器人轮子在 X 轴上的旋转,这将产生一个动画,让机器人看起来像是在驾驶。 您必须调试这些数字,但对于这个模型 60 工作得很好。

{
    "format_version": "1.8.0",
    "animations": {
        "animation.robot.drive": {
            "loop": true,
            "bones": {
                "wheel": {
                    "rotation":["query.modified_distance_moved*60", 0, 0]
                }
            }
        }
    }
}

现在动画已创建,我们需要将其链接到客户端实体文件中。 (请记住,资源包是客户端,因此为下一部分打开 <resource pack>/entity/robot.entity.json。) animations 标签链接实体使用的所有动画和动画控制器。 每个动画都有一个短名称,可用于在动画控制器中或直接在文件中播放动画,在本例中为 drive

scriptsanimate 部分可用于直接播放动画:

        "animations": {
            "drive": "animation.robot.drive"
        },
        "scripts": {
            "animate": ["drive"]
        }

在客户端实体文件的 description 标签中添加这两个标签后,驱动动画将始终处于活动状态并在实体移动时推进车轮旋转。

渲染控制器

渲染控制器允许我们使用 Molang 更改实体的几何形状、材质和材料。 以下示例显示如何使用已在客户端实体文件中链接为 default 的几何形状、材料和材质:

{
    "format_version": "1.8.0",
    "render_controllers": {
        "controller.render.robot": {
            "geometry": "Geometry.default",
            "materials": [ { "*": "Material.default" }],
            "textures": [ "Texture.default" ]
        }
    }
}

如果我们只想使用一个默认的几何形状、材料和材质,可以像以前一样让它指向默认的渲染控制器。 但是,这是学习如何添加随机材质的好时机,所以我们首先剖析渲染控制器的工作方式。

渲染控制器说明

您会注意到基本标签名为 render_controllers。 这意味着我们可以在一个文件中指定多个渲染控制器。

我们的渲染控制器使用以下方案命名:controller.render.<entity_name>。 对于多用途渲染控制器,我们还可以使用另一个关键字来代替实体名称。

在渲染控制器标签内,指定了不同的资源,但您会注意到每个资源都使用不同的 JSON 格式。

几何形状

一个渲染控制器一次只能显示一个几何图形。 这就是它以一个字符串直接链接的原因。 这个字符串可以是一个 Molang 表达式并且应始终返回一个几何形状。 在本例中,其名称为 Geometry.default,这意味着它将返回任何使用该渲染控制器的实体链接为 default 的几何形状。

您可以使用多个渲染控制器在一个实体上渲染多个几何形状。 但这可能很棘手,并且可能导致意外行为。 因此,它只推荐给有经验的创建者。

材料

与几何形状不同,材料被写成一个对象数组。 目的是我们可以为每个骨骼分配一个单独的材料。 数组中的每个对象都可以有一个键值对。 该键选择一组骨骼。 星号用作通配符。 这意味着所有骨骼,无论名称如何,都将分配默认材料。 请注意,材料是按顺序分配的,这意味着列表中更靠后的材料可以覆盖以前的材料。

        "materials": [
            { "*": "Material.default" },
            { "*_arm": "Material.transparent" }
        ],

在本例中,我们首先将默认材料应用于所有骨骼。 然后,我们用透明材料覆盖以 _arm 结尾的所有骨骼上的材料。 这样,所有手臂骨骼都将支持透明度。

材质

材质在数组中指定。 在大多数情况下,这里只会链接一个材质,因为实体不支持单独的材质。 但有一个例外:材料可以支持多个层叠的材质,例如材料 entity_multitexture。 例如,这被羊驼用来覆盖装饰。

数组

当使用一种类型的多个资源时,使用数组会很有用。 数组是在渲染控制器中定义的资源链接列表,您可以使用 Molang 从其中选择一个资源。

我们可以像这样为机器人定义一个数组:

        "controller.render.robot": {
            "arrays": {
                "textures": {
                    "Array.variant":[
                        "Texture.default",
                        "Texture.variant_b",
                        "Texture.variant_c"
                    ]
                }
            },

在 arrays 部分,我们可以为三个类别分别定义数组:texturesmaterialsgeometries。 在类别中,您可以使用 Array.<array name> 作为名称来定义数组。 数组中的每一行都链接了一个在客户端实体文件中定义的材质。

您可以使用 Molang 访问数组。 数组是从 0 开始的,所以这个数组中的第一个材质可以通过 Array.variant[0] 访问。

在这个示例中,我们使用变体查询从数组中选择一个材质。 可以通过行为文件中的 minecraft:variant 组件更改生物的变体。

"textures": [ "Array.variant[ query.variant ]" ]

现在我们需要将附加材质链接到客户端实体文件中。 常规的蓝色机器人材质已经链接为 default,我们现在将创建机器人材质文件的两个副本,编辑颜色,并将它们链接为 variant_bvariant_c

            "textures": {
                "default": "textures/entity/robot",
                "variant_b": "textures/entity/robot_b",
                "variant_c": "textures/entity/robot_c"
            },

现在,材质已链接。 最后一步是随机化行为文件中的变体。 为此,我们将使用组件组。 这些是一种随时从实体中添加和删除一组组件的方法。 我们还将使用一个事件来随机化要添加的组件组。

        "description": {
            ...
        },
        "components": {
            ...
        },
        "component_groups": {
            "compass:color_0": {
                "minecraft:variant": {"value": 0}
            },
            "compass:color_1": {
                "minecraft:variant": {"value": 1}
            },
            "compass:color_2": {
                "minecraft:variant": {"value": 2}
            }
        },
        "events": {
            "minecraft:entity_spawned": {
                "randomize": [
                    {
                        "add": {
                            "component_groups": ["compass:color_0"]
                        }
                    }, {
                        "add": {
                            "component_groups": ["compass:color_1"]
                        }
                    }, {
                        "add": {
                            "component_groups": ["compass:color_2"]
                        }
                    }
                ]
            }
        }

现在,当我们第一次生成实体时,它会随机选择一个组件组,从而选择一个变体。 这是随机化实体外观的一种非常常见的技术。

生成

生成规则定义了实体如何在世界中随机生成。 我们将为我们的机器人创建一个生成规则文件。 首先,在您的行为包中创建一个名为 spawn_rules 的文件夹。 在文件夹内,创建一个名为 robot.json 的新文本文件。 该文件的内容应如下所示:

{
    "format_version": "1.8.0",
    "minecraft:spawn_rules": {
        "description": {
            "identifier": "compass:robot",
            "population_control": "animal"
        },
        "conditions": []
    }
}

minecraft:spawn_rules 内部,我们需要考虑两件事:人口控制条件

description description 定义文件的基本属性。 identifier identifier 应该匹配我们实体的标识符。 population_control population_control 定义游戏如何知道要生成多少生物,并且稍微复杂一些。

人口控制

有不同的实体池。 当此处定义的池被认为已满时,游戏将不再生成该池中的生物。 共有三种不同的选择:

  • "animal":被动生物,如牛和猪
  • "water_animal":热带鱼、海豚等水生生物
  • "monster":敌对生物,如骷髅和僵尸

对于机器人,我们使用的是 animal(动物)池。

条件

conditions conditions 是一系列允许生物在世界中生成的可能条件。 每个条件分别尝试在世界中生成生物。 每个条件都由一组组件组成,这些组件定义何时生产或不生成生物。

对于基本的生成规则,一个条件就足够了。 对于机器人,我们将使用以下配置:

{
    "format_version": "1.8.0",
    "minecraft:spawn_rules": {
        "description": {
            "identifier": "compass:robot",
            "population_control": "animal"
        },
        "conditions": [
            {
                "minecraft:spawns_on_surface": {},
                "minecraft:brightness_filter": {
                    "min": 12,
                    "max": 15,
                    "adjust_for_weather": false
                },
                "minecraft:weight": {
                    "default": 40
                },
                "minecraft:biome_filter": {
                    "test": "has_biome_tag",
                    "value": "animal"
                }
            }
        ]
    }
}
组件名称 描述
minecraft:spawns_on_surface 生物在地表生成
minecraft:brightness_filter 仅以特定亮度生成实体。 接受三个选项,minmaxadjust_for_weather。 亮度级别范围从 0 到 15。 如果 adjust_for_weather 设置为 true,则将考虑由于下雨和雷暴导致的亮度降低。
minecraft:weight 实体生成时的重量。 数字越高,生物生成的频率越高。
minecraft:biome_filter 过滤允许生物生成的生物群系。 生物群系过滤器的工作方式与过滤器的行为类似,这意味着允许使用 all_ofany_of 等运算符。 生物群系有不同的标签,指示生物群系类型、变体、维度以及怪物和动物等特征。

机器人现在会在地表上任何动物可以生成且光线充足的地方生成。 权重为 40 时,它们也会非常频繁地生成。

行为动画

行为动画的工作方式与常规动画类似,但在行为包中运行。 虽然常规动画为模型的运动以及声音和粒子设置动画,但行为动画可以运行常规命令、触发实体事件或运行 Molang 表达式。 行为动画通常也被称为实体事件,尽管这个名称往往有点令人困惑。

由于机器人不喜欢水,我们将添加一个机制来在水中或雨中损坏机器人。 首先,我们将创建一个动画控制器来使用 Molang 查询测试实体何时在水中。 在行为包中创建一个名为 animation_controllers 的新文件夹,并在其中创建文件 robot.animation_controllers.json

{
    "format_version": "1.10.0",
    "animation_controllers": {
        "controller.animation.robot.in_water": {
            "states": {
                "default": {
                    "transitions": [
                        {"in_water": "query.is_in_water_or_rain"}
                    ]
                },
                "in_water": {
                    "transitions": [
                       {"default": "query.is_in_water_or_rain == 0"}
                    ]
                }
            }
        }
    }
}

动画控制器看起来与常规的客户端动画控制器非常相似。 它有两种状态,可以根据机器人是否在水中进行切换。

现在,让我们添加一个动画来给机器人一个中毒效果。 在行为包内创建文件夹 animations 并创建一个名为 robot.animation.json 的文件:

{
    "format_version": "1.8.0",
    "animations": {
        "animation.robot.poison": {
            "loop": true,
            "animation_length": 1,
            "timeline": {
                "0.0": [
                    "/effect @s poison 2 0 true"
                ]
            }
        }
    }
}

我们没有使用这里的 bone 标签来为骨骼设置动画,而是使用 timeline 标签。 在资源包中,timeline(时间线)只能用于运行 Molang 代码。 在行为动画中,您可以使用它来运行 Molang 代码、命令或触发实体事件。 请注意,所有这些都以字符串形式提供。 游戏将从字符串的内容中找出字符串的类型。 如果字符串以斜杠开头,它将作为命令运行。 如果它符合这个方案:@s namespace:event,它将作为实体事件运行。 如果它看起来像 Molang,它将作为 Molang 运行。

因此,在行为动画中以斜杠开头的命令很重要。 另外,请注意,我们将剧毒施加两秒钟,因为一秒钟不足以实际施加伤害。 命令末尾的 true 将使状态效果弥漫,这意味着不会有任何粒子。

与资源包中的动画一样,我们需要在实体的 description 标签中链接所有动画和动画控制器,如下所示:

        "description": {
            "identifier": "compass:robot",
            "is_spawnable": true,
            "is_summonable": true,
            "animations": {
                "poison": "animation.robot.poison",
                "in_water": "controller.animation.robot.in_water"
            },
            "scripts": {
                "animate": [
                    "in_water"
                ]
            }
        },

animations 部分列出了实体使用的所有动画和动画控制器,并为它们提供了一个简短的名称。 在 scripts/animate 部分,我们列出了应始终运行的动画。 我们希望控制器检测到始终运行的状态,而不是中毒效果。

现在,我们需要回到动画控制器并添加中毒效果。 我们还将添加一些生命恢复机制和音效,这样机器人就不会那么容易死亡。

            "states": {
                "default": {
                    "transitions": [
                        {"in_water": "query.is_in_water_or_rain"}
                    ]
                },
                "in_water": {
                    "animations": [
                        "poison"
                    ],
                    "on_exit": [
                        "/effect @s regeneration 2 4 true",
                        "/playsound random.fizz @a[r=16]"
                    ],
                    "transitions": [
                        {"default": "query.is_in_water_or_rain == 0"}
                    ]
                }
            }

animations 数组中,我们列出了所有应该在这种状态下运行的动画,在我们的示例中就是 poison

on_exit 标签中,我们添加了两个命令,它们将在机器人离开水面时运行。 第一个命令会给机器人一个四级的生命恢复效果,持续两秒。 第二个命令将播放嘶嘶声。

请注意,我们也可以在 default(默认)状态的 on_entry 数组中运行该命令,但这也会在生成机器人或重新加载世界时产生效果,因为游戏总是首先转换到 default 状态。

总结控制器和动画之间的关系:动画控制器用于控制动画何时播放,而动画本身是由控制器确定的过渡到动画的结果。 动画和动画控制器将提供给实体行为文件。

下一步内容?

在本指南中,我们为游戏添加了一个完整的自定义实体。 如果您使用现有模型文件而不是创建自己的模型文件,那么现在可能是了解 Blockbench 的好时机。 或者,您可以阅读有关服务器实体行为的更多信息。