This commit is contained in:
boybook
2025-12-01 20:59:16 +08:00
parent 12738a142c
commit 760c2dd9ad
5535 changed files with 21070 additions and 2021 deletions

View File

@@ -0,0 +1,56 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/1_1.be3fdadc.jpg
hard: 进阶
time: 15分钟
---
# 自定义方块实体
#### 作者:境界
自定义方块实体是一种可以保存复杂数据结构的方块类型。与方块状态不同的概念是,方块状态更多是保存一种单一的属性。以基岩版的铁砧为例,它带有一个方块状态:"damaged"来代表铁砧的损坏程度它接受四个值broken损坏的、slightly_damaged轻微受损的、undamaged完好的、very_damaged严重受损的。而方块实体则可以保存更复杂的数据内容如一个箱子方块里保存了一个物品数据。因此方块实体就是方块的内容方块状态更多看作是方块的属性。注意自定义方块实体功能为中国版特供所以开发者无法用同样的格式在国际板上自定义方块实体。
#### 如何自定义方块实体
![](./images/1_1.jpg)
```
{
"format_version": "1.16.0",
"minecraft:block": {
"description": {
},
"components": {
"netease:block_entity": {
"tick": true,
"movable": false
}
}
}
}
```
在自定义方块的components下开发者添加一个"netease:block_entity"的组件,其中有两个键对,"tick"设置为true时当玩家进入方块tick范围时该方块每秒会发送20次ServerBlockEntityTickEvent事件设置为false时则不会像脚本层发送事件。
"movable"用来设置该自定义方块实体是否可以被活塞推动。由于基岩版的设定,所有原版方块实体都可以被活塞推动,这里也为自定义方块实体提供了这一项功能。
#### tick与不tick
在需要方块保存数据而不需要实时更新方块内的数据时可以选择将tick设置为false。
例如玩家右键交互一个自定义方块实体每20下会随机掉落一个战利品。这里的方块实体保存数据只是为了记录玩家点击自己的次数因此可以将tick设置为false。
而当需要设置tick为true时往往该自定义方块实体需要不断更新自身的数据例如自定义一个熔炉方块当方块内有燃料并且正在烧东西时方块实体自身需要维护一个不断更新的燃烧物品时间则可以将该方块实体的tick设置为true。

View File

