- 致编者:请牢记我们的域名wiki.mcbe-dev.net!
- 致编者:欢迎加入本Wiki的官方交流QQ群或Discord服务器!
- 基岩版1.19.31现已发布!(了解更多)
- Inner Core现已支持Xbox模组联机!(了解更多)
- 如果您是第一次来到本Wiki,欢迎注册一个账户
- 点击顶部的“编辑”或“编辑源代码”按钮即可编辑当前页面
- 请知悉:在不登录时也可以编辑和新建页面,但是您当前的IP地址会记录在编辑历史中
教程:制作附加包/实体
本教程部分示例代码改编自Bedrock Wiki |
引言[编辑]
与物品不同,实体的自定义要由两部分完成:
- 服务端(纹理、名称、动画、声音)
- 客户端(行为、属性)
除此之外,我们还需要准备实体的模型及动画,关于这部分内容后面的章节将详细讲述[1]。
添加实体[编辑]
服务端[编辑]
实体的服务端文件与物品非常相似,我们只需要在行为包/entities文件夹下新建一个名为custom_entity.json
的文件并插入以下内容即可:
{
"format_version": "1.16.0",
"minecraft:entity": {
"description": {
"identifier": "wiki:custom_entity",
"is_summonable": true,
"is_spawnable": true,
"is_experimental": false
},
"components": {
"minecraft:type_family": {
"family": ["monster"]
},
"minecraft:health": {
"value": 20,
"max": 20
},
"minecraft:attack": {
"damage": 3
},
"minecraft:movement": {
"value": 0.2
},
"minecraft:collision_box": {
"width": 1,
"height": 2
},
"minecraft:loot": {
"table": "loot_tables/entities/custom_entity.json"
},
"minecraft:movement.basic": {},
"minecraft:navigation.walk": {
"can_walk": true,
"avoid_sun": true,
"can_pass_doors": true,
"can_open_doors": true
},
"minecraft:behavior.random_stroll": {
"priority": 6,
"speed_multiplier": 1
},
"minecraft:behavior.random_look_around": {
"priority": 7
},
"minecraft:behavior.look_at_player": {
"priority": 7,
"look_distance": 6,
"probability": 0.02
},
"minecraft:behavior.hurt_by_target": {
"priority": 1
},
"minecraft:behavior.nearest_attackable_target": {
"priority": 2,
"within_radius": 25,
"reselect_targets": true,
"entity_types": [
{
"filters": {
"any_of": [
{
"test": "is_family",
"subject": "other",
"value": "player"
}
]
},
"max_dist": 35
}
]
},
"minecraft:behavior.delayed_attack": {
"priority": 0,
"attack_once": false,
"track_target": true,
"require_complete_path": false,
"random_stop_interval": 0,
"reach_multiplier": 1.5,
"speed_multiplier": 1,
"attack_duration": 0.75,
"hit_delay_pct": 0.5
}
}
}
}
实体描述[编辑]
"description": {
"identifier": "wiki:custom_entity",
"is_summonable": true,
"is_spawnable": true,
"is_experimental": false
}
描述存储了此实体的最基础的一些属性:
- identifier:实体的赋命名空间标识符,此处不再赘述
- is_summonable:实体是否可以使用
/summon
命令召唤 - is_spawnable:实体是否可以使用刷怪蛋或生成规则在世界中生成
- is_experimental:实体实体是否只能添加到开启了实验性玩法的世界
实体组件[编辑]
组件定义了实体更高级的属性,其包含基础组件、AI意向、触发器等多种类型,关于组件的更多信息,参见Manual:数据驱动/实体。
基础组件[编辑]
"minecraft:type_family": {
"family": ["monster"]
},
"minecraft:health": {
"value": 20,
"max": 20
},
"minecraft:attack": {
"damage": 3
},
"minecraft:movement": {
"value": 0.2
},
"minecraft:collision_box": {
"width": 1,
"height": 2
},
"minecraft:loot": {
"table": "loot_tables/entities/custom_entity.json"
}
基础组件设置实体的生命值、移动速度、战利品、碰撞箱等属性,在上面的示例中:
minecraft:health
组件定义了实体的生命值minecraft:attack
组件定义了实体的攻击minecraft:movement
组件定义了实体的移动速度minecraft:type_family
组件定义了实体的族,在这里定义的monster
为原版怪物的族
运动机制[编辑]
"minecraft:physics": {},
"minecraft:jump.static": {},
"minecraft:movement.basic": {},
"minecraft:navigation.walk": {
"can_walk": true,
"avoid_sun": true,
"can_pass_doors": true,
"can_open_doors": true
}
运动机制由一些特殊的组件定义:
minecraft:physics
将重力和碰撞应用于实体minecraft:jump.static
使实体可以跳跃minecraft:movement.basic
允许实体在方块行走minecraft:navigation.walk
定义了实体遵循的路径
AI意向[编辑]
"minecraft:behavior.random_stroll": {
"priority": 6,
"speed_multiplier": 1
},
"minecraft:behavior.random_look_around": {
"priority": 7
},
"minecraft:behavior.look_at_player": {
"priority": 7,
"look_distance": 6,
"probability": 0.02
},
"minecraft:behavior.hurt_by_target": {
"priority": 1
},
"minecraft:behavior.nearest_attackable_target": {
"priority": 2,
"within_radius": 25,
"reselect_targets": true,
"entity_types": [
{
"filters": {
"any_of": [
{
"test": "is_family",
"subject": "other",
"value": "player"
}
]
},
"max_dist": 35
}
]
},
"minecraft:behavior.delayed_attack": {
"priority": 0,
"attack_once": false,
"track_target": true,
"require_complete_path": false,
"random_stop_interval": 0,
"reach_multiplier": 1.5,
"speed_multiplier": 1,
"attack_duration": 0.75,
"hit_delay_pct": 0.5
}
AI意向定义了实体将在何时做何事。
所有AI意向都包含一个名为priority
(优先级)的字段,其将会确定在可以在何时执行意向。
当实体选择要执行的意向时,它会从最低优先级到最高优先级搜索并排列其所有行为,并执行选择选中的意向,因此,建议将一些重要的意向的优先级设置为0或1[1]。
至此,实体的服务端文件便设置好了,接下来我们将学习实体的客户端文件。
这时如果打开世界并尝试使用命令召唤实体,它的行为应该像我们预期的那样。但地面上只会有一个影子,且实体名称是一个本地化键名,这是因为我们还没有设置客户端文件。
实体的客户端文件与物品或实体服务端文件区别较大,且包含动画、动画控制器、渲染控制器等多部分,下节我们就将学习实体的客户端配置。
客户端[编辑]
模型[编辑]
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.custom_entity",
"texture_width": 16,
"texture_height": 16,
"visible_bounds_width": 3,
"visible_bounds_height": 3,
"visible_bounds_offset": [0, 0.5, 0]
},
"bones": [
{
"name": "bb_main",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [-8, 0, -8], "size": [16, 16, 16], "uv": [-14, -14]}
]
}
]
}
]
}
模型,又称几何,决定了实体的形状。实体的模型按照JSON格式存储在资源包/models/entity文件夹中,得益于Blockbench等工具,我们不必详细学习其语法。
上面的代码示例就是在Blockbench内自动生成的一个类似于原版史莱姆的模型,请注意,此示例不可以直接拿来使用。
我们唯一需要注意的是字符串identifier,这是模型的赋命名空间标识符,一般格式为geometry.<模型名称>,我们后面需要利用它来调用模型。
纹理[编辑]
纹理,决定了实体的外观,实体的纹理一般是.png文件。为了保证模型与纹理完美契合,我们通常会在Blockbench中生成一个模板纹理,然后对这个模板纹理进行绘制,绘制完成后我们将其放入资源包/textures/entity中即可。
动画[编辑]
{
"format_version": "1.8.0",
"animations": {
"animation.custom_entity.move": {},
"animation.custom_entity.idle": {}
}
}
动画让实体更加栩栩如生,我们可以根据需要为实体提供任意数量的动画。
在上面的示例中,animation.custom_entity.move
是动画的标识符。除此之外,笔者省去了动画的执行过程而只保留动画的标识符,这在实际中是不允许的。
与模型类似,动画也是在Blockbench中自动生成的,因此我们不必学习其语法。
我们将动画文件放入资源包/animations文件夹中,但此时我们还不能正常触发它,因为这是是动画控制器的职责。
动画控制器[编辑]
{
"format_version": "1.12.0",
"animation_controllers": {
"controller.animation.custom_entity.walk": {
"initial_state": "standing",
"states": {
"standing": {
"blend_transition": 0.2,
"animations": [
"idle"
],
"transitions": [
{
"moving": "q.modified_move_speed > 0.1"
}
]
},
"moving": {
"blend_transition": 0.2,
"animations": [
"move"
],
"transitions": [
{
"standing": "q.modified_move_speed < 0.1"
}
]
}
}
}
}
}
动画控制器控制动画的播放方式,其由状态和状态之间的过渡组成。这使我们能够在实体处于某些状态时播放某些动画,当满足某些条件时,我们可以在它们之间转换。
"standing": {
"blend_transition": 0.2,
"animations": [
"idle"
],
"transitions": [
{
"moving": "q.modified_move_speed > 0.1"
}
]
},
"moving": {
"blend_transition": 0.2,
"animations": [
"move"
],
"transitions": [
{
"standing": "q.modified_move_speed < 0.1"
}
]
}
可以看到,我们设置了两个状态:standing
(站立)和moving
(移动)。
"transitions": [
{
"standing": "q.modified_move_speed < 0.1"
}
]
通过设置transitions
,我们可以让动画的状态相互转换。其中前一个值[注 1]是将要转换的状态名称,后一个值[注 2]是通过Molang设置的转换的条件。
现在动画控制器编写完成,我们将其放到资源包/animation_controllers
中即可。
渲染控制器[编辑]
{
"format_version": "1.10.0",
"render_controllers": {
"controller.render.custom_entity": {
"geometry": "geometry.default",
"materials": [
{
"*": "material.default"
}
],
"textures": ["texture.default"]
}
}
}
渲染控制器帮助开发者控制生物如何渲染在游戏世界中的表现,其存储在资源包/render_controllers文件夹中,与动画控制器同为自定义实体最难的两个部分。
原版实体中,不是所有生物都只有单一表现。例如村民根据群系拥有不同皮肤,热带鱼拥有数千种组合,狼在生气时会红眼等,这些都是由渲染控制器所控制。[2]
作为初学者,我们无需制作太复杂的渲染控制器,上面的示例即可满足我们的需求,其将从实体客户端文件中获取并采用默认材质、纹理、模型。
客户端实体[编辑]
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "wiki:custom_entity",
"materials": {
"default": "entity_alphatest"
},
"textures": {
"default": "textures/entity/custom_entity"
},
"geometry": {
"default": "geometry.custom_entity"
},
"scripts": {
"animate": ["walk_controller"]
},
"animations": {
"walk_controller": "controller.animation.custom_entity.walk",
"idle": "animation.custom_entity.idle",
"move": "animation.custom_entity.move"
},
"spawn_egg": {
"overlay_color": "#114514",
"base_color": "#9f2333"
},
"render_controllers": ["controller.render.custom_entity"]
}
}
}
客户端实体将动画、纹理、模型整合到一起,存储在资源包/entity
文件夹下,其中:
identifier
:实体的赋命名空间标识符,值应与服务端文件保持一致materials
:材质类型,这里选用entity_alphatest
以支持透明纹理geometry
:实体模型,填写模型的赋命名空间标识符textures
:实体纹理,填写纹理路径
动画短名称[编辑]
"animations": {
"walk_controller": "controller.animation.custom_entity.walk",,
"idle": "animation.custom_entity.idle",
"move": "animation.custom_entity.move"
}
动画控制器或动画想要在实体中被引用就必须在客户端文件中的animations
对象定义短名称,其中前一个值[注 3]是短名称,后一个值[注 4]是动画的赋命名空间标识符。
脚本[编辑]
"scripts": {
"animate": [
"walk_controller"
]
}
脚本决定实体在哪些特定时间执行哪些某些操作,其中animate数组将在每一刻执行数组内的动画或动画控制器。
现在,我们的动画应该可以正常工作了。
刷怪蛋[编辑]
"spawn_egg": {
"overlay_color": "#114514",
"base_color": "#9f2333"
}
"spawn_egg": {
"texture": "<物品纹理短名称>"
}
spawn_egg
对象将为实体自动生成一个刷怪蛋,其有两种写法:
- 使用十六进制RGB代码为刷怪蛋自动着色
- 使用物品纹理短名称自定义刷怪蛋纹理
本地化文件[编辑]
我们的实体还没有自己的名称,我们只需要进入或创建资源包/texts/zh_CN.lang文件,插入以下内容:
entity.wiki:custom_entity.name=自定义实体
item.spawn_egg.entity.wiki:custom_entity.name=自定义实体
大功告成!现在你的实体已经可以正常显示在Minecraft中了,恭喜!