首次上传
67
docs/netease-tutorial-103.4-main/6-重温:自定义生物/1-基本结构.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# 基本结构
|
||||
|
||||
在下面这几节中我们一起来回顾学习实体相关的自定义JSON文件。和之前一样,我们首先来回顾编辑器中创建的实体。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
我们在新建文件向导中新建一个实体配置。标识符设置为`test:test_entity`,模板选择空。
|
||||
|
||||

|
||||
|
||||
可以看到,虽然我们创建了一个空白的实体,但编辑器依旧为我们添加了“持久化保存”的行为包组件,该组件代表着实体在生成之后不会通过自动毁除(despawn)机制毁除,而是会保存至存档中。
|
||||
|
||||
资源包组件中也添加了模型和纹理的相关内容。我们很快会看到在实际JSON文件中他们的表现。
|
||||
|
||||
## 实际文件
|
||||
|
||||
在行为包的`entities`文件夹中,我们可以找到实体的服务端定义文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.12.0",
|
||||
"minecraft:entity": {
|
||||
"component_groups": {
|
||||
|
||||
},
|
||||
"components": {
|
||||
"minecraft:persistent": {
|
||||
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"identifier": "test:test_entity",
|
||||
"is_experimental": false
|
||||
},
|
||||
"events": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
在资源包的`entity`文件夹中,我们可以找到实体的资源包定义文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"minecraft:client_entity": {
|
||||
"description": {
|
||||
"geometry": {
|
||||
"default": ""
|
||||
},
|
||||
"identifier": "test:test_entity",
|
||||
"textures": {
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
可以看到,在双端`description`的`identifier`下,定义了相同的实体标识符`test:test_entity`,这可以告诉引擎他们是同一个实体的不同部分。
|
||||
|
||||
服务端定义中的`components`是服务端的组件,这里可以看到持久化组件`minecraft:persistent`已经被添加。`component_groups`是实体的组件组,这是用于控制实体在不同状态之间切换的对象,其中可以分组定义成组的组件,然后我们可以在这些分组之间切换,可以参见Minecraft Wiki的[定义](https://zh.minecraft.wiki/w/%E5%AE%9A%E4%B9%89)页面。`events`是实体的事件,我们可以通过事件来增删组件组。
|
||||
|
||||
在客户端定义中,我们默认只有`description`对象,和`identifier`并列的`textures`用于控制纹理,`geometry`用于控制模型。此外,还有更多的其他属性,大家可以在编辑器中可视化添加这些属性并返回JSON文件查看。我们也会在后续的章节中对其中一部分进行讲解。
|
||||
155
docs/netease-tutorial-103.4-main/6-重温:自定义生物/2-外观.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# 外观
|
||||
|
||||
在本节中,我们回顾学习实体的外观。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
我们回到之前添加过的守卫实体。可以看到,资源包组件处具有丰富的属性。我们可以尝试浏览这些属性,和后面JSON实际文件中的表现做出对比。
|
||||
|
||||

|
||||
|
||||
点击添加属性,我们也可以实际看到编辑器支持添加的属性列表。
|
||||
|
||||
## 实际文件
|
||||
|
||||
下面,我们一起来看一下守卫实体的资源包中的客户端定义文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"minecraft:client_entity": {
|
||||
"description": {
|
||||
"animation_controllers": [
|
||||
{
|
||||
"humanoid_baby_big_head": "controller.animation.humanoid.baby_big_head"
|
||||
},
|
||||
{
|
||||
"humanoid_base_pose": "controller.animation.humanoid.base_pose"
|
||||
},
|
||||
{
|
||||
"look_at_target": "controller.animation.humanoid.look_at_target"
|
||||
},
|
||||
{
|
||||
"move": "controller.animation.humanoid.move"
|
||||
},
|
||||
{
|
||||
"riding": "controller.animation.humanoid.riding"
|
||||
},
|
||||
{
|
||||
"holding": "controller.animation.humanoid.holding"
|
||||
},
|
||||
{
|
||||
"brandish_spear": "controller.animation.humanoid.brandish_spear"
|
||||
},
|
||||
{
|
||||
"charging": "controller.animation.humanoid.charging"
|
||||
},
|
||||
{
|
||||
"attack": "controller.animation.humanoid.attack"
|
||||
},
|
||||
{
|
||||
"sneaking": "controller.animation.humanoid.sneaking"
|
||||
},
|
||||
{
|
||||
"bob": "controller.animation.humanoid.bob"
|
||||
},
|
||||
{
|
||||
"damage_nearby_mobs": "controller.animation.humanoid.damage_nearby_mobs"
|
||||
},
|
||||
{
|
||||
"bow_and_arrow": "controller.animation.humanoid.bow_and_arrow"
|
||||
},
|
||||
{
|
||||
"swimming": "controller.animation.humanoid.swimming"
|
||||
},
|
||||
{
|
||||
"use_item_progress": "controller.animation.humanoid.use_item_progress"
|
||||
},
|
||||
{
|
||||
"zombie_attack_bare_hand": "controller.animation.zombie.attack_bare_hand"
|
||||
},
|
||||
{
|
||||
"zombie_swimming": "controller.animation.zombie.swimming"
|
||||
}
|
||||
],
|
||||
"animations": {
|
||||
"attack.rotations": "animation.humanoid.attack.rotations.v1.0",
|
||||
"bob": "animation.humanoid.bob.v1.0",
|
||||
"bow_and_arrow": "animation.humanoid.bow_and_arrow.v1.0",
|
||||
"brandish_spear": "animation.humanoid.brandish_spear.v1.0",
|
||||
"charging": "animation.humanoid.charging.v1.0",
|
||||
"damage_nearby_mobs": "animation.humanoid.damage_nearby_mobs.v1.0",
|
||||
"holding": "animation.humanoid.holding.v1.0",
|
||||
"humanoid_base_pose": "animation.humanoid.base_pose.v1.0",
|
||||
"humanoid_big_head": "animation.humanoid.big_head",
|
||||
"look_at_target_default": "animation.humanoid.look_at_target.default.v1.0",
|
||||
"look_at_target_gliding": "animation.humanoid.look_at_target.gliding.v1.0",
|
||||
"look_at_target_swimming": "animation.humanoid.look_at_target.swimming.v1.0",
|
||||
"move": "animation.humanoid.move.v1.0",
|
||||
"riding.arms": "animation.humanoid.riding.arms.v1.0",
|
||||
"riding.legs": "animation.humanoid.riding.legs.v1.0",
|
||||
"sneaking": "animation.humanoid.sneaking.v1.0",
|
||||
"swimming": "animation.humanoid.swimming.v1.0",
|
||||
"use_item_progress": "animation.humanoid.use_item_progress.v1.0",
|
||||
"zombie_attack_bare_hand": "animation.zombie.attack_bare_hand",
|
||||
"zombie_swimming": "animation.zombie.swimming"
|
||||
},
|
||||
"enable_attachables": true,
|
||||
"geometry": {
|
||||
"default": "geometry.zombie"
|
||||
},
|
||||
"identifier": "test:guard",
|
||||
"materials": {
|
||||
"default": "zombie"
|
||||
},
|
||||
"render_controllers": [
|
||||
"controller.render.zombie"
|
||||
],
|
||||
"scripts": {
|
||||
"pre_animation": [
|
||||
"variable.tcos0 = (Math.cos(query.modified_distance_moved * 38.17) * query.modified_move_speed / variable.gliding_speed_value) * 57.3;"
|
||||
]
|
||||
},
|
||||
"spawn_egg": {
|
||||
"texture": "spawn_egg",
|
||||
"texture_index": 12
|
||||
},
|
||||
"textures": {
|
||||
"default": "textures/entity/guard"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
可以看到,一个已经定义完成的实体的客户端定义文件比空实体要丰富很多。
|
||||
|
||||
曾经,我们通过修改`textures/default`字段修改过守卫实体的纹理,大家现在已经改知道了,这就是修改了JSON中纹理指向的文件路径。
|
||||
|
||||
除了材质`materials`、几何模型`geometry`之外,我们还有一个专门的文件用于控制渲染的结果,那便是渲染控制器。渲染控制器位于资源包的`render_controllers`文件夹中,然后继而被实体客户端的`render_controllers`字段引用。在当前的例子中,实体客户端定义文件下的
|
||||
`render_controllers`引用了原版的`controller.render.zombie`控制器。我们可以打开原版安装文件查看该控制器对应的JSON文件的内容:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version":"1.8.0",
|
||||
"render_controllers":{
|
||||
"controller.render.zombie":{
|
||||
"geometry":"Geometry.default",
|
||||
"materials":[
|
||||
{
|
||||
"*":"Material.default"
|
||||
}
|
||||
],
|
||||
"textures":[
|
||||
"Texture.default"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
渲染控制器具体各个字段的含义可以在官方文档[自定义生物](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/15-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B8%B8%E6%88%8F%E5%86%85%E5%AE%B9/3-%E8%87%AA%E5%AE%9A%E4%B9%89%E7%94%9F%E7%89%A9/01-%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9F%BA%E7%A1%80%E7%94%9F%E7%89%A9.html?catalog=1)页面中找到。
|
||||
|
||||
此外,实体还有一些动画效果。`animations`字段定义了该实体中可以引用的所有动画,而`animation_controllers`中则定义了该实体使用的动画控制器。实体的动画制作较为繁琐,大家可以在上述自定义生物官方页面中找到具体JSON字段含义,并在官方课程[自定义松鼠实体资源](https://mc.163.com/dev/mcmanual/mc-dev/mconline/15-%E7%8E%A9%E6%B3%95%E7%BB%84%E4%BB%B6%E6%95%99%E7%A8%8B%E3%80%90%E6%96%B0%E7%89%88%E3%80%91/11-%E7%B2%BE%E9%80%9A%E8%87%AA%E5%AE%9A%E4%B9%89%E5%A4%8D%E6%9D%82%E7%9A%84%E5%AE%9E%E4%BD%93/4-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%9D%BE%E9%BC%A0%E5%AE%9E%E4%BD%93%E8%B5%84%E6%BA%90.html?catalog=1)中找到相关制作方法。
|
||||
712
docs/netease-tutorial-103.4-main/6-重温:自定义生物/3-AI.md
Normal file
@@ -0,0 +1,712 @@
|
||||
# AI
|
||||
|
||||
在本节中,我们回顾学习实体的AI控制。
|
||||
|
||||
## 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
依旧以守卫实体为例,我们可以看到在行为包组件中添加了很多以“行为.”开头的组件。这些组件便是与AI行为有关的组件。
|
||||
|
||||

|
||||
|
||||
我们也可以自行添加更多的其他行为。这些行为组件英文都是以`behavior.`开头。
|
||||
|
||||
## 实际文件
|
||||
|
||||
我们来观察守卫实体的行为包定义文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.10",
|
||||
"minecraft:entity": {
|
||||
"component_groups": {
|
||||
"minecraft:can_break_doors": {
|
||||
"minecraft:annotation.break_door": {
|
||||
|
||||
}
|
||||
},
|
||||
"minecraft:can_have_equipment": {
|
||||
"minecraft:equipment": {
|
||||
"table": "loot_tables/entities/zombie_equipment.json"
|
||||
}
|
||||
},
|
||||
"minecraft:convert_to_baby_drowned": {
|
||||
"minecraft:is_shaking": {
|
||||
|
||||
},
|
||||
"minecraft:transformation": {
|
||||
"delay": {
|
||||
"value": 15
|
||||
},
|
||||
"drop_equipment": true,
|
||||
"into": "minecraft:drowned<minecraft:as_baby>",
|
||||
"transformation_sound": "convert_to_drowned"
|
||||
}
|
||||
},
|
||||
"minecraft:convert_to_drowned": {
|
||||
"minecraft:is_shaking": {
|
||||
|
||||
},
|
||||
"minecraft:transformation": {
|
||||
"delay": {
|
||||
"value": 15
|
||||
},
|
||||
"drop_equipment": true,
|
||||
"into": "minecraft:drowned<minecraft:as_adult>",
|
||||
"transformation_sound": "convert_to_drowned"
|
||||
}
|
||||
},
|
||||
"minecraft:look_to_start_drowned_transformation": {
|
||||
"minecraft:environment_sensor": {
|
||||
"triggers": {
|
||||
"event": "minecraft:start_transforming",
|
||||
"filters": {
|
||||
"operator": "==",
|
||||
"subject": "self",
|
||||
"test": "is_underwater",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:start_drowned_transformation": {
|
||||
"minecraft:environment_sensor": {
|
||||
"triggers": {
|
||||
"event": "minecraft:stop_transforming",
|
||||
"filters": {
|
||||
"operator": "==",
|
||||
"subject": "self",
|
||||
"test": "is_underwater",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:timer": {
|
||||
"looping": false,
|
||||
"time": 30,
|
||||
"time_down_event": {
|
||||
"event": "minecraft:convert_to_drowned"
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:zombie_adult": {
|
||||
"minecraft:behavior.mount_pathing": {
|
||||
"priority": 2,
|
||||
"speed_multiplier": 1.25,
|
||||
"target_dist": 0.0,
|
||||
"track_target": true
|
||||
},
|
||||
"minecraft:experience_reward": {
|
||||
"on_death": "query.last_hit_by_player ? 5 + (query.equipment_count * Math.Random(1,3)) : 0"
|
||||
},
|
||||
"minecraft:movement": {
|
||||
"value": 0.23
|
||||
},
|
||||
"minecraft:rideable": {
|
||||
"family_types": [
|
||||
"zombie"
|
||||
],
|
||||
"seat_count": 1,
|
||||
"seats": {
|
||||
"lock_rider_rotation": 0,
|
||||
"position": [
|
||||
0.0,
|
||||
1.1,
|
||||
-0.35
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:zombie_baby": {
|
||||
"minecraft:experience_reward": {
|
||||
"on_death": "query.last_hit_by_player ? 12 + (query.equipment_count * Math.Random(1,3)) : 0"
|
||||
},
|
||||
"minecraft:is_baby": {
|
||||
|
||||
},
|
||||
"minecraft:movement": {
|
||||
"value": 0.35
|
||||
},
|
||||
"minecraft:scale": {
|
||||
"value": 0.5
|
||||
}
|
||||
},
|
||||
"minecraft:zombie_jockey": {
|
||||
"minecraft:behavior.find_mount": {
|
||||
"max_failed_attempts": 20,
|
||||
"priority": 1,
|
||||
"start_delay": 15,
|
||||
"within_radius": 16
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:behavior.delayed_attack": {
|
||||
"attack_duration": 1.0
|
||||
},
|
||||
"minecraft:behavior.equip_item": {
|
||||
"priority": 2
|
||||
},
|
||||
"minecraft:behavior.hurt_by_target": {
|
||||
"priority": 1
|
||||
},
|
||||
"minecraft:behavior.look_at_player": {
|
||||
"look_distance": 6,
|
||||
"priority": 8,
|
||||
"probability": 0.02
|
||||
},
|
||||
"minecraft:behavior.melee_attack": {
|
||||
"priority": 3
|
||||
},
|
||||
"minecraft:behavior.nearest_attackable_target": {
|
||||
"entity_types": [
|
||||
{
|
||||
"filters": {
|
||||
"any_of": [
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "player"
|
||||
},
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "snowgolem"
|
||||
},
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "irongolem"
|
||||
}
|
||||
]
|
||||
},
|
||||
"max_dist": 35
|
||||
},
|
||||
{
|
||||
"filters": {
|
||||
"any_of": [
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "villager"
|
||||
},
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "wandering_trader"
|
||||
}
|
||||
]
|
||||
},
|
||||
"max_dist": 35,
|
||||
"must_see": false
|
||||
},
|
||||
{
|
||||
"filters": {
|
||||
"all_of": [
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "baby_turtle"
|
||||
},
|
||||
{
|
||||
"operator": "!=",
|
||||
"subject": "other",
|
||||
"test": "in_water",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"max_dist": 35
|
||||
}
|
||||
],
|
||||
"must_see": true,
|
||||
"must_see_forget_duration": 17.0,
|
||||
"priority": 2,
|
||||
"reselect_targets": true,
|
||||
"within_radius": 25.0
|
||||
},
|
||||
"minecraft:behavior.pickup_items": {
|
||||
"can_pickup_any_item": true,
|
||||
"excluded_items": [
|
||||
"minecraft:glow_ink_sac"
|
||||
],
|
||||
"goal_radius": 2,
|
||||
"max_dist": 3,
|
||||
"pickup_based_on_chance": true,
|
||||
"priority": 6,
|
||||
"speed_multiplier": 1.0
|
||||
},
|
||||
"minecraft:behavior.random_look_around": {
|
||||
"priority": 9
|
||||
},
|
||||
"minecraft:behavior.random_stroll": {
|
||||
"priority": 7,
|
||||
"speed_multiplier": 1
|
||||
},
|
||||
"minecraft:behavior.stomp_turtle_egg": {
|
||||
"goal_radius": 1.14,
|
||||
"interval": 20,
|
||||
"priority": 4,
|
||||
"search_height": 2,
|
||||
"search_range": 10,
|
||||
"speed_multiplier": 1
|
||||
},
|
||||
"minecraft:breathable": {
|
||||
"breathes_air": true,
|
||||
"breathes_water": true,
|
||||
"suffocate_time": 0,
|
||||
"total_supply": 15
|
||||
},
|
||||
"minecraft:burns_in_daylight": {
|
||||
|
||||
},
|
||||
"minecraft:can_climb": {
|
||||
|
||||
},
|
||||
"minecraft:collision_box": {
|
||||
"height": 1.9,
|
||||
"width": 0.6
|
||||
},
|
||||
"minecraft:conditional_bandwidth_optimization": {
|
||||
|
||||
},
|
||||
"minecraft:despawn": {
|
||||
"despawn_from_distance": {
|
||||
|
||||
}
|
||||
},
|
||||
"minecraft:environment_sensor": {
|
||||
"triggers": {
|
||||
"event": "minecraft:start_transforming",
|
||||
"filters": {
|
||||
"operator": "==",
|
||||
"test": "is_underwater",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:equip_item": {
|
||||
|
||||
},
|
||||
"minecraft:health": {
|
||||
"max": 40,
|
||||
"value": 40
|
||||
},
|
||||
"minecraft:hurt_on_condition": {
|
||||
"damage_conditions": [
|
||||
{
|
||||
"cause": "lava",
|
||||
"damage_per_tick": 4,
|
||||
"filters": {
|
||||
"operator": "==",
|
||||
"subject": "self",
|
||||
"test": "in_lava",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:is_hidden_when_invisible": {
|
||||
|
||||
},
|
||||
"minecraft:jump.static": {
|
||||
|
||||
},
|
||||
"minecraft:loot": {
|
||||
"table": "loot_tables/entities/zombie.json"
|
||||
},
|
||||
"minecraft:movement.basic": {
|
||||
|
||||
},
|
||||
"minecraft:nameable": {
|
||||
|
||||
},
|
||||
"minecraft:navigation.walk": {
|
||||
"can_break_doors": true,
|
||||
"can_pass_doors": true,
|
||||
"can_walk": true,
|
||||
"is_amphibious": true
|
||||
},
|
||||
"minecraft:persistent": {
|
||||
|
||||
},
|
||||
"minecraft:physics": {
|
||||
|
||||
},
|
||||
"minecraft:pushable": {
|
||||
"is_pushable": true,
|
||||
"is_pushable_by_piston": true
|
||||
},
|
||||
"minecraft:shareables": {
|
||||
"items": [
|
||||
{
|
||||
"item": "minecraft:netherite_sword",
|
||||
"priority": 0,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:diamond_sword",
|
||||
"priority": 1,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:iron_sword",
|
||||
"priority": 2,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:stone_sword",
|
||||
"priority": 3,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:golden_sword",
|
||||
"priority": 4,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:wooden_sword",
|
||||
"priority": 5,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:netherite_helmet",
|
||||
"priority": 0,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:diamond_helmet",
|
||||
"priority": 1,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:iron_helmet",
|
||||
"priority": 2,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:chainmail_helmet",
|
||||
"priority": 3,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:golden_helmet",
|
||||
"priority": 4,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:leather_helmet",
|
||||
"priority": 5,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:turtle_helmet",
|
||||
"priority": 6,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:skull:0",
|
||||
"priority": 7,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:skull:1",
|
||||
"priority": 7,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:carved_pumpkin",
|
||||
"priority": 7,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:netherite_chestplate",
|
||||
"priority": 0,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:diamond_chestplate",
|
||||
"priority": 1,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:iron_chestplate",
|
||||
"priority": 2,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:chainmail_chestplate",
|
||||
"priority": 3,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:golden_chestplate",
|
||||
"priority": 4,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:leather_chestplate",
|
||||
"priority": 5,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:netherite_leggings",
|
||||
"priority": 0,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:diamond_leggings",
|
||||
"priority": 1,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:iron_leggings",
|
||||
"priority": 2,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:chainmail_leggings",
|
||||
"priority": 3,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:golden_leggings",
|
||||
"priority": 4,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:leather_leggings",
|
||||
"priority": 5,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:netherite_boots",
|
||||
"priority": 0,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:diamond_boots",
|
||||
"priority": 1,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:iron_boots",
|
||||
"priority": 2,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:chainmail_boots",
|
||||
"priority": 3,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:golden_boots",
|
||||
"priority": 4,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
},
|
||||
{
|
||||
"item": "minecraft:leather_boots",
|
||||
"priority": 5,
|
||||
"surplus_amount": 1,
|
||||
"want_amount": 1
|
||||
}
|
||||
],
|
||||
"singular_pickup": true
|
||||
},
|
||||
"minecraft:type_family": {
|
||||
"family": [
|
||||
"zombie",
|
||||
"undead",
|
||||
"monster",
|
||||
"mob"
|
||||
]
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"identifier": "test:guard",
|
||||
"is_experimental": false,
|
||||
"is_spawnable": true,
|
||||
"is_summonable": true
|
||||
},
|
||||
"events": {
|
||||
"minecraft:as_adult": {
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:zombie_adult"
|
||||
]
|
||||
}
|
||||
},
|
||||
"minecraft:as_baby": {
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:zombie_baby"
|
||||
]
|
||||
}
|
||||
},
|
||||
"minecraft:convert_to_drowned": {
|
||||
"sequence": [
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:convert_to_drowned"
|
||||
]
|
||||
},
|
||||
"filters": {
|
||||
"operator": "!=",
|
||||
"test": "has_component",
|
||||
"value": "minecraft:is_baby"
|
||||
},
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"minecraft:start_drowned_transformation"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:convert_to_baby_drowned"
|
||||
]
|
||||
},
|
||||
"filters": {
|
||||
"test": "has_component",
|
||||
"value": "minecraft:is_baby"
|
||||
},
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"minecraft:start_drowned_transformation"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:entity_spawned": {
|
||||
"sequence": [
|
||||
{
|
||||
"randomize": [
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:zombie_adult",
|
||||
"minecraft:can_have_equipment"
|
||||
]
|
||||
},
|
||||
"remove": {
|
||||
|
||||
},
|
||||
"weight": 380
|
||||
},
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:zombie_baby",
|
||||
"minecraft:can_have_equipment"
|
||||
]
|
||||
},
|
||||
"remove": {
|
||||
|
||||
},
|
||||
"weight": 17
|
||||
},
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:zombie_baby",
|
||||
"minecraft:zombie_jockey",
|
||||
"minecraft:can_have_equipment"
|
||||
]
|
||||
},
|
||||
"remove": {
|
||||
|
||||
},
|
||||
"weight": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"randomize": [
|
||||
{
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:can_break_doors"
|
||||
]
|
||||
},
|
||||
"weight": 10
|
||||
},
|
||||
{
|
||||
"weight": 90
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:start_transforming": {
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:start_drowned_transformation"
|
||||
]
|
||||
},
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"minecraft:look_to_start_drowned_transformation"
|
||||
]
|
||||
}
|
||||
},
|
||||
"minecraft:stop_transforming": {
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:look_to_start_drowned_transformation"
|
||||
]
|
||||
},
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"minecraft:start_drowned_transformation"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这相当的复杂,但我们仔细观察,依旧可以在`components`下找到`minecraft:behavior.`开头的相关组件。这边是与编辑器中行为组件相对应的实际文件中的实体组件。特别地,这样的组件被称为AI意向(AI Goal)组件。
|
||||
|
||||
比如,最上方的`minecraft:behavior.delayed_attack`便代表实体具有延迟攻击意向。你可以在官方参考文档[国际版 - 实体AI意向列表](https://mc.163.com/dev/mcmanual/mc-dev/mcguide/20-%E7%8E%A9%E6%B3%95%E5%BC%80%E5%8F%91/100-%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99/13-AIGoalList.html?catalog=1)中找到所有AI意向的列表。
|
||||
|
||||
每一个AI意向都可选地接受一个`priority`字段,代表该意向的优先级,优先级以值更小的为更优先。每一个AI意向也可选地接受一个`control_flags`数组,其中可以添加字符串`look`、`move`、`jump`,用于调整该意向使用的控制旗标。大部分意向的控制旗标是默认选择好的,但对于某一些意向来说,精准调整控制旗标有助于精准控制意向触发的时机,例如`minecraft:behavior.timer_flag_1`、`minecraft:behavior.timer_flag_2`、`minecraft:behavior.timer_flag_3`等计时器意向。
|
||||
|
||||
关于生物AI意向的相关机制内容,可以参考Minecraft Wiki上的[生物AI](https://zh.minecraft.wiki/w/%E7%94%9F%E7%89%A9AI)页面,学习相关内容。
|
||||
77
docs/netease-tutorial-103.4-main/6-重温:自定义生物/4-掉落.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 掉落
|
||||
|
||||
在本节中,我们学习实体的掉落物机制。
|
||||
|
||||
# 在编辑器中添加
|
||||
|
||||

|
||||
|
||||
我们可以在编辑器中添加行为包组件,并找到`minecraft:loot`。在我们的守卫实体中,该组件已经天然添加到行为包组件中了。
|
||||
|
||||

|
||||
|
||||
可以看到,实体的掉落物也是由一个战利品表控制的。这里使用了原版僵尸的战利品表。
|
||||
|
||||
## 实际文件
|
||||
|
||||

|
||||
|
||||
我们依旧查看行为包的服务端定义文件,这里我们只截取对应组件部分:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.10",
|
||||
"minecraft:entity": {
|
||||
"component_groups": {
|
||||
// ...
|
||||
},
|
||||
"components": {
|
||||
// ...
|
||||
"minecraft:loot": {
|
||||
"table": "loot_tables/entities/zombie.json"
|
||||
},
|
||||
// ...
|
||||
},
|
||||
"description": {
|
||||
"identifier": "test:guard",
|
||||
"is_experimental": false,
|
||||
"is_spawnable": true,
|
||||
"is_summonable": true
|
||||
},
|
||||
"events": {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`minecraft:loot`组件的`table`字段引用了一个战利品表。这和方块掉落物一样,我们可以用相同的格式自定义实体的掉落物,即实体的战利品。例如,我们可以把实体的战利品更改为我们的钻石苹果战利品表:
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.10",
|
||||
"minecraft:entity": {
|
||||
"component_groups": {
|
||||
// ...
|
||||
},
|
||||
"components": {
|
||||
// ...
|
||||
"minecraft:loot": {
|
||||
"table": "loot_tables/diamond_apple_loot.json"
|
||||
},
|
||||
// ...
|
||||
},
|
||||
"description": {
|
||||
"identifier": "test:guard",
|
||||
"is_experimental": false,
|
||||
"is_spawnable": true,
|
||||
"is_summonable": true
|
||||
},
|
||||
"events": {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
当我们的守卫实体被打败时,将不再掉落腐肉,而是掉落一个钻石苹果。
|
||||
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 73 KiB |