@@ -0,0 +1,256 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/2_1.8a46d947.jpg
hard: 进阶
time: 25分钟
---
# 自定义作物
#### 作者:境界
在《我的世界》中种植一个作物需要一颗种子。因此从开发的角度来说自定义作物需要用到一个种子道具和一个自定义方块。实现自定义作物的常用方法一共有两种一种可以通过纯组件方式实现一种则需要用到MODSDK本章将会为开发者提供这两种思路去实现自己的自定义作物。
#### 开始前的准备
#### 自定义种子
![](./images/2_1.jpg)
自定义一个种子道具设置它的最大堆叠数为64个。加入"minecraft:seed"组件,其中有两个键对,"crop_result"指向种植的方块,这里命名为"design:custom_crop_0",它将作为未成熟的自定义作物方块的名称域备用。"plant_at"指向可以种植的方块,这里设置只能种植在灰化土上。
```
{
"format_version": "1.16.0",
"minecraft:item": {
"description": {
"identifier": "design:custom_crop_item",
"category": "Items"
},
"components": {
"minecraft:max_stack_size": 64,
"minecraft:seed": {
"crop_result": "design:custom_crop_0",
"plant_at": ["podzol"]
}
}
}
}
```
#### 自定义农作物方块
![](./images/2_2.jpg)
```
{
"format_version": "1.16.0",
"minecraft:block": {
"description": {
"identifier": "design:custom_crop_0"
},
"components": {
"minecraft:block_light_absorption": 0,
"minecraft:destroy_time": 0.0,
"minecraft:loot": "loot_tables/empty.json",
"netease:render_layer": {
"value": "alpha"
},
"netease:aabb": {
"collision": {
"min": [0.0, 0.0, 0.0],
"max": [0.0, 0.0, 0.0]
},
"clip": {
"min": [0.0, 0.0, 0.0],
"max": [1.0, 0.125, 1.0]
}
},
"netease:may_place_on": {
"block": ["minecraft:podzol"]
}
}
}
}
```
自定义未成熟的作物方块行为,用"minecraft:block_light_absorption"设置它的透光度为0这样方块不会在世界中产生难看的阴影。用netease:aabb将碰撞箱和射线检测碰撞箱适配实际方块的形象。用netease:render_layer将方块材质设置为透明材质。用"minecraft:destroy_time"设置它的破坏时间为0.0,用"minecraft:loot"将掉落物指向原版的空战利品表即不掉落任何掉落物。用“netease:may_place_on”设置方块只能生长在灰化土上不是灰化土则自毁。
![](./images/2_3.jpg)
自定义未成熟的作物方块材质,设置它被破坏的音效为草的音效,与原版作物方块被破坏的音效一致。将它的方块形状设置为"cross_texture",这样方块就会像原版的作物方块一样呈现一个交叉形状,适合对方块模型没有特殊要求的开发者。
```
{
"format_version": [
1,
1,
0
],
"design:custom_crop_0": {
"blockshape": "cross_texture",
"sound": "grass",
"textures": "design:custom_crop_0"
}
}
```
![](./images/2_4.jpg)
```
{
"resource_pack_name": "vanilla",
"texture_name": "atlas.terrain",
"texture_data": {
"design:custom_crop_0": {
"textures": "textures/blocks/wheat_stage_0"
}
}
}
```
最后在textures/terrain_texture.json文件如果没有就新建设置作物的资源键和资源路径。
![](./images/2_5.jpg)
在自定义方块内加入"netease:transform"组件,"condition"内放置方块的条件brightness光照控制方块在什么光照条件下生长random_tick_count为转化需要的随机tick次数surrounding为防转化需要的周围方块radius是方块半径。result是方块转化后的结果方块。
```
{
"format_version":"1.16.0",
"minecraft:block":{
"description":{
"identifier":"design:custom_crop_0"
},
"components":{
"minecraft:block_light_absorption":0,
"minecraft:destroy_time":0,
"minecraft:loot":"loot_tables/empty.json",
"netease:render_layer":{
"value":"alpha"
},
"netease:aabb":{
"collision":{
"min":[0,0,0],
"max":[0,0,0]
},
"clip":{
"min":[0,0,0],
"max":[1,0.125,1]
}
},
"netease:may_place_on":{
"block":[
"minecraft:podzol"
]
},
"netease:transform":{
"conditions":{
"brightness":{ // 农作物生长必须满足的光照条件
"max":15,
"min":9
},
"random_tick_count":{ // 转化需要的随机tick次数
"value":2
},
"surrouding":{ //转化需要的周围方块
"value":"minecraft:podzol",
"radius":1 //半径
}
},
"result":"minecraft:wheat" //转化为哪种方块
}
}
}
}
```
#### 脚本实现自定义方块
![](./images/2_6.jpg)
```
{
"format_version": "1.16.0",
"minecraft:block": {
"description": {
"identifier": "design:custom_crop_0"
},
"components": {
"minecraft:block_light_absorption": 0,
"minecraft:destroy_time": 0.0,
"minecraft:loot": "loot_tables/empty.json",
"netease:render_layer": {
"value": "alpha"
},
"netease:aabb": {
"collision": {
"min": [0.0, 0.0, 0.0],
"max": [0.0, 0.0, 0.0]
},
"clip": {
"min": [0.0, 0.0, 0.0],
"max": [1.0, 0.125, 1.0]
}
},
"netease:may_place_on": {
"block": ["minecraft:podzol"]
},
"netease:random_tick": {
"enable": true,
"tick_to_script": true
},
"netease:block_entity": {
"tick": false,
"movable": false
}
}
}
}
```
在自定义方块内加入"netease:random_tick"组件其中enable为是否启用random_tick随机时间tick_to_script为触发随机时间时是否传递BlockRandomTickServerEvent事件到脚本层。启动随机时间组件后方块会在每一个随机间隔内将事件发送到脚本层为了达到更加拟真的效果我们加入方块实体组件这样可以用来保存方块状态进行一个生长值的模拟。
![](./images/2_7.jpg)
在示例图中我们通过监听BlockRandomTickServerEvent来判断是否可以转换到下一个阶段的自定义农作物判断条件不限定于netease:transform中描述的光照、tick数量以及周边环境。同时我们还可以借助blockEntityData组件来存储数据。最后满足条件结果会将自定义作物方块转化为成熟的小麦当然也可以替换成开发者自定义的作物。

