367 lines
11 KiB
Markdown
367 lines
11 KiB
Markdown
---
|
||
front: https://nie.res.netease.com/r/pic/20211104/69055361-2e7a-452f-8b1a-f23e1262a03a.jpg
|
||
hard: 进阶
|
||
time: 25分钟
|
||
---
|
||
|
||
# 让实体在水中悬浮
|
||
|
||
我们知道,鸭子都喜欢在水面上游动。鸭子在游动的时候,虽然双脚在水中拍打,但是在水面上却极为平稳。成语“鸭子凫水”便意味着暗地使劲,明面上看不出来的行为。而我们目前的水鸭在水中漂浮时却仅仅是像其他生物一样,一上一下。在本节中,我们将我们的鸭子的行为改为在水面上持续悬浮。
|
||
|
||
## 在原版实体中找到对应的组件
|
||
|
||
我们在原版实体中回忆哪种实体存在悬浮在液体表面的行为。不难发现,赤足兽便是一种可以在熔岩表面悬浮的实体。因此,赤足兽的行为文件中必定存在一种可以用于悬浮的组件。我们打开赤足兽的行为文件来一探究竟。由于在水面漂浮应该是一种AI意向,我们着重关注带有`behavior.`前缀的组件。
|
||
|
||
```json
|
||
"minecraft:behavior.rise_to_liquid_level": {
|
||
"priority": 0,
|
||
"liquid_y_offset": 0.25,
|
||
"rise_delta": 0.01,
|
||
"sink_delta": 0.01
|
||
},
|
||
"minecraft:behavior.move_to_lava": {
|
||
"priority": 7,
|
||
"search_range": 16,
|
||
"search_height": 10,
|
||
"goal_radius": 0.9,
|
||
"search_count": 30
|
||
},
|
||
"minecraft:behavior.random_stroll": {
|
||
"priority": 8,
|
||
"speed_multiplier": 0.8
|
||
},
|
||
"minecraft:behavior.look_at_player": {
|
||
"priority": 9,
|
||
"look_distance": 6.0,
|
||
"probability": 0.02
|
||
},
|
||
"minecraft:behavior.random_look_around": {
|
||
"priority": 10
|
||
},
|
||
"minecraft:behavior.panic": {
|
||
"priority": 3,
|
||
"speed_multiplier": 1.1,
|
||
"panic_sound": "panic",
|
||
"sound_interval": {
|
||
"range_min": 1.0,
|
||
"range_max": 3.0
|
||
}
|
||
},
|
||
"minecraft:behavior.tempt": {
|
||
"priority": 5,
|
||
"speed_multiplier": 1.2,
|
||
"items": [
|
||
"warped_fungus",
|
||
"warped_fungus_on_a_stick"
|
||
],
|
||
"tempt_sound": "tempt",
|
||
"sound_interval": {
|
||
"range_min": 2.0,
|
||
"range_max": 5.0
|
||
}
|
||
}
|
||
```
|
||
|
||
很快,我们便能通过其组件名的字面意思定位到`priority`优先级为0的那个组件`minecraft:behavior.rise_to_liquid_level`。事实上,这个确实就是能够使赤足兽悬浮的AI意向。我们将其复制到鸭子中。
|
||
|
||
## 实现水鸭的行为
|
||
|
||
我们稍作修改,然后将其复制到水鸭的行为定义文件中。
|
||
|
||
```json
|
||
"minecraft:behavior.rise_to_liquid_level": {
|
||
"priority": 0,
|
||
"liquid_y_offset": -0.5,
|
||
"rise_delta": 0.01,
|
||
"sink_delta": 0.01
|
||
}
|
||
```
|
||
|
||
这并没有结束。因为我们知道,水鸭之所以会在水面上上下浮动是因为另一个AI意向也在起作用,那就是`minecraft:behavior.float`。我们删除这个AI意向。
|
||
|
||
最后,我们更改水鸭的导航组件。因为我们删除了`minecraft:behavior.float`,水鸭的AI便不再要求水鸭持续浮在水面上,所以我们在水鸭的导航组件`minecraft:navigation.walk`中加入`can_sink`并设置为`false`。这样,水鸭在水中便不会下沉。
|
||
|
||
```json
|
||
"minecraft:navigation.walk": {
|
||
"can_path_over_water": true,
|
||
"can_sink": false,
|
||
"avoid_damage_blocks": true
|
||
}
|
||
```
|
||
|
||
至此,我们从理论上边实现了水鸭的行为替换。
|
||
|
||
```json
|
||
{
|
||
"format_version": "1.16.0",
|
||
"minecraft:entity": {
|
||
"description": {
|
||
"identifier": "tutorial_demo:teal",
|
||
"runtime_identifier": "minecraft:chicken",
|
||
"is_spawnable": true,
|
||
"is_summonable": true,
|
||
"is_experimental": false
|
||
},
|
||
"component_groups": {
|
||
"minecraft:teal_baby": {
|
||
"minecraft:is_baby": {},
|
||
"minecraft:scale": {
|
||
"value": 0.5
|
||
},
|
||
"minecraft:ageable": {
|
||
"duration": 1200,
|
||
"feed_items": ["wheat_seeds", "beetroot_seeds", "melon_seeds", "pumpkin_seeds"],
|
||
"grow_up": {
|
||
"event": "minecraft:ageable_grow_up",
|
||
"target": "self"
|
||
}
|
||
},
|
||
"minecraft:behavior.follow_parent": {
|
||
"priority": 5,
|
||
"speed_multiplier": 1.1
|
||
}
|
||
},
|
||
"minecraft:teal_adult": {
|
||
"minecraft:experience_reward": {
|
||
"on_bred": "Math.Random(1,7)",
|
||
"on_death": "query.last_hit_by_player?Math.Random(1,3):0"
|
||
},
|
||
"minecraft:loot": {
|
||
"table": "loot_tables/entities/chicken.json"
|
||
},
|
||
"minecraft:breedable": {
|
||
"require_tame": false,
|
||
"breeds_with": {
|
||
"mate_type": "tutorial_demo:teal",
|
||
"baby_type": "tutorial_demo:teal",
|
||
"breed_event": {
|
||
"event": "minecraft:entity_born",
|
||
"target": "baby"
|
||
}
|
||
},
|
||
"breed_items": ["wheat_seeds", "beetroot_seeds", "melon_seeds", "pumpkin_seeds"]
|
||
},
|
||
"minecraft:behavior.breed": {
|
||
"priority": 3,
|
||
"speed_multiplier": 1
|
||
},
|
||
"minecraft:rideable": {
|
||
"seat_count": 1,
|
||
"family_types": ["zombie"],
|
||
"seats": {
|
||
"position": [0, 0.4, 0]
|
||
}
|
||
},
|
||
"minecraft:spawn_entity": {
|
||
"entities": {
|
||
"min_wait_time": 300,
|
||
"max_wait_time": 600,
|
||
"spawn_sound": "plop",
|
||
"spawn_item": "egg",
|
||
"filters": {
|
||
"test": "rider_count",
|
||
"subject": "self",
|
||
"operator": "==",
|
||
"value": 0
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"components": {
|
||
"minecraft:type_family": {
|
||
"family": ["chicken", "mob"]
|
||
},
|
||
"minecraft:breathable": {
|
||
"total_supply": 15,
|
||
"suffocate_time": 0
|
||
},
|
||
"minecraft:collision_box": {
|
||
"width": 0.6,
|
||
"height": 0.8
|
||
},
|
||
"minecraft:nameable": {},
|
||
"minecraft:health": {
|
||
"value": 4,
|
||
"max": 4
|
||
},
|
||
"minecraft:hurt_on_condition": {
|
||
"damage_conditions": [
|
||
{
|
||
"filters": {
|
||
"test": "in_lava",
|
||
"subject": "self",
|
||
"operator": "==",
|
||
"value": true
|
||
},
|
||
"cause": "lava",
|
||
"damage_per_tick": 4
|
||
}
|
||
]
|
||
},
|
||
"minecraft:movement": {
|
||
"value": 0.25
|
||
},
|
||
"minecraft:damage_sensor": {
|
||
"triggers": {
|
||
"cause": "fall",
|
||
"deals_damage": false
|
||
}
|
||
},
|
||
"minecraft:leashable": {
|
||
"soft_distance": 4,
|
||
"hard_distance": 6,
|
||
"max_distance": 10
|
||
},
|
||
"minecraft:balloonable": {
|
||
"mass": 0.5
|
||
},
|
||
"minecraft:navigation.walk": {
|
||
"can_path_over_water": true,
|
||
"can_sink": false, // 添加不会下沉
|
||
"avoid_damage_blocks": true
|
||
},
|
||
"minecraft:movement.basic": {},
|
||
"minecraft:jump.static": {},
|
||
"minecraft:can_climb": {},
|
||
"minecraft:despawn": {
|
||
"despawn_from_distance": {}
|
||
},
|
||
"minecraft:behavior.rise_to_liquid_level": {
|
||
"priority": 0,
|
||
"liquid_y_offset": -0.5,
|
||
"rise_delta": 0.01,
|
||
"sink_delta": 0.01
|
||
}, // 添加赤足兽的悬浮行为
|
||
"minecraft:behavior.panic": {
|
||
"priority": 1,
|
||
"speed_multiplier": 1.5
|
||
},
|
||
"minecraft:behavior.mount_pathing": {
|
||
"priority": 2,
|
||
"speed_multiplier": 1.5,
|
||
"target_dist": 0,
|
||
"track_target": true
|
||
},
|
||
"minecraft:behavior.tempt": {
|
||
"priority": 4,
|
||
"speed_multiplier": 1,
|
||
"items": ["wheat_seeds", "beetroot_seeds", "melon_seeds", "pumpkin_seeds"]
|
||
},
|
||
"minecraft:behavior.random_stroll": {
|
||
"priority": 6,
|
||
"speed_multiplier": 1
|
||
},
|
||
"minecraft:behavior.look_at_player": {
|
||
"priority": 7,
|
||
"look_distance": 6,
|
||
"probability": 0.02
|
||
},
|
||
"minecraft:behavior.random_look_around": {
|
||
"priority": 8
|
||
},
|
||
"minecraft:physics": {},
|
||
"minecraft:pushable": {
|
||
"is_pushable": true,
|
||
"is_pushable_by_piston": true
|
||
},
|
||
"minecraft:conditional_bandwidth_optimization": {}
|
||
},
|
||
"events": {
|
||
"from_egg": {
|
||
"add": {
|
||
"component_groups": ["minecraft:teal_baby"]
|
||
}
|
||
},
|
||
"minecraft:entity_spawned": {
|
||
"randomize": [
|
||
{
|
||
"weight": 95,
|
||
"trigger": "minecraft:spawn_adult"
|
||
},
|
||
{
|
||
"weight": 5,
|
||
"add": {
|
||
"component_groups": ["minecraft:teal_baby"]
|
||
}
|
||
}
|
||
]
|
||
},
|
||
"minecraft:entity_born": {
|
||
"remove": {},
|
||
"add": {
|
||
"component_groups": ["minecraft:teal_baby"]
|
||
}
|
||
},
|
||
"minecraft:ageable_grow_up": {
|
||
"remove": {
|
||
"component_groups": ["minecraft:teal_baby"]
|
||
},
|
||
"add": {
|
||
"component_groups": ["minecraft:teal_adult"]
|
||
}
|
||
},
|
||
"minecraft:spawn_adult": {
|
||
"add": {
|
||
"component_groups": ["minecraft:teal_adult"]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
但是事实上,由于某些缺陷,我们当前的水鸭在实际游戏中依旧会无视`minecraft:behavior.rise_to_liquid_level`行为并给自己添加一个`minecraft:behavior.float`行为。这会导致我们的行为替换失败。这是由于我们的水鸭包是Blockbench生成的,使用了微软最新的清单文件格式版本,我们需要将清单文件中格式版本从2改为1才能消除这一隐患。
|
||
|
||
同样地,我们在资源包中也需要将清单文件的格式版本从2替换为1,否则将因为格式版本的不对应导致水鸭的贴图无法加载。由于格式版本的改变,这将影响到最低引擎版本,所以我们将资源包中的最低引擎版本删除,否则将导致加载失败。
|
||
|
||
```json
|
||
{
|
||
"format_version": "1.10.0",
|
||
"minecraft:client_entity": {
|
||
"description": {
|
||
"identifier": "tutorial_demo:teal",
|
||
//"min_engine_version": "1.12.0",
|
||
"materials": {
|
||
"default": "chicken",
|
||
"legs": "chicken_legs"
|
||
},
|
||
"textures": {
|
||
"default": "textures/entity/teal"
|
||
},
|
||
"geometry": {
|
||
"default": "geometry.teal"
|
||
},
|
||
"animations": {
|
||
"move": "animation.teal.move",
|
||
//"general": "animation.teal.general",
|
||
"look_at_target": "animation.common.look_at_target",
|
||
"baby_transform": "animation.teal.baby_transform"
|
||
},
|
||
"scripts": {
|
||
"animate": [
|
||
//"general",
|
||
{
|
||
"move": "query.modified_move_speed"
|
||
},
|
||
"look_at_target",
|
||
{
|
||
"baby_transform": "query.is_baby"
|
||
}
|
||
]
|
||
},
|
||
"render_controllers": ["controller.render.chicken"],
|
||
"spawn_egg": {
|
||
"base_color": "#62c287",
|
||
"overlay_color": "#87692b"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
同时,我们将`general`动画删除。`general`动画是硬编码的翅膀煽动动画,鸭子在水中或空气中都会播放该动画。但是,众所周知,鸭子游泳时翅膀是不煽动的,所以我们直接删除此动画。
|
||
|
||

|
||
|
||
我们进入游戏,可以看到我们鸭子确实拥有了悬浮的AI意向! |