View File

@@ -0,0 +1,55 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/3_1.f808b90b.jpg
hard: 进阶
time: 15分钟
---
# 自定义管线方块
#### 作者:境界
管线方块作为一些知名模组的物质传输方块,常常出现在玩家面前。中国版当前支持制作根据接触其他方块的面显示对应连接部位的方块模型。注意:自定义连接功能为中国版特供,所以开发者无法用同样的格式在国际版为自定义方块添加该功能。
#### 资源上的定义
![](./images/3_1.jpg)
打开附件里bbmodel文件夹内的管道方块模型可以看到连接6个面的方块骨骼和内部的方块位置。
root是管道的中心骨骼当四面都没有可连接的方块时应当只显示root骨骼。当方块的南面有可连接的方块时应显示root和south骨骼其他亦然。
捋顺模型的制作思路后,还要注意的是,为了让游戏知道模型在哪个面连接到相应方块时显示哪一面的接口,还需要在最终的模型文件上进行配置。
![](./images/3_2.jpg)
如上图所示我们需要在骨骼名称的同级下打开键对“enable”值为molang语法query.is_connect(接触面)。其中接触面即方块朝向的固定值。“down”是管道下方的骨骼与此同时我们在它的骨骼同级下加入"enable": "query.is_connect(0)",即仅当下方有可连接方块时,才显示该骨骼所携带的方块。
#### 功能上的定义
![](./images/3_3.jpg)
在自定义方块内加入"netease:connection"组件,"blocks"内放置连接的方块,只有连接到这些方块,模型才会显示出连接过去的一部分。
同时,自定义方块模型会携带一部分阴影,需要将"netease:solid"的值设置为false才能关闭阴影。
由于方块拥有了比基本方块更小的体积,我们需要将方块的射线检测和碰撞体积都契合它真实的模型。
首先将aabb组件内的collision碰撞体积和clip射线检测体积都改为数组形式这样方块才能拥有多重的体积。
通过blockbench的世界坐标和方块位置、体积求得每个骨骼的实际体积需要再加入enable键对来帮助游戏控制每个连接部位的显示与否。

View File

@@ -0,0 +1,415 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/4_10.f2c5d857.jpg
hard: 进阶
time: 35分钟
---
# 简易教程①:制作一个挂载果实的树
#### 作者:境界
挂载苹果示例包下载:下载[示例包](https://g79.gdl.netease.com/guidedemo-case13.zip) 。
#### 增加苹果方块
![](./images/4_1.jpg)
#### 实现代码逻辑如下:
![](./images/4_2.jpg)
```
{
"format_version": "1.16.0",
"minecraft:block": {
"description": {
"identifier": "design:custom_apple"
},
"components": {
"minecraft:block_light_absorption": 0,
"minecraft:destroy_time": 1.0,
"netease:render_layer": {
"value": "alpha"
},
"netease:aabb": {
"collision": {
"min": [0.3125, 0.375, 0.3125],
"max": [0.6875, 1.0, 0.6875]
},
"clip": {
"min": [0.3125, 0.375, 0.3125],
"max": [0.6875, 1.0, 0.6875]
}
},
"minecraft:loot": "loot_tables/custom_apple.json",
"netease:solid": {
"value": false
},
"netease:pathable": {
"value": true
}
}
}
}
```
1首先我们将方块的透光率设置为0即将minecraft:block_light_absorption值写为0。这是由于苹果方块用到自定义模型游戏内的日夜光照会对模型进行阴影覆盖我们希望方块受到阴影的程度的影响小一些因此将值设置为0。开发者也可以根据自己的实际情况在0~15间内进行微调这是透光率组件允许接受的数值范围。
2接着用netease:render_layer将方块材质设置为透明材质以允许方块模型使用带有透明图层的贴图。
3之后在netease:aabb里将碰撞体积和射线检测贴准苹果方块真实的样子。组件中每1点对应blockbench建模空间中16格也就是每0.0625的长度对应blockbench内的一格空间。
4接着将方块设置为非实心方块这是由于我们希望避免玩家与苹果方块接触时偶尔会因为碰撞盒重叠出现窒息扣血的情况。
5接着将方块指向自定义的苹果战利品表使玩家在挖掉苹果方块后会掉落苹果物品。
6最后将方块设置为生物无视其继续循着自己的寻路路径走。
#### 添加苹果战利品表
![](./images/4_3.jpg)
1添加战利品池设置筛选次数为1次战利品入口设置为只有苹果这一个物品。
```
{
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "item",
"name": "minecraft:apple"
}
]
}
]
}
```
#### 添加苹果方块资源文件
![](./images/4_4.jpg)
```
{
"format_version": "1.13.0",
"netease:block_geometry": {
"bones": [
],
"description": {
"identifier": "design:custom_apple",
"textures": [
"design:custom_apple"
],
"use_ao": false
}
}
}
```
![](./images/4_5.jpg)
```
{
"format_version": [
1,
1,
0
],
"design:custom_apple": {
"netease_model": "design:custom_apple",
"sound": "wood"
}
}
```
1使用MCSTUDIO导出苹果方块工程文件获得json模型文件
2将模型放入材质包/models/netease_block文件夹内
3将材质放入材质包/textures/blocks文件夹内
4新建terrain_texture.json文件列入资源键和路径
5将资源键写入模型文件中将环境光遮罩关闭("use_ao": false)
6在材质包/blocks.json内配置苹果方块的模型和破坏音效
#### 制作特征
实现游戏内自然放置苹果方块,一共有三个维度。分别要用到单方块特征、检索特征、和总和特征。其中单方块特征负责设定苹果方块放置的规则、检索特征帮助苹果方块寻找放置的位置、总和特征会作为最后打包的部分被特征规则所使用。详细的细节请看以下:
#### 单方块特征
1 首先在行为包根目录下的netease_features文件夹内新建custom_apple_feature.json的特征特征类型为单方块特征。基本格式如下
```
{
    "format_version":"1.14.0",
    "minecraft:single_block_feature":{
        "description":{
            "identifier":"特征的identifier以命名空间标识符为格式其中命名空间后面的标识符还必须与文件名称匹配""
        },
        "places_block":"方块",
        "enforce_placement_rules":false,
        "enforce_survivability_rules":false,
        "may_place_on":[
            "方块"
        ],
        "may_replace":[
            "方块"
        ]
    }
}
```
2接着我们需要希望单方块特征会放置自定义的苹果方块。一共有两种写法即只指定方块类型和指定方块类型加方块状态。由于自定义的苹果方块不存在任何方块状态因此可以用places_block: “design:custom_apple”的方式。在未来开发者如果想要放置一些带有方块状态的例如原版方块。则可以参考下面放置成熟小麦的例子
```
“places_block”: {
“name”: “minecraft:wheat”,
“states”: {
“growth”: 7
}
}
```
3 之后为了能够保证苹果方块放置的其中之一条件必须是所替换的方块只能是空气方块我们在may_replace_on这个属性集合内放入minecraft:air。从常理上只有当放置规则在放置苹果方块时满足了单方块特征里只能替换掉空气方块的规则最后苹果方块才能放置成功。否则如果是替换任何一种方块则在游戏内会让玩家察觉到非常不适的视觉效果。例如苹果方块占用了叶子的位置将叶子替换成了自己。
4 紧接着为了实现能够让果实挂载在树叶底下。我们要加入may_attach_to属性字段并告知单方块特征果实会挂载在叶子的下面即方块的顶面top会贴在原版的树叶方块即树叶方块的下面。auto_rotate字段用来决定是否自动旋转方块来符合贴近规则这里我们填写false假。示例教程里我们单独挑出橡木树叶和桦木树叶作为例子。
5 最后是enforce_placement_rules和enforce_survivability_rules字段前者会触发方块自我检查是否定义了方块放在什么方块边上的行为后者会触发方块自我检查是否定义了方块可以在什么方块上存活保留的行为。由于自定义方块功能当前没有存活条件的行为我们将此enforce_survivability_rules字段设置为falseenforce_placement_rules设置为true。
![](./images/4_6.jpg)
```
{
"format_version": "1.14.0",
"minecraft:single_block_feature": {
"description": {
"identifier": "design:custom_apple_feature"//特征名称域
},
"places_block": {
"name": "design:custom_apple",//方块名称域
"states": {}
},
"enforce_placement_rules": true,//是否根据放置规则放置特征这里要写为true真
"enforce_survivability_rules": false,
"may_attach_to": {
"auto_rotate": false,
"min_sides_must_attach": 1,
"top": [
{
"name": "minecraft:leaves",// 方块必须上部贴住橡树树叶才会生成
"states": {
"old_leaf_type": "oak"
}
},
{
"name": "minecraft:leaves",// 方块必须上部贴住桦树树叶才会生成
"states": {
"old_leaf_type": "birch"
}
}
]
},
"may_replace": [//只会在有空气的位置替换成苹果方块
"minecraft:air"
]
}
}
```
#### 检索特征
![](./images/4_7.jpg)
1首先在行为包根目录下的netease_features文件夹内新建custom_apple_search_feature.json的特征特征类型为检索特征。基本格式如下
```
{
"format_version":”1.14.0”,
"minecraft:search_feature": {
"description": {
"identifier": "特征的identifier以命名空间标识符为格式其中命名空间后面的标识符还必须与文件名称匹配""
},
"places_feature": "特征identifier",
"search_volume": {
"min": [ -3, -3, -3 ],
"max": [ 3, 3, 3 ]
},
"search_axis": "-y",
"required_successes": 3
}
```
2然后我们将检索特征下所放置的特征挂载为前面设定的苹果单方块特征。
3紧接着我们将检索特征会寻找的放置坐标范围这需要用到search_volume对象在min和max中进行调整。min代表左下角起点max代表右上角最大点。这样拉出来的空间是一个方型。我们希望在之后和原版数特征组合用总和特征打包起来后检索特征会检索前一个树木特征放下来后从它的特征放置点下在最小点到最大点的空间内进行偏移寻找空间内是否有树叶并且必须满足前面单方块特征的条件包括苹果方块只能替换空气方块以及放置单方块特征时必须是树叶下面的坐标点。这样子特征联动的效果就打通了。
4接着我们将寻找的位置从这个空间开始出发以最小点【000】即检索特征被放置的坐标点开始以Y轴往上进行向x轴正8格Y轴正16格Z轴正8格的方向去寻找树叶。当然在search_axis字段内不仅允许从Y轴往上的方向去寻找也可以从其他方向去找这其中包括-x、+x、-y、+y、-z、+z。
5最后required_successes字段用来指定寻找到的合适放置苹果方块的坐标究竟要达到多少个整个特征才会正确放置。如果最后找到的坐标不满足要求的数量则整个特征就会放置失败。在许多情况下这个也属于情理之中因为有些树可能紧靠在一些突起的地貌环境树叶的数量不足以挂接这么多的苹果亦或是总和特征中放置的树木大小本来就小承载不了要求的最低数量的苹果方块。但这也让环境变得更加多样变化与不同了。
```
{
"format_version": "1.14.0",
"minecraft:search_feature": {
"description": {
"identifier": "design:custom_apple_search_feature"//自定义名称域
},
"places_feature": "design:custom_apple_feature",//放置的规则为前面自定义的单方块特征
"search_volume": {//寻找的位置是从放置坐标开始位移X轴正8格、Y轴16格、Z轴8格内的体积内
"min": [ 0, 0, 0 ],
"max": [ 8, 16, 8 ]
},
"search_axis": "+y",//寻找的位置从设定的点开始以Y轴往上
"required_successes": 5
//至少要有5个可放置苹果的位置该特征才会放置成功
}
}
```
![](./images/4_8.jpg)
#### 总和特征
1 在行为包根目录下/netease_features文件夹内新建oak_tree_with_custom_apple_feature.json的特征特征类型为总和特征。它的基本格式如下
```
{
"format_version": “1.14.0”,
"minecraft:aggregate_feature": {
"description": {
"identifier": "特征的identifier以命名空间标识符为格式其中命名空间后面的标识符还必须与文件名称匹配"
},
"features": [
“特征1”
“特征2”
]
}
}
```
2这里我们将写好的检索特征和原版的橡木树木特征放在里面。需要注意的是在features内写好的特征所处于的顺序不代表它们最终放置的顺序。因此有时候可能是先尝试放置了树木特征后再尝试放置苹果有时候则相反。因此通过这个特征所放置的橡木不一定全部都挂接着苹果因为先尝试放置苹果的检索特征大概率会导致检索特征放置失败因为可能树木特征还没有来得及放下去所放置的坐标点此时可能光秃秃一片。但这也符合常理毕竟不是所有野外的树木都挂载着果实。如果开发者希望做到必须挂接着果实的树木可以期待后续的教程更新中关于 队列特征的内容。
```
{
"format_version": "1.14.0",
"minecraft:aggregate_feature": {
"description": {
"identifier": "design:oak_tree_with_custom_apple_feature"
},
"features": [
"minecraft:oak_tree_feature",
"design:custom_apple_search_feature"
]
}
}
```
#### 特征规则
![](./images/4_9.jpg)
1首先在行为包根目录下/netease_feature_rules文件夹内新建overworld_apple_oak_tree_feature.json的特征规则。
2接着我们需要设定特征放置的群系条件通过conditions对象我们希望整个主世界的群系都能够长出带有苹果方块的橡木。但请不用担心这会让我们在例如海洋、冰原群系也看得到它因为原版的橡木特征里会携带着橡木能够生长在什么方块上的规则因此奇怪的群系是看不到苹果树的。每个主世界群系都会携带overworld的标签因此只要判断是否携带overworld标签就能够放置在整个主世界维度当中。
3最后我们在分布规则distribution里在iterations中写下数字1即每一个区块尝试放置一次。在区块内放置时我们希望特征遵守先确定好X和Z轴再决定Y轴的规则我们希望X和Z坐标取从区块起始坐标开始随机偏移0~16格的范围内的其中一个点。在Y轴在X和Z轴点确定下这个点位置最高的非实心方块Y轴坐标点。保证树木会放置在地面上而不是可能在地面中或者地面下。
```
{
"format_version": "1.14.0",
"minecraft:feature_rules": {
"description": {
"identifier": "design:overworld_apple_oak_tree_feature",
"places_feature": "design:oak_tree_with_custom_apple_feature"
},
"conditions": {
"placement_pass": "surface_pass",
"minecraft:biome_filter": [
{
"test": "has_biome_tag",
"operator": "==",
"value": "overworld"
}
]
},
"distribution": {
"iterations": 1,
"x": {
"distribution": "uniform",
"extent": [ 0, 16 ]
},
"y": "query.heightmap(variable.worldx, variable.worldz)",
"z": {
"distribution": "uniform",
"extent": [ 0, 16 ]
}
}
}
}
```
#### 效果图如下:
![](./images/4_10.jpg)

View File

@@ -0,0 +1,167 @@
---
front: https://mc.res.netease.com/pc/zt/20201109161633/mc-dev/assets/img/5_5.d0bc082b.jpg
hard: 进阶
time: 25分钟
---
# 简易教程②:制作一个加速作物生长的火把方块
#### 作者:境界
加速火把示例包下载:下载[示例包](https://g79.gdl.netease.com/guidedemo-case13.zip) 。
#### 火把方块示意图:
![5_1](./images/5_1.jpg)
#### 增加火把方块行为包
![](./images/5_2.jpg)
```
{
"format_version": "1.16.0",
"minecraft:block": {
"description": {
"identifier": "design:custom_torch"
},
"components": {
"minecraft:block_light_absorption": 0,
"minecraft:block_light_emission": 1.0,
"minecraft:destroy_time": 1.0,
"netease:render_layer": {
"value": "alpha"
},
"netease:aabb": {
"collision": {
"min": [0.4375, 0.0, 0.4375],
"max": [0.5625, 0.6875, 0.5625]
},
"clip": {
"min": [0.4375, 0.0, 0.4375],
"max": [0.5625, 0.6875, 0.5625]
}
},
"netease:solid": {
"value": false
},
"netease:pathable": {
"value": true
},
"netease:block_entity": {
"tick": true,
"movable": false
}
}
}
}
```
1首先我们将方块的透光率设置为0即将minecraft:block_light_absorption值写为0。这是由于火把方块用到自定义模型游戏内的日夜光照会对模型进行阴影覆盖我们希望方块受到阴影的程度的影响小一些因此将值设置为0。开发者也可以根据自己的实际情况在0~15间内进行微调这是透光率组件允许接受的数值范围。
2接着使用minecraft:block_light_emission组件将发光程度调成1.0使火把会在游戏内产生发光效果。开发者也可以根据自己的实际情况在0.0~1.0间内进行微调,这是发光组件允许接受的数值范围。
2接着用netease:render_layer将方块材质设置为透明材质以允许方块模型使用带有透明图层的贴图。
3之后在netease:aabb里将碰撞体积和射线检测贴准火把方块真实的样子。组件中每1点对应blockbench建模空间中16格也就是每0.0625的长度对应blockbench内的一格空间。
4接着将方块设置为非实心方块这是由于我们希望避免玩家与苹果方块接触时偶尔会因为碰撞盒重叠出现窒息扣血的情况。
5紧接着我们使用一个方块自定义的小技巧即不设置方块的掉落物。那么在游戏内方块默认会掉落方块物品本身。
6最后将方块设置为生物无视其继续循着自己的寻路路径走。
#### 增加火把方块材质包
1使用MCSTUDIO导出火把方块工程文件获得json模型文件
2将模型文件的贴图资源指向原版的火把贴图"torch_on",将环境光遮罩关闭("use_ao": false)
3在材质包/blocks.json内配置火把方块的模型和破坏音效
#### 脚本实现自定义方块
![](./images/5_3.jpg)
```
{
"format_version": "1.16.0",
"minecraft:block": {
"description": {
"identifier": "design:custom_torch"
},
"components": {
"netease:block_entity": {
"tick": true,
"movable": false
}
}
}
}
```
在自定义方块内加入"netease:block_entity"组件其中设置tick为真movable为假。加速火把方块会在每一秒发送20次事件到脚本层即 每一次事件间隔为1 / 20 = 0.05秒。
![](./images/5_4.jpg)
在示例图中我们通过监听ServerBlockEntityTickEvent来判断是否可以将小麦变成下一个生长程度判定条件为小麦是否是成熟状态注意本加速火把示例中只对小麦种子加速有效果其他种子无效果。
```
def torch_grow(self, event):
x = event['posX'] # 获取坐标X
y = event['posY'] # 获取坐标Y
z = event['posZ'] # 获取坐标Z
block_name = event['blockName']
if block_name != 'design:custom_torch': # 是否为自定义加速方块
return
dim_id = event['dimension'] # 获取维度ID
block_comp = serverApi.GetEngineCompFactory().CreateBlockInfo(serverApi.GetLevelId())
block_state_comp = serverApi.GetEngineCompFactory().CreateBlockState(serverApi.GetLevelId())
block_entity_comp = serverApi.GetEngineCompFactory().CreateBlockEntityData(serverApi.GetLevelId())
block_entity_data = block_entity_comp.GetBlockEntityData(dim_id, (x, y, z)) # 获取方块数据
tick = block_entity_data['tick'] # 获取方块刷新次数
if not tick:
tick = 0
tick += 1 # 加速火把方块会在每一帧自增一次刷新次数
block_entity_data['tick'] = tick
if tick % 20 != 0: # 根据文档可知事件会在一秒刷新20次当刷新次数与20求模为0时即过了一秒钟
return
# 运用列表推导式,获得[(x - 1, y, z - 1), (x, y, z - 1), (x + 1, y, z - 1), (x + 1, y, z + 1), (x, y, z),
# (x - 1, y, z + 1), (x, y, z + 1), (x - 1, y, z), (x + 1, y, z)]的坐标列表
grow_poses = [(x + x_offset, y, z + z_offset) for x_offset in xrange(-1, 2) for z_offset in xrange(-1, 2)]
grow_poses.remove((x, y, z)) # 由于坐标(x, y, z)是加速火把,所以移除这个坐标
for grow_pos in grow_poses:
block = block_comp.GetBlockNew(grow_pos, dim_id)
if block and block['name'] == 'minecraft:wheat': # 如果是小麦
block_state = block_state_comp.GetBlockStates(grow_pos, dim_id)
if block_state['growth'] < 7: # 且小麦还未成熟即成长值小于7
block_state['growth'] += 1 # 增加一级成长值
block_state_comp.SetBlockStates(grow_pos, block_state, dim_id)
```
#### 最终效果如下:
![](./images/5_5.jpg)