first commit

This commit is contained in:
boybook
2025-03-17 13:24:39 +08:00
commit 9a0334ee84
6410 changed files with 221907 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义方块概述
<span id="customBlockJump"></span>
该功能不需要开启实验性玩法。
开发者可以通过在addon中配置json来添加自定义方块。添加的自定义方块支持ModAPI中与方块及物品相关的所有事件及接口。
## 注册
以demo [CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)为例:
1. 在行为包中新建`netease_blocks`目录
![reg-1](./picture/customblock/reg_1.png)
2. 在目录下新建一个json用于编写方块的定义。json的格式可参考[官方wiki](https://minecraft.gamepedia.com/Bedrock_Edition_blocks_documentation)。
![reg-2](./picture/customblock/reg-2.png)
![reg-3](./picture/customblock/reg-3.png)
- json中至少有一个component
- **identifier**的格式为:命名空间[冒号]方块名。命名空间推荐与mod名称一致。而冒号后的**方块名**必须全局唯一为避免与原版方块以及其他mod重复**请加上命名空间作为前缀来保证唯一**。
(例如图中的<font size="5" style="font-weight: bold;">customblocks:<font color="red">customblocks_</font>test0</font>
而不要写成customblocks:test0。
- **mod中其他地方都是用这个identifier与这个自定义方块对应上**。
3. 将方块的贴图放到`textures\blocks`
可以支持高于16x16分辨率的高清贴图但需要注意过高的分辨率会导致手机端尤其是低端机上无法进入游戏。
![reg-4](./picture/customblock/reg-4.png)
4. 在textures中新建`terrain_texture.json`编写资源名与贴图的对应关系。资源名的命名必须满足全局唯一。json格式可参考“Mod PC开发包”的`data\resource_packs\vanilla\textures\terrain_texture.json`
![reg-5](./picture/customblock/reg-5.png)
![reg-6](./picture/customblock/reg-6.png)
5. 在resource中新建一个`blocks.json`,编写方块贴图及声音,贴图的值需要与上一步`terrain_texture.json`中配置的资源名对应。json格式可参考“Mod PC开发包”的`data\resource_packs\vanilla\blocks.json`
![reg-7](./picture/customblock/reg-7.png)
![reg-8](./picture/customblock/reg-8.png)
6.`texts\zh_CN.lang`中配置方块中文名称:
键的格式为`tile.方块identifier.name`
![reg-9](./picture/customblock/reg-9.png)
![reg-10](./picture/customblock/reg-10.png)
7. 重复1-6编写其他自定义方块
## 卸载
若使用了自定义方块的存档卸载mod后再进入时
1. 对地图上已存在的自定义方块:
1自定义方块会变为未知的方块。如果用GetBlockNew接口获取它的信息indentifier是之前的自定义方块。生存模式下玩家可以用手瞬间破坏这个未知的方块生成掉落物且可以拾取。拾取到背包后显示的物品名字为”未知“且无法放置到世界中。
2若某个subchunk未进行过方块更新那么重新加载mod时自定义方块会保留。但一旦subchunk进行了方块更新即使重新加载mod自定义方块会永远消失。
2. 对玩家背包中的自定义方块:
物品会消失。若重新加载mod对卸载期间登录过的玩家物品不会恢复没登录过的玩家物品可以保留。
3. 对地图上容器内的自定义方块:
物品会消失。若重新加载mod对卸载期间进行探索过的区域内的容器物品不会恢复未探索区域的容器物品可以保留。
4. 对地图上未捡起的掉落物:
掉落物会消失。若重新加载mod对卸载期间进行探索过的区域掉落物不会恢复除非subchunk内没有其他任何entity未探索区域的掉落物可以保留。

View File

@@ -0,0 +1,409 @@
---
front:
hard: 入门
time: 分钟
---
# JSON组件
## format_version
基岩版自定义方块的json结构曾经过多次调整当填写format_version时需要按照对应版本的json结构编写components。
你可以在以下两个版本进行选择:
- 1.16.0
该版本的components结构详见[bedrock.dev](https://bedrock.dev/zh/docs/1.16.0.0/1.16.0.66/Blocks)。
- 1.10.0
该版本的components结构详见[bedrock.dev](https://bedrock.dev/zh/docs/1.12.0.0/1.12.0.28/Blocks)。该版本相比于1.16.0component的值为一个Json Object例如`minecraft:destroy_time`在1.10.0中为
```json
"minecraft:destroy_time": {
"value": 4.0
}
```
而在更高的版本中为
```json
"minecraft:destroy_time": 4.0
```
## description
| 键 | 类型 | 默认值 | 解释 |
| ----------------------- | ---- | ------ | ------------------------------------------------------------ |
| identifier | str | | 包括命名空间及物品名。需要全局唯一。<br>建议使用mod名称作为命名空间 |
| register_to_create_menu | bool | false | 是否注册到创造栏 |
| category | str | Nature | 注册到创造栏的分类,可选的值有:<br>Construction<br>Nature<br>Equipment<br>Items |
## components
目前行为包中自定义方块json中支持的component包括原版component和网易独有的component。minecraft开头的为原版componentnetease开头的为网易独有component。
对于原版component你可以在上方的format_version解释中找到更多的参数及解释。
<span id="minecraft_loot"></span>
### minecraft:loot
可用于使用loot table控制掉落物
可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)的customblocks:customblocks_test_ore方块
<span id="minecraft_destroy_time"></span>
### minecraft:destroy_time
可用于控制挖掘所需的时间。该值的含义与[官方wiki](https://minecraft-zh.gamepedia.com/%E6%8C%96%E6%8E%98#.E6.96.B9.E5.9D.97.E7.A1.AC.E5.BA.A6)的“硬度”一致
主要用于[挖掘](./2-功能.md#wajue)的功能
<span id="minecraft_block_light_emission"></span>
### minecraft:block_light_emission
可用于设置方块亮度。关于亮度及方块光源可参考[官方wiki](https://minecraft-zh.gamepedia.com/%E4%BA%AE%E5%BA%A6)
主要用于[亮度](./2-功能.md#liangdu)的功能
<span id="minecraft_explosion_resistance"></span>
### minecraft:explosion_resistance
可用于设置爆炸抗性。原版方块的爆炸抗性见[官方wiki](https://minecraft-zh.gamepedia.com/%E7%88%86%E7%82%B8#.E7.88.86.E7.82.B8.E6.8A.97.E6.80.A7)
<span id="minecraft_block_light_absorption"></span>
### minecraft:block_light_absorption
可用于设置方块的透光率。具体可参考[官方wiki](https://minecraft-zh.gamepedia.com/%E4%BA%AE%E5%BA%A6#.E9.98.BB.E7.A2.8D.E5.85.89.E7.85.A7.E7.9A.84.E6.96.B9.E5.9D.97)
默认为不透光。
主要用于[亮度](./2-功能.md#liangdu)的功能
<span id="minecraft_map_color"></span>
### minecraft:map_color
可用于设置方块显示在地图上的颜色
<span id="netease_tier"></span>
### netease:tier
用于设置与挖掘相关的属性
主要用于[挖掘](./2-功能.md#wajue)的功能
| 键 | 类型 | 默认值 | 解释 |
| :-------------: | :----: | :----: | :----------------------------------------------------------- |
| digger | string | | 必须设置。表示方块使用此工具挖掘时有速度加成。<br>可选的值有:<br> shovel铲<br> pickaxe镐<br> hatchet斧 |
| destroy_special | bool | false | 可选。<br>当设置为true时表示只有使用digger设置的工具进行挖掘才会产生掉落物。 |
| level | int | 0 | 可选。<br>当destroy_special为true时才会生效。表示挖掘所需的工具等级若手持工具等级小于该值则不会产生掉落物。<br>原版工具的等级:<br> 空手/其他非工具物品0<br> 木制/金制工具0<br> 石制工具1<br> 铁制工具2<br> 钻石工具3 |
<span id="netease_aabb"></span>
### netease:aabb
用于设置方块的碰撞盒
**注意事项:**
1. 无碰撞箱的方块请将collision的每个项都设置为0
2. 有碰撞箱的方块clip的范围需要小于或等于collision的范围否则弹射物命中时会异常
3. aabb的min不要小于[-1, -1, -1]max不要大于[2, 2, 2]
可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)的customblocks_model_flower及customblocks_model_wire方块。
| 键 | 类型 | 默认值 | 解释 |
| --------- | ------------- | ------ | ------------------------------------------------------------ |
| collision | object或array | | 计算与物体碰撞时用的碰撞盒 |
| clip | object或array | | 计算射线检测时用的碰撞盒。如准心选取及弹射物碰撞。<br>那么当该AABB没有体积时准心与弹射物都会无视这个方块 |
当collision或clip为object时用于表示恒定大小的单一碰撞盒结构为
| 键 | 类型 | 默认值 | 解释 |
| ---- | ------------ | --------- | ---------------------------------- |
| min | array(float) | [0, 0, 0] | min的三个值必须小于等于max的三个值 |
| max | array(float) | [1, 1, 1] | |
当collision或clip为array时用于可变化的多个碰撞盒的组合通常用于可变化的自定义方块模型。元素的结构为
| | 类型 | 默认值 | 解释 |
| ------ | ------------ | --------- | ------------------------------------------------------------ |
| enable | molang | true | 控制是否开启该碰撞箱<br/>目前仅支持is_connect查询详见[netease:connection](#netease_connection) |
| min | array(float) | [0, 0, 0] | min的三个值必须小于等于max的三个值 |
| max | array(float) | [1, 1, 1] | |
<span id="netease_face_directional"></span>
### netease:face_directional
用于设置方块的多面向
主要用于[多面向](./2-功能.md#duomianxiang)的功能
| 键 | 类型 | 默认值 | 解释 |
| ---- | ------ | ------ | ----------------------------------------------------- |
| type | string | | direction四面向方块<br>facing_direction六面向方块 |
<span id="netease_render_layer"></span>
### netease:render_layer
用于设置方块渲染时使用的材质
可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)的customblocks:customblocks_model_flower方块。
| 键 | 类型 | 默认值 | 解释 |
| ----- | ------ | ------ | ------------------------------------------------------------ |
| value | string | | 目前支持的材质有:<br>opaque不透明即“terrain_opaque”材质。默认为此项<br>alpha全透明即“terrain_alpha”材质如火焰树叶。<br>blend半透明即“terrain_blend”材质如彩色玻璃 |
<span id="netease_solid"></span>
### netease:solid
用于设置方块是否为实心方块主要与生物在方块内时是否受到窒息伤害有关。
可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)的customblocks:customblocks_model_flower方块。
| 键 | 类型 | 默认值 | 解释 |
| ----- | ---- | ------ | ------------------------------------------------------------ |
| value | bool | true | 为true时生物在方块内会受到窒息伤害<br>为false时生物在方块内不会受到窒息伤害 |
<span id="netease_pathable"></span>
### netease:pathable
用于设置游戏内AI在进行寻路时方块是否被当作障碍物。
可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)的customblocks:customblocks_model_flower方块。
| 键 | 类型 | 默认值 | 解释 |
| ----- | ---- | ------ | ------------------------------------------------------------ |
| value | bool | false | 为true时寻路时被当作空气<br>为false时寻路时被当作障碍物并且可在其上方行走 |
<span id="netease_block_entity"></span>
### netease:block_entity
用于给自定义方块添加[自定义方块实体](./4-自定义方块实体.md)。
可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)的customblocks:customblocks_test_block_entity方块。
| 键 | 类型 | 默认值 | 解释 |
| ------- | ---- | ------ | ------------------------------------------------------------ |
| tick | bool | false | 为true时当玩家进入方块tick范围时该方块每秒会发送**20次**ServerBlockEntityTickEvent事件<br>为false时该方块不会发送ServerBlockEntityTickEvent事件 |
| movable | bool | true | 为true时该方块可被粘性活塞拉回<br>为false时该方块不可被粘性活塞拉回 |
<span id="netease_random_tick"></span>
### netease:random_tick
用于给自定义方块定义是否可以随机tick并且设置该tick事件是否发送到脚本层。
| 键 | 类型 | 默认值 | 解释 |
| -------------- | ---- | ------ | ------------------------------------------------------------ |
| enable | bool | false | 方块是否随机tick |
| tick_to_script | bool | false | 是否发送事件<a href="../../../../mcdocs/1-ModAPI/事件/方块.html#blockrandomtickserverevent" rel="noopenner"> BlockRandomTickServerEvent </a>到python脚本 |
### netease:redstone_property
用于给自定义方块设置红石属性
| 键 | 类型 | 默认值 | 解释 |
| ----- | ---- | ------ | ------------------------------------------------------------ |
| value | str | None | 目前只支持break_on_push设置之后方块可以被活塞破坏变成掉落物否则方块会被活塞推动而不破坏 |
### netease:neighborchanged_sendto_script
| 键 | 类型 | 默认值 | 解释 |
| ----- | ---- | ------ | ------------------------------------------------------------ |
| value | bool | false | 方块周围环境变化是否发送事件<a href="../../../../mcdocs/1-ModAPI/事件/方块.html#blockneighborchangedserverevent#blockneighborchangedserverevent" rel="noopenner"> BlockNeighborChangedServerEvent </a>到脚本层 |
<span id="netease_connection"></span>
### netease:connection
用于给自定义方块定义“连接”属性
使用枚举的方式配置该方块与哪些方块具有“连接”属性,并且此属性是单向的。不支持附加值。
由于方块更新的特性,“床”和“旗帜”方块在区块边缘放置时,与其他方块会出现连接失败。
可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)的customblocks_model_wire方块。
| 键 | 类型 | 解释 |
| ------ | ------------- | -------------------------- |
| blocks | array(string) | 数组元素为方块的identifier |
目前该属性只用于[netease:aabb](#netease_aabb)及[自定义方块模型](./5-自定义方块模型.md)的is_connect查询
| 名称 | 解释 |
| ---------------- | ------------------------------------------------------------ |
| query.is_connect | 传入一个参数返回该方块与对应临面上的方块是否有connection属性<br/>参数取值与对应的面:<br>0-down面1-up面2-north面3-south面4-west面5-east面。 |
<span id="netease_redstone"></span>
### netease:redstone
用于配置自定义红石源与自定义红石机械元件;
可以配置自定义红石的类型,如红石源或者红石机械元件;
可以配置初始信号强度默认为15。
| 键 | 类型 | 默认值 | 说明 |
| -------- | ---- | ------ | ---------------------------------------------------------- |
| type | str | | 红石类型:<br/>producer红石源<br/>consumer红石机械元件 |
| strength | int | 15 | 红石信号值,范围[0,15] |
<span id="listen_block_remove"></span>
### netease:listen_block_remove
用于配置自定义方块是否监听方块的<a href="../../../../mcdocs/1-ModAPI/事件/方块.html#blockremoveserverevent" rel="noopenner"> BlockRemoveServerEvent </a>事件
| 键 | 类型 | 默认值 | 说明 |
| ----- | ---- | ------ | ------------ |
| value | bool | false | 是否监听事件 |
<span id="netease_may_place_on"></span>
### netease:may_place_on
用于配置自定义方块可存在于哪些方块的上面。
会生效于玩家右键放置方块时;以及已存在的方块下方的方块发生改变时。
可参考CustomBlocksMod示例中的customblocks_model_flower
| 键 | 类型 | 默认值 | 说明 |
| --------------- | ------------ | ------ | ------------------------------------------------------------ |
| block | list(str) | | 方块identifier的列表。这些方块的所有[方块状态](../../10-基本概念/1-我的世界基础概念.md#方块状态)都可放置 |
| block_state | list(object) | | [方块状态](../../10-基本概念/1-我的世界基础概念.md#方块状态)的列表。<br>每个元素只对应一个特定的方块状态,如果方块有多个种类的状态,需要考虑排列组合的所有情况<br>最终可在上面放置的方块是block字段与block_state字段的并集 |
| spawn_resources | bool | true | 已存在的方块因下方的方块发生改变而被破坏时,是否生成掉落物 |
<span id="netease_fire_resistant"></span>
### netease:fire_resistant
用于配置自定义方块是否防火。
设置为防火时,方块的掉落物会与下界合金一样,不会被火烧毁,掉进岩浆时会弹走。
可参考CustomBlocksMod示例中的customblocks_test_ore
| 键 | 类型 | 默认值 | 说明 |
| ----- | ---- | ------ | -------- |
| value | bool | | 是否防火 |
### netease:block_properties
用于配置自定义方块的方块属性
这些方块属性可以叠加,主要用于引擎对一些方块特性逻辑的判断
可参考CustomBlocksMod示例中的customblocks_slime、customblocks_flower_extend
| 键 | 类型 | 默认值 | 说明 |
| ----- | ---- | ------ | -------- |
| properties | array | | 所有属性字符串 |
其中properties数组目前支持以下字符串填充
| 键 | 说明 |
| ----- |-------- |
| piston_block_grabber | 被活塞推动时是否带动旁边方块 |
| slime | 主要用于变为移动方块(例如被活塞推)时修改对实体力的计算 |
|breaks_when_fallen_on_by_heavy| 当重力方块结束下落在该方块位置后,自身是否被毁坏|
如果方块碰撞盒体积使用netease:aabb或minecraft:entity_collision改小可能会导致无法触发目前可参考范围是边长0.4以下不会触发)。
### netease:on_stand_on
用于触发实体站在方块上的事件
可参考CustomBlocksMod示例中的customblocks_slime利用了该事件组合做出了个模拟原版粘液块的效果。
| 键 | 类型 | 默认值 | 说明 |
| ----- | ---- | ------ | -------- |
| send_python_event | bool | | 是否发送事件至python |
当send_python_event为true时该方块会触发OnStandOnBlockClientEvent、OnStandOnBlockServerEvent事件。
如果方块碰撞盒体积使用netease:aabb或minecraft:entity_collision改小可能会导致无法触发目前可参考范围是边长0.4以下不会触发)。
### netease:on_before_fall_on
用于触发实体刚下落至方块的事件,主要用于伤害计算
可参考CustomBlocksMod示例中的customblocks_slime利用了该事件组合做出了个模拟原版粘液块的效果。
| 键 | 类型 | 默认值 | 说明 |
| ----- | ---- | ------ | -------- |
| send_python_event | bool | | 是否发送事件至python |
当send_python_event为true时该方块会触发OnBeforeFallOnBlockServerEvent事件。
如果方块碰撞盒体积使用netease:aabb或minecraft:entity_collision改小可能会导致无法触发目前可参考范围是边长0.4以下不会触发)。
### netease:on_after_fall_on
用于触发实体下落至方块后的事件,主要用于力的计算
可参考CustomBlocksMod示例中的customblocks_slime利用了该事件组合做出了个模拟原版粘液块的效果。
| 键 | 类型 | 默认值 | 说明 |
| ----- | ---- | ------ | -------- |
| send_python_event | bool | | 是否发送事件至python |
当send_python_event为true时该方块会触发OnAfterFallOnBlockClientEvent、OnAfterFallOnBlockServerEvent事件。
如果方块碰撞盒体积使用netease:aabb或minecraft:entity_collision改小可能会导致无法触发目前可参考范围是边长0.4以下不会触发)。
### netease:on_entity_inside
用于触发实体碰撞盒所在位置有方块时的事件(判断位置逻辑有无方块,与方块碰撞盒大小无关)。
可参考CustomBlocksMod示例中的customblocks_flower_extend利用了该事件做出模拟原版蜘蛛网穿过时的缓速效果。
| 键 | 类型 | 默认值 | 说明 |
| ----- | ---- | ------ | -------- |
| send_python_event | bool | | 是否发送事件至python |
当send_python_event为true时该方块会触发OnEntityInsideClientEvent、OnEntityInsideServerEvent事件。
### netease:on_step_on
用于触发实体刚移动至一个实心方块上的事件
可参考CustomBlocksMod示例中的customblocks_slime在触发该事件时进行了日志打印
| 键 | 类型 | 默认值 | 说明 |
| ----- | ---- | ------ | -------- |
| send_python_event | bool | | 是否发送事件至python |
当send_python_event为true时该方块会触发StepOnBlockServerEvent、StepOnBlockClientEvent事件。
### netease:on_step_off
用于触发实体刚离开一个实心方块上的事件
可参考CustomBlocksMod示例中的customblocks_slime在触发该事件时进行了日志打印
| 键 | 类型 | 默认值 | 说明 |
| ----- | ---- | ------ | -------- |
| send_python_event | bool | | 是否发送事件至python |
当send_python_event为true时该方块会触发StepOffBlockServerEvent、StepOffBlockClientEvent事件。

View File

@@ -0,0 +1,210 @@
---
front:
hard: 入门
time: 分钟
---
# 功能
## 获取及设置某个位置的方块
获取见服务端blockInfo组件的GetBlockNew接口
设置见服务端blockInfo组件的SetBlockNew接口
## 物品形式的生成及获取
支持“MOD SDK文档”中所有与物品相关的接口及事件其中的物品identifier对应方块identifier。
## 方块及物品事件
支持“MOD API”中所有与方块相关的事件其中添加了“fullName”字段返回对应的方块identifier
支持"MOD API"中所有与物品相关的事件其中添加了“itemName”字段返回对应的方块identifier。
## 自定义配方
见[自定义配方文档](../5-自定义配方.md)材料及结果都支持填写方块identifier。可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)行为包的netease_recipes
## 方块组合
见"MOD API"的服务端block组件defines项支持填写自定义方块的identifier。可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)脚本的CustomBlocksServer.RegisterBlockPattern
## 村民交易
可将行为包的交易配置中的item修改为自定义方块的identifier。可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)行为包的`trading\economy_trades\armorer_trades.json`里面将新手级盔甲商的其中一个交易项替换为绿宝石兑换customblocks:customblocks_test0方块
## 构成自定义群系
阅读这条前请先阅读[群系地貌文档](../4-自定义维度/2-群系地貌.md)。
可通过修改minecraft:overworld_surface字段来使用自定义方块生成区块。可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)行为包的`netease_biomes\dm5`里面在自定义群系demo[CustomBiomesMod](../../13-模组SDK编程/60-Demo示例.md#CustomBiomesMod)中dm5维度的基础上进行修改将该维度的dm5_cold_beach、dm5_frozen_ocean、dm5_frozen_river、dm5_ice_plains、dm5_river几个群系的地表方块进行了替换。
<span id="shengyin"></span>
## 声音
resource包中`blocks.json`配置方块的sound。
可以使用原版`sounds.json`中block_sounds里的类型。不支持添加自定义block_sounds类型
<span id="liangdu"></span>
## 亮度
行为包中使用[minecraft:block_light_emission](./1-JSON组件.md#minecraft_block_light_emission)可将方块设置为光源。
可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)的customblocks:customblocks_model_flower方块。
[minecraft:block_light_absorption](./1-JSON组件.md#minecraft_block_light_absorption)可设置方块透光率值的范围为0-15
<span id="wajue"></span>
## 挖掘
挖掘的详细介绍可参考[官方wiki](https://minecraft-zh.gamepedia.com/挖掘)
挖掘时间可使用[minecraft:destroy_time](./1-JSON组件.md#minecraft_destroy_time)配置
挖掘工具可使用[netease:tier](./1-JSON组件.md#netease_tier)配置
可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)的customblocks:customblocks_test_ore方块
<span id="duomianxiang"></span>
## 多面向
行为包中使用[netease:face_directional](./1-JSON组件.md#netease_face_directional)配置。
四面向可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)的customblocks:customblocks_test_face4方块
六面向可参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)的customblocks:customblocks_test_face6方块
对于两种面向当玩家进行放置时都是north的贴图面向玩家。
方块的面向等于north贴图面向的方向即玩家放置时准心的反方向
当设置为四面向时方块面向与附加值auxvalue的关系为
| 方块面向 | auxvalue |
| -------- | -------- |
| south | 0 |
| west | 1 |
| north | 2 |
| east | 3 |
当设置为六面向时方块面向与附加值auxvalue的关系为
| 方块面向 | auxvalue |
| -------- | -------- |
| down | 0 |
| up | 1 |
| north | 2 |
| south | 3 |
| west | 4 |
| east | 5 |
<span id="zidingyiqunxiyanse"></span>
## 自定义方块及自定义方块模型的群系颜色
关于生物群系颜色的描述可看[生物群系 - Minecraft Wiki最详细的我的世界百科 ](https://minecraft.fandom.com/zh/wiki/生物群系#.E7.94.9F.E7.89.A9.E7.BE.A4.E7.B3.BB.E9.A2.9C.E8.89.B2)
原版方块在不同生物群系中会有稍稍不同的颜色变化,例如草、树叶等方块,它们会随着它们所在的群系的温度以及降雨量而产生颜色变化,在温度高的环境中会偏绿,在降雨量低的环境中会变黄。
[自定义方块](./0-自定义方块概述.md)及[自定义方块模型](./5-自定义方块模型.md)也支持该特性。开发者们也可以参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)中的**customblocks:customblocks_leaves_tinted**方块、**customblocks:customblocks_test_face4_tinted**方块以及**customblocks:customblocks_model_flower_tinted**方块并参考这三个方块所使用的的颜色渐变图CustomBlocksMod\CustomBlocksMod_resource\textures\colormap\my_grass.png
以下将会说明如何为自定义方块添加自定义群系颜色。
#### **1. 颜色渐变图的准备**
首先我们需要为方块准备一张颜色渐变图color map,该图示例如下:
<img src="./picture/customblock/custom_foliage-0-1.png" style="zoom: 67%;" />
该图分辨率固定为256x256目前暂不支持其他分辨率并且仅图像中的左下三角形部分会被使用右上三角形部分不会被使用因此可以置为空白。
方块在被添加群系颜色时,会按照该群系的降雨量及温度来决定我们所取的群系颜色是这张颜色渐变图上的哪一个颜色点。其规则如下:
- 温度从低往高时会按照红色箭头方向从颜色渐变图的右边到左边决定颜色点的x坐标值
- 降雨量从低往高时会按照蓝色箭头方向从颜色渐变图的下方到上方决定颜色点的y坐标值。
举个例子,在降雨量低而且温度高的群系,所取的颜色为这张颜色渐变图的最左下角部分,即颜色会偏黄色。
**根据以上规则,开发者可以自己来定义自己的颜色渐变图来为自定义方块添加特殊的群系颜色。制作时也可以根据原版的颜色渐变图来修改。需要注意的是,分 辨率固定为256x256。**
制作好的渐变图可以放在resource_pack/textures/colormap/这个路径下。
#### **2. 为自定义方块设置这张渐变图**
渐变图的使用方式有两种,一种是为方块整体使用这张渐变图,一种是为方块中指定的贴图使用这张贴图。
##### 1为方块整体使用这张渐变图
在准备好这张图后我们需要在resource_pack/blocks.json中添加这张图的使用
```json
"customblocks:customblocks_leaves_tinted": {
"sound": "grass",
"textures": "customblocks:customblocks_leaves_tinted",
// 使用"use_colormap"字段指定使用的colormap贴图路径
// 使用colormap后, 该方块的颜色将会随群系的变化而变化
"use_colormap":"textures/colormap/my_grass"
}
```
我们使用"use_colormap"字段来指定这个方块使用自定义群系颜色,这个字段的值则是这张颜色渐变图的相对路径。
这样我们的自定义方块就能在不同群系中表现出不同的颜色差异了。
<img src="./picture/customblock/custom_foliage-0-3.png" style="zoom: 67%;" />
##### 2为方块指定的贴图使用这张渐变图
为方块指定的贴图使用这张渐变图时我们需要在resource_pack/textures/terrain_texture.json中为某张贴图进行指定
```json
"customblocks:customblocks_test_face4_top_tinted":{
"textures": "textures/blocks/glazed_terracotta_white",
// 使用"use_colormap"字段指定使用的colormap贴图路径, 分辨率固定为256x256, 暂不支持其他分辨率
"use_colormap":"textures/colormap/my_grass"
},
```
我们在上面的代码示例中为"customblocks:customblocks_test_face4_top_tinted"这张贴图指定了渐变图。这样一来我们可以在resource_pack/blocks.json为这个方块的某个面指定使用这张"customblocks:customblocks_test_face4_top_tinted"贴图了:
```json
"customblocks:customblocks_test_face4_tinted": {
"textures": {
"down": "customblocks:customblocks_test_face4_front_tinted", // 这个贴图使用了带colormap的贴图(colormap在textures/terrain_texture.json中指定), 该面的颜色将会随群系的变化而变化
"up": "customblocks:customblocks_test_face4_front_not_tinted",
"north": "customblocks:customblocks_test_face4_top_tinted", // 这个贴图使用了带colormap的贴图(colormap在textures/terrain_texture.json中指定), 该面的颜色将会随群系的变化而变化
"south": "customblocks:customblocks_test_face4_top_sides_not_tinted",
"west": "customblocks:customblocks_test_face4_top_sides_not_tinted",
"east": "customblocks:customblocks_test_face4_top_tinted" // 这个贴图使用了带colormap的贴图(colormap在textures/terrain_texture.json中指定), 该面的颜色将会随群系的变化而变化
},
"sound": "stone"
}
```
我们为这个方块的下表面,东表面以及北表面使用了这些带有渐变图的贴图,如此,方块就表现为某些面能在群系中产生不同颜色的变化,而某些面则不会产生颜色变化。
<img src="./picture/customblock/custom_foliage-0-2.png" style="zoom: 67%;" />
#### **3.不适用的方块及情况**
注意,以下自定义方块或情形将不适用自定义群系颜色:
1重力方块在下落时由于会转换为方块实体因此方块颜色将变为原来的颜色。
2使用了textures/flipbook_textures.json中定义的动态贴图的自定义方块自定义群系颜色也不会生效。
3自定义方块实体外观不适用自定义群系颜色。
4自定义流体不适用自定义群系颜色。
5自定义刷怪箱、自定义传送门不适用自定义群系颜色。
6自定义方块模型无法支持为这个模型中指定的贴图使用自定义群系颜色只能整体使用自定义群系颜色。

View File

@@ -0,0 +1,23 @@
---
front:
hard: 入门
time: 分钟
---
# 特殊方块概述
开发者可通过在方块定义json中添加base_block来修改方块的基础行为。
base_block包括
* mob_spawner 自定义刷怪箱
* portal 自定义传送门
* custom_crop_block 自定义农作物
* custom_heavy_block 自定义重力方块
* liquid 自定义静态流体方块
* flowing_liquid 自定义动态流体方块
![special-1](.././picture/customblock/special-1.png)
如下图为自定义刷怪箱的base_block配置
![special-2](.././picture/customblock/special-2.png)

View File

@@ -0,0 +1,27 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义刷怪箱
## base_block设置
- **自定义刷怪箱方块的base_block需要设为mob_spawner**
- **还应在blocks.json中进行如下设置**
![special-3](.././picture/customblock/special-3.png)
## netease:mob_spawner
可在netease:mob_spawner组件中设置刷怪的类型目前支持原生生物、微软自定义生物。
| 键 | 类型 | 默认值 | 解释 |
| ---- | ------ | ------ | -------------------------------- |
| type | string | | 必须设置,用于控制生成的生物类型 |
- 原生生物type为"minecraft:Namespaced ID",如"minecraft:parrot"Namespaced ID可参考[官方wiki](https://minecraft.gamepedia.com/Mob#List_of_mobs)中各Mob的详细信息。
- 微软自定义生物type为"minecraft:entity"中"description"的"identifier"项,可参考[自定义生物文档](../../3-自定义生物/01-自定义基础生物.md)及[CustomBlocksMod](../../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)中的customblocks_test_mobspawner1.json。

View File

@@ -0,0 +1,65 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义传送门方块
## base_block设置
- **自定义传送门方块的base_block需要设为portal。**
## 动画纹理
- 可通过在`resource/textures/flipbook_textures.json`中配置动画纹理使其贴图拥有动态效果,属于微软功能。
## 传送门方块介绍
- 传送门方块拥有两种朝向其方块延伸方向分别与X轴、Z轴相同如图所示
- 可在netease:portal中设置传送门方块上播放的粒子特效以及目标维度
![special-4](.././picture/customblock/special-4.png)
## netease:portal
| 键 | 类型 | 默认值 | 解释 |
| -------------------- | ------ | ------ | ------------------------------------------------------------ |
| particle_east_west | string | | 可选对应于粒子json文件中的identifier用于控制方块与Z轴同向时播放的粒子特效 |
| particle_north_south | string | | 可选对应于粒子json文件中的identifier用于控制方块与X轴同向时播放的粒子特效 |
| target_dimension | int | | 必须设置,用于控制进入传送门方块后到达的目标维度 |
- 粒子特效应放置于`resource/particles`,粒子特效编写可参考[官方关于粒子组件的说明](https://minecraft.gamepedia.com/Bedrock_Edition_particle_documentation)。
- **目标维度为0或3-20的整数或者大于21的新版自定义维度的数值1下界和2末地会被视作0来处理。**
## 自定义传送门方块相关特性
- 若通过服务端blockInfo组件的SetBlockNew接口放置传送门方块
- 附加值'aux'设为1时该方块延伸方向与X轴相同播放particle_north_south对应的粒子
- 附加值'aux'设为2时该方块延伸方向与Z轴相同播放particle_east_west对应的粒子。
- **避免将附加值'aux'设为0。**
- 还可以在游戏内通过指令/setblock放置方块**注意'aux'值应设为1或2。**
如下为在(0, 65, 0)处放置aux值为2的customblocks_test_portal_blue方块的指令
`/setblock 0 65 0 customblocks_test_portal_blue 2`
- 手动放置的传送门方块附加值'aux'始终为0无论它朝向哪里**不建议开发者手动放置传送门方块。**
- 目标维度与当前维度相同时,将不会进行传送。
- 只有玩家才能够通过自定义传送门方块进行传送。
- 同一玩家存在一定的传送冷却时间,不会连续传送。
- 传送前后玩家坐标不发生改变。

View File

@@ -0,0 +1,411 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义农作物
## 概述
开发者可以通过以下两种方式实现自定义农作物详见demo [CustomCropMod](../../../13-模组SDK编程/60-Demo示例.md#CustomCropMod)
1通过[netease:transform组件](#netease_transform)定义农作物之间的转换规则;
2通过python脚本监听<a href="../../../../../mcdocs/1-ModAPI/事件/物品.html#serveritemuseonevent" rel="noopenner"> ServerItemUseOnEvent </a>、<a href="../../../../../mcdocs/1-ModAPI/事件/方块.html#blockrandomtickserverevent" rel="noopenner"> BlockRandomTickServerEvent </a>、<a href="../../../../../mcdocs/1-ModAPI/事件/方块.html#blockneighborchangedserverevent" rel="noopenner"> BlockNeighborChangedServerEvent </a>等事件控制方式。
## 公共组件说明
### base_block设置
- **自定义农作物方块的base_block需要设为custom_crop_block**
<span id="netease_transform"></span>
### netease:transform
该组件用于自定义农作物方块之间的转换
| 键 | 类型 | 默认值 | 解释 |
| ---------- | ---- | ------ | ---------------------------------------------------------- |
| conditions | dict | | 农作物方块转换的条件三个条件同时满足时会转化为result方块 |
| result | str | | 农作物方块转换后的方块名称 |
例如:
```json
"netease:transform": {
"conditions": {
"brightness": { # 农作物生长必须满足的光照条件
"max": 15,
"min": 9
},
"random_tick_count": { # 转化需要经过的随机tick次数
"value": 2 # 2表示在第三次随机tick时转化不允许小于等于0的值
},
"surrouding": { # 转化需要的周围方块
"value": "minecraft:sand",
"radius": 1 # 半径
}
},
"result": "minecraft:egg" # 转化为哪种方块
}
```
### minecraft:seed
自定义种子,详见[minecraft:seed](../../1-自定义物品/1-自定义基础物品.md#minecraft_seed)
## 自定义农作物方式一
该方式适用于纯配置json不需要写任何python脚本逻辑。
这种方式包括一个种子(自定义物品)与三种自定义农作物的状态(自定义方块)。
### 1自定义种子
参照[自定义基础物品](../../1-自定义物品/1-自定义基础物品.md)自定义一个农作物种子customcrop:custom_wheat_seeds。
```json
{
"format_version": "1.10",
"minecraft:item": {
"description": {
"identifier": "customcrop:custom_wheat_seeds",
"register_to_create_menu":true,
"category": "Nature"
},
"components": {
"minecraft:seed": {
"crop_result": "customcrop:customcrop_stage0",# 种子生成的方块
"plant_at": "minecraft:sand" #种植条件
}
}
}
}
```
json说明
该种子的标识为customcrop:custom_wheat_seeds它包含一个minecraft:seed组件其中
| 字段 | 值 | 说明 |
| ----------- | ---------------------------- | ------------------------------------------------------------ |
| crop_result | customcrop:customcrop_stage0 | 种子将生长为customcrop:customcrop_stage0自定义方块 |
| plant_at | minecraft:sand | 该种子只能在“沙子”上种植,种植后其所有的生长状态的下方方块也必须为“沙子”,如果底部的方块被破坏,农作物也将被破坏 |
### 2自定义三种农作物状态
参照[自定义方块](../0-自定义方块概述.md)我们将自定义三种农作物状态分别为customcrop:customcrop_stage0、customcrop:customcrop_stage1、customcrop:customcrop_stage2其中部分json如下所示
#### customcrop:customcrop_stage0
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"identifier": "customcrop:customcrop_stage0",
"register_to_creative_menu": true,
"is_experimental": false,
"base_block": "custom_crop_block"
},
"components": {
...
"netease:transform": {
"conditions": {
"brightness": { # 光照条件
"max": 15,
"min": 9
},
"random_tick_count": { # 随机tick次数条件
"value": 1
},
"surrouding": { # 在半径为1的周围需要存在“沙子”
"value": "minecraft:sand",
"radius": 1
}
},
"result": "customcrop:customcrop_stage1" # 成长下一阶段的方块
},
...
}
}
}
```
#### customcrop:customcrop_stage1
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"identifier": "customcrop:customcrop_stage1",
"register_to_creative_menu": true,
"is_experimental": false,
"base_block": "custom_crop_block"
},
"components": {
...
"netease:transform": {
"conditions": {
"brightness": {
"max": 15,
"min": 9
},
"random_tick_count": {
"value": 1
},
"surrouding": {
"value": "minecraft:sand",
"radius": 1
}
},
"result": "customcrop:customcrop_stage2" # 成长下一阶段的方块
},
...
}
}
}
```
#### customcrop:customcrop_stage2
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"identifier": "customcrop:customcrop_stage2",
"register_to_creative_menu": true,
"is_experimental": false,
"base_block": "custom_crop_block"
},
"components": {
...
"minecraft:loot": {
"table": "loot_tables/blocks/customcrop_stage2.json"
}
...
}
}
}
```
该阶段为农作物的成熟阶段可以通过minecraft:loot的方式获得收获。
### 3成长过程
<img src="../../picture/customcrop/custom_stage_2.jpg" alt="流程" style="zoom:75%;" />
其中中间为阶段一customcrop:customcrop_stage0最右边为阶段二customcrop:customcrop_stage1左边为阶段三customcrop:customcrop_stage2
## 自定义农作物方式二
该方式适用于配置json+python脚本控制。
这种方式包括一个物品(自定义物品)与三种自定义农作物的状态(自定义方块)。
这种方式需要配置[netease:random_tick](../1-JSON组件.md#netease_random_tick)和[netease:block_entity](../1-JSON组件.md#netease_block_entity),使得<a href="../../../../../mcdocs/1-ModAPI/事件/方块.html#blockrandomtickserverevent" rel="noopenner"> BlockRandomTickServerEvent事件 </a>发送到脚本层并且支持[自定义方块实体](../4-自定义方块实体.md),从而实现方块转换的控制以及方块状态的存档。
#### 1自定义物品
在示例mod中该自定义物品为customcrop:custom_item在该物品的使用时通过监听事件<a href="../../../../../mcdocs/1-ModAPI/事件/物品.html#serveritemuseonevent" rel="noopenner"> ServerItemUseOnEvent </a>来判断是否可以在当前位置种植该物品类似customcrop:custom_wheat_seeds的minecraft:seed中的plant_at功能并且通过<a href="../../../../../mcdocs/1-ModAPI/接口/世界/方块管理.html#setblocknew" rel="noopenner"> SetBlockNew </a>设置农作物阶段一customcrop:customcrop_1_stage0
#### 2自定义三种农作物状态
##### customcrop:customcrop_1_stage0
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"identifier": "customcrop:customcrop_1_stage0",
"register_to_creative_menu": true,
"is_experimental": false
},
"components": {
...
"netease:random_tick": { # 该方块会触发BlockRandomTickServerEvent事件
"enable": true,
"tick_to_script": true
},
"netease:redstone_property": {
"value": "break_on_push"
},
"netease:neighborchanged_sendto_script": {# 该方块会触发BlockNeighborChangedServerEvent事件
"value": true
},
"netease:block_entity": { # 方块实体数据存储
"tick": false,
"movable": true
}
}
}
}
```
##### customcrop:customcrop_1_stage1
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"identifier": "customcrop:customcrop_1_stage1",
"register_to_creative_menu": true,
"is_experimental": false
},
"components": {
...
"netease:random_tick": {
"enable": true,
"tick_to_script": true
},
"netease:redstone_property": {
"value": "break_on_push"
},
"netease:neighborchanged_sendto_script": {
"value": true
},
"netease:block_entity": {
"tick": false,
"movable": true
}
}
}
}
```
##### customcrop:customcrop_1_stage2
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"identifier": "customcrop:customcrop_1_stage2",
"register_to_creative_menu": true,
"is_experimental": false
},
"components": {
...
"netease:neighborchanged_sendto_script": {
"value": true
},
"netease:block_entity": {
"tick": false,
"movable": true
}
}
}
}
```
#### 3生长过程
<img src="../../picture/customcrop/custom_stage_1.jpg" alt="流程" style="zoom:75%;" />
其中左边为阶段一customcrop:customcrop_1_stage0中间为阶段二customcrop:customcrop_1_stage2右边为阶段三customcrop:customcrop_1_stage2
#### 4脚本简要说明
##### 物品使用条件限定
在自定义物品customcrop:custom_item使用生成农作物第一阶段方块customcrop:customcrop_1_stage0可以通过监听事件<a href="../../../../../mcdocs/1-ModAPI/事件/物品.html#serveritemuseonevent" rel="noopenner"> ServerItemUseOnEvent </a>来限制,例如:
```python
def OnServerItemUseOnEvent(self, args):
if args["itemName"] == "customcrop:custom_item":
# 使用自定义物品时生成自定义方块
comp = self.CreateComponent(self.playerId, "Minecraft", "blockInfo")
belowPos = (args["x"], args["y"], args["z"]) # below
blockDict = comp.GetBlockNew(belowPos)
if blockDict["name"] == "minecraft:dirt": # 底下为泥土才能种植这里同种子的plant_at判断
blockDict = {
'name': 'customcrop:customcrop_1_stage0',
'aux': 0
}
comp.SetBlockNew((args["x"], args["y"] + 1, args["z"]), blockDict)
```
##### 农作物转换条件
在示例mod中我们通过监听事件<a href="../../../../../mcdocs/1-ModAPI/事件/方块.html#blockrandomtickserverevent" rel="noopenner"> BlockRandomTickServerEvent </a>来判断是否可以转换到下一个阶段的自定义农作物判断条件不限定于netease:transform中描述的光照、tick数量以及周边环境。同时我们还可以借助blockEntityData组件来存储数据。
```python
def OnStage0BlockTick(self, args):
pos = (args["posX"], args["posY"], args["posZ"])
comp = self.CreateComponent(self.playerId, "Minecraft", "blockInfo")
lightlevel = comp.GetBlockLightLevel(pos)
if (15 >= lightlevel >= 0): # 光照条件判断
dimension = args["dimensionId"]
blockEntitycomp = self.CreateComponent(self.playerId, "Minecraft", "blockEntityData")
blockEntityData = blockEntitycomp.GetBlockEntityData(dimension, pos)
if not blockEntityData:
return
growth = blockEntityData["growth"]
if not growth:
growth = 0
growth += 1
# 使用blockEntity保存tick count数据
blockEntityData["growth"] = growth
if (growth >= 1): # tick数量条件判断
comp = self.CreateComponent(self.playerId, "Minecraft", "blockInfo")
blockDict = {
'name': 'customcrop:customcrop_1_stage1',
'aux': 0
}
comp.SetBlockNew(pos, blockDict) # 切换到农作物的下一个阶段
```
##### 农作物收获
开发者可以根据需要,通过监听事件<a href="../../../../../mcdocs/1-ModAPI/事件/方块.html#destroyblockevent" rel="noopenner"> DestroyBlockEvent </a>以及<a href="../../../../../mcdocs/1-ModAPI/接口/世界/实体管理.html#spawnitemtolevel" rel="noopenner"> SpawnItemToLevel </a>来实现农作物的掉落。
## 自定义农作物外观
- 可使用[自定义方块模型](../5-自定义方块模型.md)配置农作物的外观。
demo的`resource/bbmodel`下有demo中农作物的模型工程demo中所有农作物都共用一个工程只是贴图不一样。
## Q&A
1什么时候需要把自定义方块base_block配置成custom_crop_block
需要[netease:transform组件](#netease_transform)驱动方块之间的转换时
2如何限制农作物的种植条件
使用“自定义农作物方式一“的方式可以通过种子的”plant_at“字段进行限制
使用“自定义农作物方式二”的方式可以通过监听<a href="../../../../../mcdocs/1-ModAPI/事件/物品.html#serveritemuseonevent" rel="noopenner"> ServerItemUseOnEvent </a>来限制种植时的条件。
3自定义农作物下方的方块被破坏、被替换、被推动时如何检测
监听<a href="../../../../../mcdocs/1-ModAPI/事件/方块.html#blockneighborchangedserverevent" rel="noopenner"> BlockNeighborChangedServerEvent </a>事件监听周围方块的变化,并做响应的处理。

View File

@@ -0,0 +1,67 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义红石方块
自定义红石方块是一种特殊的自定义方块,包括信号源方块与红石机械元件方块,支持方块相关的所有事件以及接口。
## 自定义红石信号源方块
自定义红石信号源方块放置在地图上会发出红石信号,信号的初始值可以配置。
其中type为producerstrength为初始红石信号量。
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"identifier": "customblocks:customblocks_redstone",
"register_to_creative_menu": true,
"is_experimental": false,
},
"components": {
"minecraft:map_color": {
"color": "#408080"
},
"netease:redstone": {
"type": "producer",
"strength": 10
}
}
}
}
```
## 自定义红石机械元件方块
自定义红石机械元件方块放置在地图上会接收红石信号,可以被激活。
对于自定义红石机械元件方块,其红石信号变化时触发事件<a href="../../../../../mcdocs/1-ModAPI/事件/方块.html#blockstrengthchangedserverevent" rel="noopenner"> BlockStrengthChangedServerEvent </a>。
其中type为consumer初始红石信号量为0未激活状态不能通过netease:redstone的strength字段进行配置。
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"identifier": "customblocks:customblocks_redstone_consumer",
"register_to_creative_menu": true,
"is_experimental": false,
},
"components": {
"netease:redstone": {
"type": "consumer"
}
}
}
}
```

View File

@@ -0,0 +1,149 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义流体
## 概述
自定义流体需要设置两个方块,一个静态流体,一个动态流体。液体在流动过程中最外层是动态流体,其他都是静态流体,二者会相互转换。当流体扩散完毕后可见的均已转化为静态流体,可以通过设置不同颜色来观察动态流体与静态流体之间的相互转换。
## base_block设置
- 自定义流体的**base_block**,静态流体需要设为**liquid**,动态流体需要设为**flowing_liquid**
- 命名规则因为静态流体与动态流体是相互转换的在引擎层通过flowing去定位所以需要注册一对才能正常使用
- 静态流体——**命名空间:流体方块名**,例如`customLiquid:red_water`
- 动态流体——**命名空间:flowing_流体方块名**,例如`customLiquid:flowing_red_water`
## 动画纹理
- 流体需要在`resource/textures/flipbook_textures.json`中配置动画纹理使其贴图拥有动态流动效果,属于微软功能。
## 流体方块介绍
- 可在netease:liquid中设置流体方块的流动速度、流动范围、颜色以及能否使船浮起来
- 流体方块与原版水一致,如图所示:
![special-4](.././picture/customblock/special-5.png)
## netease:liquid
| 键 | 类型 | 默认值 | 解释 |
| -------------- | ------------- | ---------------------------------------- | ------------------------------------------------------------ |
| liquid_color | array | [255, 255, 255, 255] | 可选流体颜色4个数依次对应RGBA取值范围均为0-255。透明度只有在开启了“精美图像”选项时生效。 |
| spread_range | int | 8 | 可选流体范围以动态流体为中心往外扩散的格数取值范围1-8仅动态流体有效 |
| spread_delay | int | 5 | 可选流体扩散刻数每经过该刻数扩散一格每秒20刻仅动态流体有效 |
| spread_fire | bool | false | 可选,是否传播火,可参考岩浆效果 |
| can_float_boat | bool | true | 可选,流体是否能浮起船来,动态流体及静态流体均需要设置 |
| bucket_name | string | "water_bucket" | 可选空桶对水源使用使获得的物品默认是原版的水桶如果是自定义物品需带上命名空间输入完整的物品id |
| water_splash | string | "minecraft:water_splash_particle_manual" | 可选,实体进入流体时会播放对应的粒子特效,在玩家所在位置附近随机播放若干该特效,特效需采用微软特效 |
| mob_effects | array(dict) | [] | 可选,实体进入流体时添加状态效果,会触发对应的添加/刷新状态效果的事件 |
| remove_effects | array(string) | [] | 可选,实体进入流体时移除状态效果,会触发对应的移除状态效果的事件 |
- 如果没有注册该组件,液体颜色、范围及扩散延迟默认和原版水一样,**但是将无法使船浮起来**
添加状态效果mob_effects各字段配置如下
| 键 | 类型 | 解释 |
| ------------- | ------ | -------------------------------------------- |
| effect_name | string | 状态效果名称 |
| duration | int | 状态效果持续时间 |
| amplifier | int | 状态效果倍率比等级小1例如力量II的倍率为1 |
| show_particle | bool | 是否显示状态效果的粒子效果,默认不显示 |
## 自定义流体方块相关特性
- 可以在游戏内通过指令/setblock放置方块静态方块放置后不会向周围扩散当其周围方块发生变化时会转变成流动方块继承流动特性
- 继承自原版水,因此会有原版水的特性,例如和岩浆有互动、玩家进入会有流动效果、溺水、与海绵互动等。
- 用水桶装载后会生成普通水桶通过配置bucket_name可实现生成别的物品可结合自定义桶实现自定义流体的装载与倒出
## 示例
动态流体:
```json
{
"format_version": "1.16.0",
"minecraft:block": {
"description": {
"identifier": "customblocks:flowing_green_water",
"register_to_creative_menu": true,
"base_block": "flowing_liquid"
},
"components": {
"netease:liquid": {
"liquid_color": [ 0, 128, 0, 254 ],
"spread_range": 4,
"spread_delay": 5,
"bucket_name": "customBucket:green_bucket",
"spread_fire": true,
"mob_effects": [
{
"effect_name": "slowness",
"duration": 3,
"amplifier": 1,
"show_particle": true
},
{
"effect_name": "weakness",
"duration": 1,
"amplifier": 4
}
],
"remove_effects": [ "speed", "jump_boost" ]
}
}
}
}
```
静态流体:
```json
{
"format_version": "1.16.0",
"minecraft:block": {
"description": {
"identifier": "customblocks:green_water",
"register_to_creative_menu": false,
"base_block": "liquid"
},
"components": {
"netease:liquid": {
"liquid_color": [ 0, 128, 0, 254 ],
"bucket_name": "customBucket:green_bucket",
"spread_fire": true,
"mob_effects": [
{
"effect_name": "slowness",
"duration": 3,
"amplifier": 1,
"show_particle": true
},
{
"effect_name": "weakness",
"duration": 1,
"amplifier": 4
}
],
"remove_effects": [ "speed", "jump_boost" ]
}
}
}
}
```

View File

@@ -0,0 +1,73 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义重力方块
## 概述
自定义重力方块可以模拟[下落的方块](https://minecraft.fandom.com/zh/wiki/%E4%B8%8B%E8%90%BD%E7%9A%84%E6%96%B9%E5%9D%97)并且支持在组件中修改配置、python监听事件。
## base_block设置
- 自定义重力方块的base_block需要设为`custom_heavy_block`
## netease:fall
| 键 | 类型 | 默认值 | 解释 |
| ------------ | ----- | -------------------- | ------------------------------------------------------------ |
| send_python_event | bool | false | 可选,是否发送重力方块/下落方块实体相关事件至python |
| fall_acceleration | float | 0.04 | 可选下落的方块实体每次tick的垂直加速增量 |
| adjust_percentage | float | 0.98 | 可选下落的方块实体每次tick移动完后移速乘的调整数值 |
| hurt_entity | bool | false | 可选,下落的方块实体结束下落后是否要计算对碰撞实体的伤害 |
| fall_damage_amount | float | 2.0 | 可选,原版下落伤害计算完后乘的倍率 |
| max_fall_damage | int | 40 | 可选,下落伤害乘完倍率后也会被限制在该值的范围内 |
| min_height_remove_tick | int | 100 | 可选当下落的方块实体低于区块最低高度后多少tick将其强制删除 |
| force_break_tick | int | 600 | 可选下落的方块实体多少tick后会强制被破坏 |
| cancel_drop | bool | false | 可选,下落的方块实体被破坏时是否取消方块物品的掉落 |
- `send_python_event`主要影响HeavyBlockStartFallingServerEvent、FallingBlockCauseDamageBeforeServerEvent、FallingBlockBreakServerEvent、FallingBlockReturnHeavyBlockServerEvent、FallingBlockCauseDamageBeforeClientEvent几个事件。
- 如果没有在mod程序中监听的需要可以不将`send_python_event`设为true以优化性能不发python事件也可以配置组件的其他值
- 原版对于下落的方块实体计算下落的过程使用python伪代码表示大致为
```python
while Tick:
falling_block.move_vector.y -= fall_acceleration # 当前移动向量增加一个向下的力
move(falling_block) # 按照当前的移动向量调整实体位置
falling_block.move_vector *= adjust_percentage # 移动完后将当前移速(移动向量)乘个数值回调
```
- 原版下落的方块实体并没有对实体实时的碰撞检测,这就意味着在调整下落的方块移动速度时可能会遇到两个问题:
- 如果两个下落的方块速度不一致,会看到一个方块实体从另一个方块实体传过去,并没有碰撞效果。
- 下落的方块对实体造成伤害的计算并不是在刚接触到实体时,而是在落地时才检测范围有无实体,把移速调整的慢点更容易观察到此现象。
## 示例配置
可参考[CustomBlocksMod](../../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)中的customblocks:customblocks_test_heavy.json。
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"identifier": "customblocks:customblocks_test_heavy",
"register_to_creative_menu": true,
"is_experimental": false,
"base_block": "custom_heavy_block",
"category": "custom"
},
"components": {
"netease:fall": {
"send_python_event":true,
"fall_acceleration":0.04,
"adjust_percentage":0.98,
"hurt_entity":true,
"min_height_remove_tick":100,
"force_break_tick":600,
"fall_damage_amount":2.0,
"max_fall_damage":40
}
}
}
}
```

View File

@@ -0,0 +1,133 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义含水方块
## 概述
自定义含水方块支持在组件中配置自定义方块含水的相关功能并支持python监听事件、接口设置等。
## netease:water_destory
可在netease:water_destory组件中设置是否无法摆放在水源和流水方块中如果设置为true会被流水摧毁。
| 键 | 类型 | 默认值 | 解释 |
| ----- | ---- | ------ | -------------------------------------------- |
| value | bool | | 必须设置,用于设置无法摆放在水源和流水方块中 |
- 可以在方块的loottable中设置被水流摧毁后的掉落物
### 示例
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"register_to_creative_menu": true,
"identifier": "customblocks:water_destroy_test_block",
"is_experimental": false,
"category": "custom"
},
"components": {
"netease:water_destory": {
"value": true
}
}
}
}
```
## netease:water_only
可在netease:water_only组件中设置是否必须放置在水中。
| 键 | 类型 | 默认值 | 解释 |
| ----- | ---- | ------ | ------------------------------------ |
| value | bool | | 必须设置,用于设置是否必须放在水中。 |
### 示例
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"register_to_creative_menu": true,
"identifier": "customblocks:water_only_test_block",
"is_experimental": false,
"category": "custom"
},
"components": {
"netease:water_only": {
"value": true
}
}
}
}
```
## netease:water_source
可在netease:water_source组件中设置是否在水源方块中表现为含水。
| 键 | 类型 | 默认值 | 解释 |
| ----- | ---- | ------ | -------------------------------------- |
| value | bool | | 必须设置,是否在水源方块中表现为含水。 |
### 示例
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"register_to_creative_menu": true,
"identifier": "customblocks:water_source_test_block",
"is_experimental": false,
"category": "custom"
},
"components": {
"netease:water_source": {
"value": true
},
"netease:render_layer": {
"value": "alpha"
}
}
}
}
```
## netease:water_flow_source
可在netease:water_flow_source组件中设置是否在水源和流水方块中表现为含水。
| 键 | 类型 | 默认值 | 解释 |
| ----- | ---- | ------ | -------------------------------------- |
| value | bool | | 必须设置,是否在水源和流水方块中表现为含水。 |
### 示例
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"register_to_creative_menu": true,
"identifier": "customblocks:water_flow_source_test_block",
"is_experimental": false,
"category": "custom"
},
"components": {
"netease:water_flow_source": {
"value": true
},
"netease:render_layer": {
"value": "alpha"
}
}
}
}
```

View File

@@ -0,0 +1,56 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义交叉贴图方块
## 概述
自定义交叉贴图方块支持使用引擎预设的交叉贴图模型,自己配置物品贴图和模型贴图,制作出类似于甘蔗、蜘蛛网的模型方块。
![web_reeds.png](../picture/customblock/web_reeds.png)
## model_item_texture
可在model_item_texture中设置使用的物品贴图。
| 类型 | 默认值 | 解释 |
| ------ | ------ | ----------------------------------------------- |
| string | | 使用的物品贴图,必须设置"netease_model"才能生效 |
## model_texture
可在model_texture中设置使用的模型贴图。
| 类型 | 默认值 | 解释 |
| ----- | ------ | ----------------------------------------------- |
| array | | 使用的模型贴图,必须设置"netease_model"才能生效 |
- model_texture和model_item_texture必须同时设置才能生效
## 使用交叉贴图模型
- 在resource_packs\blocks.json下面添加自定义的方块identifier的配置
- 在"netease_model"里配置"customblocks:web_preset""model_item_texture"和"model_textures"根据需求配置自己的物品贴图和模型贴图
### blocks.json示例
```json
{
"format_version": [
1,
1,
0
],
"customblocks:web_preset": {
"netease_model": "customblocks:web_preset",
"model_item_texture": "customblocks:reeds_item",
"model_textures": [
"customblocks:reeds"
]
}
}
```

View File

@@ -0,0 +1,70 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义含雪方块
## 概述
自定义含雪方块支持在组件中配置自定义方块含雪的相关功能并支持python监听事件、接口设置等。
需要配置方块含雪,需设置以下两个组件
## netease:snow_recover_able
可在netease:snow_recover_able组件中设置方块是否能含雪。
| 键 | 类型 | 默认值 | 解释 |
| ----- | ---- | ------ | -------------------------------- |
| value | bool | | 必须设置,用于设置方块是否能含雪 |
## netease:can_built_over
可在netease:can_built_over组件中设置在放置其他方块时如果该位置已有含netease:can_built_over配置的方块其他方块能否和放置在此方块中。
| 键 | 类型 | 默认值 | 解释 |
| ----- | ---- | ------ | ------------------------------------------------------------ |
| value | bool | | 必须设置用于设置在放置其他方块时如果该位置已有含netease:can_built_over配置的方块其他方块能否和放置在此方块中 |
### 示例
```json
{
"format_version": "1.10.0",
"minecraft:block": {
"description": {
"register_to_creative_menu": true,
"identifier": "customblocks:customblocks_test_ore",
"is_experimental": false,
"category": "custom"
},
"components": {
"minecraft:block_light_absorption": {
"value": 0
},
"netease:render_layer": {
"value": "alpha"
},
"netease:snow_recover_able": {
"value": true
},
"netease:can_built_over": {
"value": true
},
"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.188, 1.0]
}
}
}
}
}
```
## 注意
目前自定义含雪方块和方块实体不兼容(包括自定义方块实体,自定义刷怪箱等),请不要一起使用

View File

@@ -0,0 +1,153 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义方块实体
## 概念
方块实体的概念详见[官方wiki](https://minecraft-zh.gamepedia.com/方块实体)
## 添加自定义方块实体
需要添加netease:block_entity组件才能为自定义方块添加自定义方块实体。
| 键 | 类型 | 默认值 | 解释 |
| ------- | ---- | ------ | ------------------------------------------------------------ |
| tick | bool | false | 为true时当玩家进入方块tick范围时该方块每秒会发送**20次**ServerBlockEntityTickEvent事件<br>为false时该方块不会发送ServerBlockEntityTickEvent事件 |
| movable | bool | true | 为true时该方块可被粘性活塞拉回<br>为false时该方块不可被粘性活塞拉回 |
- **对于已有方块实体的方块,如[自定义刷怪箱](./3-特殊方块/1-自定义刷怪箱.md),将无法再添加自定义方块实体。**
- 添加了自定义方块实体的方块,可通过**服务端blockEntityData组件**来管理方块实体内的数据。
## 相关组件与事件
- <a href="../../../../mcdocs/1-ModAPI/接口/方块/方块实体.html#getblockentitydata" rel="noopenner"> GetBlockEntityData接口 </a>
可用于管理方块实体内的数据。
- <a href="../../../../mcdocs/1-ModAPI/事件/方块.html#serverplaceblockentityevent" rel="noopenner"> ServerPlaceBlockEntityEvent事件 </a>
当玩家手动放置含自定义方块实体的自定义方块时触发,此时可向该方块实体中存储数据。
- <a href="../../../../mcdocs/1-ModAPI/事件/世界.html#chunkgeneratedserverevent" rel="noopenner"> ChunkGeneratedServerEvent事件 </a>
通过自定义特征放置含自定义方块实体的自定义方块时,在区块生成完毕时触发,其中包含了该区块中自定义方块实体信息列表,此时可向该方块实体中存储数据。
- <a href="../../../../mcdocs/1-ModAPI/事件/方块.html#serverblockentitytickevent" rel="noopenner"> ServerBlockEntityTickEvent事件 </a>
若在netease:block_entity组件中配置tick为true则当该自定义方块位于模拟范围内时触发。该事件触发频率为**每秒20次**
<span id="demo"></span>
## demo解释
- 方块配置
[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)中,`customblocks:customblocks_test_block_entity`方块配置了自定义方块实体,具体配置如下:
即该方块在距离玩家不远时会每秒发送20次ServerBlockEntityTickEvent事件且无法被粘性活塞拉回。
![block_entity_1](./picture/customblock/block-entity-1.png)
- 方块放置
customBlocksServer.py中注册了对ServerPlaceBlockEntityEvent事件的监听在回调里通过blockEntityData组件向每个由玩家手动创建的自定义方块实体中写入数据
```python
def ServerPlaceBlockEntityEvent(self, args):
print 'ServerPlaceBlockEntityEvent ', args
dimension = args['dimension'] # 该自定义方块实体所在的维度
blockPos = (args['posX'], args['posY'], args['posZ']) # 该自定义方块实体所处位置
blockName = args['blockName'] # 含该自定义方块实体的方块名称
# 创建blockEntityData组件
comp = self.CreateComponent(self.levelId, "Minecraft", "blockEntityData")
# 获取可操作该自定义方块实体的对象
blockEntityData = comp.GetBlockEntityData(dimension, blockPos)
# 在对自定义方块实体内数据进行操作前,要先进行判空处理
if blockEntityData:
# 使用与dict类似的操作方式存入键为"abc"、值为{"1":True,"2":None,"3":"123"}的数据
blockEntityData['abc'] = {"1": True, "2": None, "3": "123"}
```
- 方块交互
监听了ServerBlockUseEvent在其中判断玩家是否在与customblocks:customblocks_test_block_entity方块进行交互。是则向其中写入数据
```python
def ServerBlockUseEvent(self, args):
blockName = args['blockName'] # 方块名称
blockPos = (args['x'], args['y'], args['z']) # 方块位置
playerId = args['playerId'] # 玩家id
dimensionComp = serverApi.CreateComponent(playerId, "Minecraft", "dimension")
dimension = dimensionComp.GetPlayerDimensionId() # 获取玩家所在维度
# 判断交互的方块类型
if blockName == 'customblocks:customblocks_test_block_entity':
comp = self.CreateComponent(self.levelId, "Minecraft", "blockEntityData")
blockEntityData = comp.GetBlockEntityData(dimension, blockPos)
if blockEntityData:
# 向方块实体中写入键为"key"、值为[1, 2, 3]的数据
blockEntityData['key'] = [1, 2, 3]
```
- 方块实体tick
```python
def OnBlockEntityTick(self, args):
# 避免在Tick中频繁打印输出易造成卡顿
# print 'blockEntityTick ', args
pass
```
监听了ServerBlockEntityTickEvent事件netease:block_entity组件中配置tick为true的自定义方块每秒会触发20次其自定义方块实体tick事件。
- **应避免在诸如tick事件回调等高频函数中进行打印输出易造成卡顿。**
- **应避免在地图中放置过多netease:block_entity组件配置tick为true的自定义方块频繁事件调用也可能造成卡顿**
- 方块销毁
监听了ServerPlayerTryDestroyBlockEvent事件当有玩家尝试摧毁customblocks:customblocks_test_block_entity方块时会尝试从其自定义方块实体中读取数据并输出。
```python
def ServerPlayerTryDestroyBlockEvent(self, args):
pos = (args["x"], args["y"], args["z"])
playerId = args['playerId']
dimensionComp = serverApi.CreateComponent(playerId, "Minecraft", "dimension")
dimension = dimensionComp.GetPlayerDimensionId()
comp = self.CreateComponent(self.levelId, "Minecraft", "blockEntityData")
blockEntityData = comp.GetBlockEntityData(dimension, pos)
if blockEntityData:
# 根据key获取方块实体中对应的value
value1 = blockEntityData['key']
value2 = blockEntityData['abc']
print 'value of "key" is', value1
print 'value of "abc" is', value2
```
- 对于从未进行过交互的customblocks:customblocks_test_block_entity方块当玩家尝试摧毁它时会输出
```python
# 不存在于方块实体中的数据将返回None
'value of "key" is None'
'value of "abc" is {"1": True, "2": None, "3": "123"}'
```
- 若玩家曾经与该方块进行过交互,会输出:
```python
'value of "key" is [1, 2, 3]'
'value of "abc" is {"1": True, "2": None, "3": "123"}'
```

View File

@@ -0,0 +1,655 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义方块实体外观
## 概述
根据[自定义方块实体](./4-自定义方块实体.md)以及[自定义方块实体模型](./5-自定义方块模型.md)这两个步骤,我们可以做出具有个人特色的自定义方块实体,如果希望这个自定义方块实体能够具有更强的表现力,能够像原版方块实体如附魔台那样动起来,又或是具有更酷炫的特效,那么则可遵循本教程来进一步扩展我们的自定义方块实体。
自定义方块实体的扩展功能包含两个方面:
1 **为自定义方块实体添加动画功能**。支持使用由BlockBench制作的原版模型或者是游戏原版模型并支持这些模型附带的动画可以使自定义方块实体具有动画效果。
2 **为自定义方块实体添加特效功能**。通过配置或者接口可为自定义方块实体附加网易版粒子特效及序列帧特效,并且支持使用特效及序列帧等系列接口来进行控制和管理。自定义方块实体还支持配置微软原版粒子特效及音效。
接下来我们将讲解如何为我们的自定义方块实体使用以上两个扩展功能,并制作一个小松鼠自定义方块实体,用户可同时参考[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)示例中的自定义方块实体-小松鼠custom_block_squirrel学习。
## 为自定义方块实体添加动画功能
在这一节,我们将讲述如何为自定义方块实体添加动画功能
#### 1. 准备粒子特效或者序列帧特效文件
我们首先需要一个原版实体模型这个可以通过BlockBench软件进行制作这一步用户可以参考[自定义方块实体模型](./5-自定义方块模型.md)中的使用BlockBench制作小蓝花步骤但需要注意的是制作好的模型bbmodel文件**不需要通过MC Studio导入模型来生成模型的json文件**,而是只需要在制作好模型后,点击**文件-导出-导出基岩版几何体**即可,如下图所示:
<img src="./picture/customblock/model-7-1.png" style="zoom: 67%;" />
与此同时我们可以利用BlockBench为该模型制作动画在制作好动画后我们通过软件右上方切换到动画模式然后点击左上方的**动画-Export Animations**即可导出该模型的动画json文件。如下图所示
<img src="./picture/customblock/model-7-2.png" style="zoom:80%;" />
关于模型的制作以及动画的制作,用户也可以参考[原版模型制作指南](../../../16-美术/6-模型和动作/01-原版模型制作指南.md)来进行制作。制作好的模型json文件放在resource_pack/models/entity目录下 动画json文件则放在resource_pack/animations目录下这些都与原版实体生物相同。
#### 1.1 BlockBench模型调整
在使用BlockBench制作模型时往往需要知道所制作的模型在游戏中的实际大小和偏移以此为基准来调节模型的大小及位置。目前自定义方块实体外观功能所表现出的模型大小、旋转、尺寸与BlockBench里的位置、尺寸、旋转的表现效果是一致的。
如下图所示我们在BlockBench里制作一个**位置0,0,0尺寸16,16,16旋转0,0,0**且**粉红色贴图的表面正对着北方**的方块
<img src="./picture/customblock/model-7-5.png" style="zoom:80%;" />
则这个方块在游戏的表现如下图所示:
<img src="./picture/customblock/model-7-6.png" style="zoom:80%;" />
该方块在游戏中同样以粉红色贴图正对着北方且大小正好为一个普通方块大小。同时如果用户在BlockBench中调整方块的旋转及尺寸那么在游戏中会有与BlockBench相同的旋转及尺寸调整效果。在使用<a href="../../../../mcdocs/1-ModAPI/接口/方块/索引.html" rel="noopenner"> **技术手册-ModAPI-方块** </a>中的自定义方块实体模型调整接口时也与BlockBench中调整参数所带来的效果相同。
但需要注意的是用户在使用接口调整模型y轴方向的缩放时会与BlockBench的拉伸方向相反同时会在缩放模型的同时带有一段y轴方向的位置平移。
总的来说,模型调整要点可以归结如下:
1 实体json文件中scale没有定义或者定义为1时BlockBench中尺寸为16等于游戏中一个普通方块的边长长度。 实体json文件的scale定义可查看下一节介绍。
2 BlockBench中模型的面向、尺寸拉伸方向y轴除外与游戏中的表现一致。使用缩放接口调整的效果也与BlockBench中调整参数的效果一致。
3 BlockBench中位置为0,0,0时对应游戏中自定义方块实体实际的位置方块面向的南北方向、BlockBench中的坐标轴方向也与游戏中一致。
用户可在BlockBench中调整好预期的效果大部分模型的调整可在BlockBench中完成再在游戏中进行测试以减少在游戏中反复调整模型的效果所带来的时间消耗。
使用接口对模型进行缩放、旋转时的特性归结如下:
1 对模型使用<a href="../../../../mcdocs/1-ModAPI/接口/方块/渲染.html#setblockentitymodelrotation" rel="noopenner"> SetBlockEntityModelRotation </a>接口旋转
对模型使用接口进行旋转时,旋转以方块位置的西北方向的下顶点作为原点的坐标轴作为旋转轴来进行旋转,如下图所示:
<img src="./picture/customblock/model-7-7.png" style="zoom:80%;" />
假设使用接口旋转30度绕x轴旋转时会以上图中的**粗红线**作为旋转轴,以看向**x轴正方向的顺时针**旋转30度。
绕z轴旋转时会以上图中的**粗蓝线**作为旋转轴,以看向**z轴正方向的顺时针**旋转30度。
绕Y轴旋转时会以上图中的**粗绿线**作为旋转轴,以看向**y轴正方向的顺时针**旋转30度。
2 对模型使用<a href="../../../../mcdocs/1-ModAPI/接口/方块/渲染.html#setblockentitymodelscale" rel="noopenner"> SetBlockEntityModelScale </a>接口缩放
对模型使用接口进行旋转时,旋转以方块位置的西北方向的下顶点作为原点的坐标轴作为起始轴来进行拉伸,如下图所示:
<img src="./picture/customblock/model-7-8.png" style="zoom:80%;" />
假设使用接口放大2倍x轴方向放大时会以上图中的**粗蓝线**作为起始轴,向**x轴正方向**拉伸为原来的2倍长。
z轴方向放大时会以上图中的**粗红线**作为起始轴,向**z轴正方向**拉伸为原来的2倍长。
y轴方向放大时会向**y轴负方向**拉伸为原来的2倍长。
#### 1.2 方块实体的多面向
自定义方块实体外观支持四面向或六面向。如果方块实体定义了[netease:face_directional](2-功能.md#duomianxiang)组件后方块实体具有多面向功能。在没有定义该组件时方块实体的面向与BlockBench中一致即默认朝向北方。定义该组件后方块实体的面向会根据玩家放置的方向或者利用接口<a href="../../../../mcdocs/1-ModAPI/接口/世界/方块管理.html#setblocknew" rel="noopenner"> SetBlockNew </a>设置时所设定的auxValue来决定。
方块实体的面向改变后,
1 方块的面向改变**不会**影响旋转轴的改变,因为旋转轴是以世界坐标系为准。利用接口旋转方块时的旋转轴**仍然为未改变面向之前的旋转轴**,即默认朝向北方时方块的西北方向的下顶点作为原点的坐标轴。
2 方块的面向改变**会**影响拉伸方向改变,因为拉伸方向是以方块的本身的模型坐标系为准。因此面向改变后,会以面向改变后的模型坐标系来进行拉伸。例如, 方块面向默认朝向北面时x方向的拉伸方向为从西到东拉伸当方块面向变为朝向东时利用接口进行x方向的拉伸则变为从北到南可以看成模型坐标系顺时针旋转了90度。
### 2. 配置模型及动画
在准备好模型及动画文件后,我们需要进行模型及动画的配置。这一步其实与原版生物的配置相同,如果用户熟悉原版生物的配置,可以跳过这一步。
首先我们需要准备一个控制实体动画及渲染的entity.json文件这个文件在resource_pack/entity目录下创建命名为xxx.entity.jsonxxx为用户自定义的文件名称。这个文件可以参考[自定义基础生物](../3-自定义生物/01-自定义基础生物.md)中的资源包生物定义进行创建。有一定的外语阅读能力的用户还可以参考基岩版百科中的[实体创建说明](https://bedrock.dev/zh/docs/stable/Entities)以及[实体动画](https://bedrock.dev/zh/docs/stable/Animations)
我们的实体custom_block_squirrel.entity.json创建如下
```json
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
// 自定义方块实体的identitfier
"identifier": "customblocks:custom_block_squirrel",
// 指定使用的实体模型,位于resource_pack/models/entity目录下
"geometry": {
"default": "geometry.squirrel"
},
// 指定使用的模型贴图,位于resource_pack/textures/entity目录下
"textures": {
"red": "textures/entity/squirrel/red"
},
// 指定使用的模型材质
"materials": {
"red": "entity_alphatest"
},
// 指定使用的模型渲染控制器,位于resource_pack/render_controllers目录下
"render_controllers": [ "controller.render.squirrel" ],
"scripts": {
// 模型的缩放值
"scale": "0.9375",
// 实体Molang变量初始化用于切换动画状态
"initialize": [
"variable.mod_is_moving = 2.0;"
],
// 运行的动画general为我们创建的自定义动画控制器表示该模型会一直运行该动画控制器。
"animate": [
"general"
]
},
// 该模型包含的动画general为动画控制器定义在resource_pack/animations_controllers目录下
// move,idle,look_at_target为动画定义在resource_pack/animations目录下
"animations": {
"move": "animation.squirrel.move",
"idle": "animation.squirrel.idle",
"general": "controller.animation.squirrel.general"
}
}
}
}
```
以上文件创建了一个使用”geometry.squirrel”模型文件的实体该实体包含了一个名为”general“的动画控制器默认运行该动画控制器该动画控制器包含了2个动画“move”以及”idle”这些都可以参考resource_pack/animations_controllers/squirrel.animation_controllers.json中的示例
```json
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.squirrel.general": {
"initial_state" : "default",
"states": {
// 默认待机动画状态
"default": {
"animations": [ "idle" ],
"transitions": [
// 由实体Molang变量variable.mod_is_moving控制动画状态切换初始值在entity.json中的sripts字段中进行定义。
{ "squMove": "variable.mod_is_moving==1" }
]
},
// 行走动画状态
"squMove": {
"animations": ["move"],
"transitions": [
// 由实体Molang变量variable.mod_is_moving控制动画状态切换初始值在entity.json中的sripts字段中进行定义。
{ "default": "variable.mod_is_moving==2" }
]
}
}
}
}
}
```
我们定义了一个实体Molang变量”variable.mod_is_moving“该Molang变量用于在控制”general“的动画状态切换它的初始值为2.0表示实体模型的默认动画状态为“default”该动画状态运行的动画为”idle”。
### 3. 将实体模型与方块实体联系起来
在配置好实体模型以及动画之后,我们需要将这个模型与方块实体联系起来。
在resouce_pack/blocks.json文件中找到我们想要对其添加实体模型和动画的方块实体在这里我们是”customblocks:custom_block_squirrel”并加入“client_entity”的字段表示这个方块实体将会用到实体模型如下所示
```json
{
"format_version": [
1,
1,
0
],
///...
"customblocks:custom_block_squirrel": {
"sound": "grass",
// 可与netease_model字段一起使用
"netease_model": "customblocks:customblocks_model_decoration",
// --- 实体模型配置 ---
// 这个方块实体将会使用到实体模型
"client_entity": {
// 对应custom_block_squirrel.entity.json里面的identifier
"identifier": "customblocks:custom_block_squirrel",
// 这个方块实体的手持模型或掉落时模型是否使用该实体模型。
"hand_model_use_client_entity": true,
// 这个方块实体的物品icon贴图
"block_icon": "test_block_icon",
// 方块实体被破坏时使用的贴图
"destoryed_textures":"destroy_squirrel"
},
},
///...
}
```
“client_entity”的字段中包含了四个字段他们的作用分别如下表格所示
| 字段名称 | 说明 |
| ---------------------------- | ------------------------------------------------------------ |
| identifier | 对应custom_block_squirrel.entity.json里面的identifier用于指定使用resouce_pack/entity目录下的哪个entity.json文件 |
| hand_model_use_client_entity | 这个方块实体的手持模型或掉落时模型是否使用该实体模型。定义为true时玩家手持这个方块实体或者方块实体掉落在地上时显示所定义的这个实体模型。定义为false时根据用户是否定义了“netease_model”这个字段会出现两种情况<br />1定义了netease_model字段手持模型和掉落模型会显示netease_model所定义的方块模型<br />2没有定义netease_model字段手持模型和掉落模型会显示由block_icon所定义的贴图所组成的方块模型同时放置在地上的方块实体也会出现该贴图组成的方块模型。 |
| block_icon | 这个方块实体的物品icon贴图定义了这个字段后方块实体的icon贴图将会使用这个字段中的贴图贴图的路径定义resouce_pack/textures/terrain_texture.json文件中。以下情况需要定义这个字段<br />1在"hand_model_use_client_entity"为true的情况否则将看不到这个方块实体的物品icon。<br />2在"hand_model_use_client_entity"为false并且没有定义“netease_model”字段的情况。否则将看不到这个方块实体的物品icon。 |
| destoryed_textures | 可选项。方块实体被破坏时产生的粒子所取样的贴图贴图的路径定义resouce_pack/textures/terrain_texture.json文件中。方块被破坏时粒子的取样贴图按照如下优先顺序来决定<br /> 1destoryed_texures (2) block_icon (3) netease_model里面的贴图 4textures字段<br /> 即1有定义就优先使用11没有定义就使用2如此类推。 |
通过以上步骤的配置,我们就可以实现一个具有动画效果的方块实体了:
![动画实体](./picture/customblock/model-7-3.gif)
### 4. 使用接口来控制动画及调整模型
我们为用户提供了一些可用的接口来调整模型的大小,旋转及相对位置,也提供了一些用于控制动画播放的接口。这些接口可以在<a href="../../../../mcdocs/1-ModAPI/接口/方块/索引.html" rel="noopenner"> **技术手册-ModAPI-方块** </a>中查看。
| 接口 | 所属端 | 用处 |
| ------------------------------------------------------------ | -------------------------------------------------------- | ------------------------------------------------ |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/渲染.html#setblockentitymodelposoffset" rel="noopenner"> SetBlockEntityModelPosOffset </a> | <span style="display:inline;color:#7575f9">客户端</span> | 设置自定义方块实体的实体模型位置偏移值。 |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/渲染.html#setblockentitymodelrotation" rel="noopenner"> SetBlockEntityModelRotation </a> | <span style="display:inline;color:#7575f9">客户端</span> | 设置自定义方块实体的实体模型在各个轴上的旋转值。 |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/渲染.html#setblockentitymodelscale" rel="noopenner"> SetBlockEntityModelScale </a> | <span style="display:inline;color:#7575f9">客户端</span> | 设置自定义方块实体的实体模型大小的缩放值。 |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/方块实体.html#setenableblockentityanimations" rel="noopenner"> SetEnableBlockEntityAnimations </a> | <span style="display:inline;color:#7575f9">客户端</span> | 设置是否开启自定义方块实体的动画效果。 |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/方块实体.html#setblockentitymolangvalue" rel="noopenner"> SetBlockEntityMolangValue </a> | <span style="display:inline;color:#7575f9">客户端</span> | 设置自定义方块实体的Molang变量。 |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/方块实体.html#getblockentitymolangvalue" rel="noopenner"> GetBlockEntityMolangValue </a> | <span style="display:inline;color:#7575f9">客户端</span> | 获取自定义方块实体的Molang变量的值。 |
## 为自定义方块实体添加特效功能
在这一节,我们将讲述如何为方块实体添加特效功能。特效功能分为网易版特效以及微软原版特效。
### 添加网易版特效
#### 1. 准备粒子特效或者序列帧特效文件
这一步用户可以参考[粒子特效制作](../../../16-美术/9-特效/2-特效创建与使用.md#制作一个粒子特效)或者[序列帧特效制作](../../../16-美术/9-特效/2-特效创建与使用.md#制作一个序列帧特效)进行特效制作。
- 粒子特效资源中的json文件放于resource_pack/effects目录下贴图文件放于resource_pack/textures/particle目录下。
- 序列帧特效支持使用由Texture Packer导出的贴图和json序列帧文件也支持使用由MC Studio导出的序列帧json文件。如果是由Texture Packer导出的贴图和json序列帧文件均放在resource_pack/textures/sfx目录下。如果是由MC Studio导出的序列帧json文件则放于resource_pack/effects目录下。
#### 2. 配置粒子特效或者序列帧特效
与实体模型的配置相同特效的配置同样在resouce_pack/blocks.json文件中进行配置。
在resouce_pack/blocks.json文件中找到我们想要对其添加特效的方块实体在这里我们同样是”customblocks:custom_block_squirrel”并加入“netease_particle_effects”的字段或者是“netease_frame_effects”的字段表示这个方块实体将会用到特效如下所示
```json
{
"format_version": [
1,
1,
0
],
///...
"customblocks:custom_block_squirrel": {
"sound": "grass",
// 可与netease_model一起使用
"netease_model": "customblocks:customblocks_model_decoration",
// --- 实体模型配置 ---
// 这个方块实体将会使用到实体模型
"client_entity": {
// 对应custom_block_squirrel.entity.json里面的identifier
"identifier": "customblocks:custom_block_squirrel",
// 这个方块实体的手持模型或掉落时模型是否使用该实体模型。
"hand_model_use_client_entity": true,
// 这个方块实体的物品icon贴图
"block_icon": "test_block_icon",
// 方块实体被破坏时使用的贴图
"destoryed_textures":"destroy_squirrel"
},
// --- 特效配置 ---
// 使用网易粒子特效
"netease_particle_effects": {
// 粒子特效
"particle1": { "path": "effects/xy_electro_fpA_gangqinlizu.json", "pos": [1.0,0.5,1.0]},
"particle2": { "path": "effects/yx_electro_fpA_02.json", "pos": [-1.0,0.5,-1.0]}
//... 可以定义多个,注意性能消耗
},
// 使用网易序列帧特效
"netease_frame_effects": {
// 序列帧特效
"frame1": { "path": "effects/yx_electro_fzb_waiquan2.json", "pos": [1.0,1.0,1.0]},
"frame2": { "path": "textures/sfx/zhishujie_fz01", "pos": [-1.0,1.0,-1.0]}
//... 可以定义多个,注意性能消耗
}
},
///...
}
```
粒子特效或者是序列帧特效,我们使用以下格式来配置:
```json
"particle1": { "path": "effects/xy_electro_fpA_gangqinlizu.json", "pos": [1.0,0.5,1.0]}
```
其中,
- "particle1": 特效的自定义键值名称,可由用户自由决定
- "path"特效的相对路径位置对于粒子特效则该路径应该是以”effects/”开头的相对路径。对于序列帧特效,有两种情况:
1由Texture Packer导出的序列帧特效则是以“textures/“开头的相对路径,并且不需要添加.json后缀名。
2由MC Studio导出的json文件则是以”effects/”开头的相对路径,并且需要添加.json后缀名。
- "pos": 该特效的位置,是相对于方块实体位置的位置偏移,即以方块实体位置为原点的坐标系下的坐标。
通过以上两个步骤的配置,我们就可以为方块实体添加粒子特效以及序列帧特效了:
![动画实体](./picture/customblock/model-7-4.gif)
#### 3. 使用接口来控制粒子及序列帧特效
我们提供了一些接口来供用户进行方便的特效添加、删除及调整功能。这些接口可以在<a href="../../../../mcdocs/1-ModAPI/接口/方块/索引.html" rel="noopenner"> **技术手册-ModAPI-方块** </a>中查看。
同时用户可以通过定义好的特效键值名称获取在自定义方块实体上创建好的特效Id利用这个Id用户可以使用<a href="../../../../mcdocs/1-ModAPI/接口/特效/粒子.html" rel="noopenner"> **技术手册-ModAPI-特效-粒子** </a>中的粒子系列接口及<a href="../../../../mcdocs/1-ModAPI/接口/特效/序列帧.html" rel="noopenner"> **技术手册-ModAPI-特效-序列帧** </a>中的序列帧系列接口进行特效的一系列操作。
**序列帧**
| 接口 | 所属端 | 用处 |
| ------------------------------------------------------------ | -------------------------------------------------------- | ------------------------------------------------------------ |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/方块实体.html#createframeeffectforblockentity" rel="noopenner"> CreateFrameEffectForBlockEntity </a> | <span style="display:inline;color:#7575f9">客户端</span> | 在自定义方块实体上创建序列帧特效创建后该接口返回序列帧特效的Id。 |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/方块实体.html#getframeeffectidinblockentity" rel="noopenner"> GetFrameEffectIdInBlockEntity </a> | <span style="display:inline;color:#7575f9">客户端</span> | 获取在自定义方块实体中已创建的指定序列帧特效的Id。 |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/方块实体.html#removeframeeffectinblockentity" rel="noopenner"> RemoveFrameEffectInBlockEntity </a> | <span style="display:inline;color:#7575f9">客户端</span> | 移除在自定义方块实体上创建的序列帧特效。移除后的特效Id将会失效。 |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/渲染.html#setblockentityframeposoffset" rel="noopenner"> SetBlockEntityFramePosOffset </a> | <span style="display:inline;color:#7575f9">客户端</span> | 设置自定义方块实体中序列帧特效位置偏移值,用于调整序列帧特效相对于方块位置的偏移。 |
**粒子**
| 接口 | 所属端 | 用处 |
| ------------------------------------------------------------ | -------------------------------------------------------- | ------------------------------------------------------------ |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/方块实体.html#createparticleeffectforblockentity" rel="noopenner"> CreateParticleEffectForBlockEntity </a> | <span style="display:inline;color:#7575f9">客户端</span> | 在自定义方块实体上创建粒子特效创建后该接口返回粒子特效的Id。 |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/方块实体.html#getparticleeffectidinblockentity" rel="noopenner"> GetParticleEffectIdInBlockEntity </a> | <span style="display:inline;color:#7575f9">客户端</span> | 获取在自定义方块实体中已创建的指定粒子特效的Id。 |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/方块实体.html#removeparticleeffectinblockentity" rel="noopenner"> RemoveParticleEffectInBlockEntity </a> | <span style="display:inline;color:#7575f9">客户端</span> | 移除在自定义方块实体上创建的粒子特效。移除后的特效Id将会失效。 |
| <a href="../../../../mcdocs/1-ModAPI/接口/方块/渲染.html#setblockentityparticleposoffset" rel="noopenner"> SetBlockEntityParticlePosOffset </a> | <span style="display:inline;color:#7575f9">客户端</span> | 设置自定义方块实体中粒子特效位置偏移值,用于调整粒子特效相对于方块位置的偏移。 |
### 添加微软原版粒子特效及音效
微软动画功能支持在动画控制器json文件中或者动画json文件中配置粒子特效或者音效。自定义方块实体外观功能同样也支持这种配置方式。
有一定外语阅读能力的用户,可以查看[原版wiki](https://wiki.bedrock.dev/visuals/custom-particles.html)来了解关于在实体动画控制器或动画中定义粒子特效和音效的方式。
#### 1. 使用原版粒子
原版粒子的资源可以采用游戏自带的粒子资源,也可以进行自行制作,游戏自带的粒子资源可参考[Wiki中对Particles部分](https://wiki.bedrock.dev/documentation/particles.html)的罗列。自定制作的方法也可参考[这个Wiki中的介绍](https://wiki.bedrock.dev/visuals/custom-particles.html)。本指引在这里就不再叙述。
制作好的粒子资源可在游戏中使用
```
/particle <namespace:particle_id> ~ ~2 ~
```
该指令来测试是否生效。
当拥有了一些粒子资源后我们就需要在entitiy.json文件中进行声明以及在animation_controllers.json文件中进行配置。配置的方式实际上与在生物实体中配置原版粒子的方法相同如果用户对这部分的内容熟悉就可以跳过这部分的指引。
以resource_pack/entity/custom_block_squirrel.entity.json为例我们在现有的基础上增加一个particle_effects的组件
```json
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
// 自定义方块实体的identitfier
"identifier": "customblocks:custom_block_squirrel",
/// ... 省略中间的文件内容
// 该模型包含的动画general为动画控制器定义在resource_pack/animations_controllers目录下
// move,idle,look_at_target为动画定义在resource_pack/animations目录下
"animations": {
"move": "animation.squirrel.move",
"idle": "animation.squirrel.idle",
"general": "controller.animation.squirrel.general"
},
// 该模型所包含的微软原版粒子
"particle_effects": {
"headsmoke": "minecraft:water_fog"
}
}
}
}
```
并添加了一个键值为headsmoke的粒子粒子使用的是粒子资源minecraft:water_fog。
接着我们使用BlockBench对模型添加一个名为head_locator的Locator定位器来决定我们的粒子在模型中的位置我们可以对模型的head组件右键点击添加定位器导出保存即可
![动画实体](./picture/customblock/model-7-9.png)
有了定位器及粒子定义后我们就可以打开animation_controllers.json文件来决定我们的粒子在哪个动画状态进行播放了
以squirrel.animation_controllers.json为例我们对default动画状态配置这个粒子在default动画状态中添加一个名为particle_effects的序列
```json
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.squirrel.general": {
"initial_state" : "default",
"states": {
// 默认待机动画状态
"default": {
"animations": [ "idle" ],
// 该动画状态所播放的原版粒子效果
"particle_effects": [
{
// entity.json中定义的粒子名称
"effect": "headsmoke",
// geometry中定义的定位器
"locator": "head_locator"
}
//,
//... 可配置多个原版粒子
],
"transitions": [
// 由实体Molang变量"variable.mod_is_moving"控制动画状态切换初始值在entity.json中的sripts字段中进行定义。
{ "squMove": "variable.mod_is_moving==1" }
]
}
///, ... 其他动画状态
}
}
}
}
```
至此,我们就完成了一个微软原版粒子效果的配置了。
另外粒子的配置不仅可以在animation_controllers.json中进行配置也可以直接在对应的动画文件animations.json中进行配置。
以squirrel.animation.json为例我们直接对idle动画进行粒子配置配置方式是在动画定义中添加一个particle_effects的序列同时以动画时间为键值来决定我们的粒子效果在动画播放到什么时候进行播放
```json
{
"format_version": "1.8.0",
"animations": {
"animation.squirrel.idle": {
"loop": true,
"animation_length": 2,
"bones": {
/// ... 省略骨骼内容
},
/// 原版粒子
"particle_effects": {
/// 在0.4833这个动画帧播放粒子效果
"0.4833": {
// entity.json中定义的粒子名称
"effect": "headsmoke",
// geometry中定义的定位器
"locator": "head_locator"
}
}
}
}
```
#### 2.使用原版音效
音效的定义及配置方式实际上与原版粒子特效的方式类似,用户也可以参考这个[指引](https://wiki.bedrock.dev/concepts/sounds.html)来进行。
我们首先需要在resource_pack/sounds/sound_definitions.json定义好我们的音效如果没有这个json文件则需要自己创建。它的内容如下
```json
{
"format_version": "1.14.0",
"sound_definitions": {
// 定义一个自定义音效
"squirrel.idle.thunder": {
"category": "music",
"min_distance": 0.0,
"max_distance": 5.0,
"sounds": [
{
"name": "sounds/music/blocks",
"pitch": 1,
"volume": 1,
"load_on_low_memory": true
}
]
}
}
}
```
在这个文件中我们定义了一个名叫squirrel.idle.thunder的自定义音效。
接下来与原版粒子特效的配置类似我们需要在entity.json文件中声明这个音效
```json
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
// 自定义方块实体的identitfier
"identifier": "customblocks:custom_block_squirrel",
/// ... 省略中间的文件内容
// 该模型包含的动画general为动画控制器定义在resource_pack/animations_controllers目录下
// move,idle,look_at_target为动画定义在resource_pack/animations目录下
"animations": {
"move": "animation.squirrel.move",
"idle": "animation.squirrel.idle",
"general": "controller.animation.squirrel.general"
},
// 该模型所包含的微软原版粒子
"particle_effects": {
"headsmoke": "minecraft:water_fog"
},
// 该模型所包含的自定义音效
"sound_effects": {
"thunder": "squirrel.idle.thunder"
}
}
}
}
```
在entity.json中声明了该音效之后我们就可以在animation_controllers.json或者animations.json中使用这个音效了。
注意format_version为1.8.0的版本的animation_controller.json**不支持**sounds_effects组件的配置否则会报错。用户需要改成1.10.0的版本。
以squirrel.animation_controllers.json为例我们对default动画状态配置这个音效实际就是增加一个"sound_effects"的序列:
```json
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.squirrel.general": {
"initial_state" : "default",
"states": {
// 默认待机动画状态
"default": {
"animations": [ "idle" ],
// 该动画状态所播放的原版粒子效果
"particle_effects": [
{
// entity.json中定义的粒子名称
"effect": "headsmoke",
// geometry中定义的定位器
"locator": "head_locator"
}
//,
//... 可配置多个原版粒子
],
// 该动画状态所播放的自定义音效
"sound_effects": [
{
// 使用thunder这个自定义音效
"effect": "thunder"
}
],
"transitions": [
// 由实体Molang变量"variable.mod_is_moving"控制动画状态切换初始值在entity.json中的sripts字段中进行定义。
{ "squMove": "variable.mod_is_moving==1" }
]
}
///, ... 其他动画状态
}
}
}
}
```
以squirrel.animation.json为例我们直接对idle动画进行音效配置配置方式与粒子特效也类似。注意format_version为1.8.0的版本的animations.json**支持**sounds_effects组件的配置。
```json
{
"format_version": "1.8.0",
"animations": {
"animation.squirrel.idle": {
"loop": true,
"animation_length": 2,
"bones": {
/// ... 省略骨骼内容
},
/// 原版粒子
"particle_effects": {
/// 在0.4833这个动画帧播放粒子效果
"0.4833": {
// entity.json中定义的粒子名称
"effect": "headsmoke",
// geometry中定义的定位器
"locator": "head_locator"
}
},
/// 自定义音效
"sound_effects": {
"0.4833": {
"effect": "thunder"
}
}
}
}
```
至此,我们就完成了自定义音效的配置。

View File

@@ -0,0 +1,295 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义方块模型
## 概述
下面将按照[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)示例中的三个自定义模型方块由浅入深讲述如何借助BlockBench以及MCStudio搭建自定义方块的模型。
## 从零开始制作方块模型 - 小蓝花
手把手指导如何制作[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)示例中的小蓝花customblocks_model_flower
在示例中的`resource/bbmodel/flower`中提供了小蓝花的工程文件。
### 使用BlockBench制作模型
1. 找个地方新建一个文件夹作为工作路径,并准备好小蓝花的贴图
![image-20200713141928885](./picture/customblock/model-a-0.png)
1. 打开blockbench这里使用的版本为3.3.1)。
在File->Settings->General可设置为中文重启blockbench生效。
<img src="./picture/customblock/model-0--1.png" alt="image-20200304174000311" style="zoom:67%;" />
1. 新建一个“自由模型”项目,填写文件名以及几何体名称。
盒子UV不要勾选贴图长宽最大不能超过64。在下面示例中我们使用16x16的贴图。
![image-20200713142240647](./picture/customblock/model-a-1.png)
1. 游戏里一个方块的大小对应为16 x 16 x 16即面板上网格的大小。网格上的N标识了北面的朝向
![image-20200713143140863](./picture/customblock/model-a-2.png)
1. 为了避免光照影响预览,可以打开文件->设置->预览,把“阴影”去掉
<img src="./picture/customblock/model-0-3-1.png" alt="image-20200304174348146" style="zoom:67%;" />
1. 打开文件->设置->默认把“自动UV“勾上这样调整cube大小时各个面的uv大小也会自动跟着调整
<img src="./picture/customblock/model-0-3-2.png" alt="image-20200304174844623" style="zoom:67%;" />
1. 将小蓝花贴图拖进来
![image-20200713143419975](./picture/customblock/model-a-3.png)
1. 添加一个cube调整其大小位置及旋转使其的north面位于16 x 16网格的对角线上
![image-20200713143645975](./picture/customblock/model-a-4.png)
1. 选择北面然后把小蓝花贴图拖上去。这样这个cube的北面就应用了小蓝花贴图
![image-20200713144036430](./picture/customblock/model-a-5.png)
1. 点击插件目录-移除空白面。这样这个cube就会只显示北面
![image-20200713144141391](./picture/customblock/model-a-6.png)
1. 重复上面三步,添加另一个垂直的面片
![image-20200304210159699](./picture/customblock/model-0-7.png)
1. 点击文件-保存工程,保存到我们刚才放贴图的路径。
![image-20200713144454174](./picture/customblock/model-a-7.png)
### 使用MCStudio导入模型
1. 打开MCStudio新建一个AddOn或者导入已有的然后启动编辑
![image-20200714115027639](./picture/customblock/model-a-8.png)
1. 设置好命名空间
![image-20200714141322104](./picture/customblock/model-a-11.png)
1. 在资源管理器中选择导入方块模型
![image-20200714115834234](./picture/customblock/model-a-9.png)
1. 选择我们刚才保存的BlockBench工程文件
![image-20200714120055068](./picture/customblock/model-a-10.png)
这一步导入的背后MCStudio做了这些操作
* 将bbmodel工程文件转换为自定义方块模型格式的json并放到`resourcepack/models/netease_block`
* 将贴图拷贝到了`resourcepack/textures/blocks`
* 将贴图配置到了`resourcepack/textures/terrain_texture.json`
### 配置其他需要的文件
MCStudio帮我们做了一些工作接下来还有几个文件需要手动配置
1. 编写behavior的定义
<img src="./picture/customblock/model-0--2.png" alt="image-20200304213457975" style="zoom:67%;" />
2.`resourcepack/blocks.json`中,添加该方块
<img src="./picture/customblock/model-0-11.png" alt="image-20200304212134086" style="zoom:80%;" />
其中使用“netease_model”配置为`resourcepack/models/netease_block`中生成的模型json的identifier。
![image-20200714145835565](./picture/customblock/model-a-12.png)
3. 完成一个自定义模型方块所涉及的路径汇总:
<img src="./picture/customblock/model-0-12.png" alt="image-20200304220109659" style="zoom:67%;" />
## 制作更复杂的模型 - 装饰品
大致流程与小蓝花类似比较重复的内容不再赘述不同之处只在于blockbench中的操作。
这里讲述当单张16x16贴图不足以满足需求时如何制作具有多张贴图的模型以及uv翻转及uv旋转的使用
**注意我们使用多张16x16贴图来解决贴图大小的需求而不是使用高分辨率的贴图**
在[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)示例中的`resource/bbmodel/decoration`中提供了装饰品的工程文件。
### 多贴图模型
对一些比较复杂的模型单张16x16的贴图不够用时可以把不同的骨骼立方体或者面绘制到多张贴图上。
1. 新建一个自由模型的工程搭好骨骼与cube
![image-20200714161411832](./picture/customblock/model-a-14.png)
2. 新建一个工作目录准备好要用到的贴图并且全部拖进BlockBench。
![image-20200714161536270](./picture/customblock/model-a-13.png)
3. 给每个cube的每个面配置UV
熟悉BlockBench的开发者也可以使用右上角的画板模式来绘制方块模型
![image-20200714161947428](./picture/customblock/model-a-15.png)
### uv的翻转与旋转
可以直接使用BlockBench的UV旋转以及UV镜像功能。贴图的右上角会显示该面使用的旋转与翻转。
![image-20200714195619078](./picture/customblock/model-a-16.png)
## 制作可变化的模型 - 电线
大致流程与小蓝花类似比较重复的内容不再赘述不同之处只在于blockbench中的操作对导出模型json的调整以及behavior中方块json的定义。
这里讲述如何制作会随周围方块不同而发生改变的模型。
在[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)示例中的`resource/bbmodel/wire`中提供了电线的工程文件。
1. 在behavior的定义中使用[netease:connection](./1-JSON组件#netease:connection)配置与其他方块的“连接”属性
示例中的电线,与熔炉,草方块,以及电线自身具有“连接"属性
![image-20200308121341271](./picture/customblock/model-3-1.png)
2. 分析电线的效果:当六个方向都没有可连接的方块时,只显示一个中间小方块;当某个方向上的方块可以连接时,则从中间”长“出一个长方体与其连接。
<img src="./picture/customblock/model-3-.png" alt="image-20200308122302847" style="zoom:67%;" />
3. 那么当六个方向都有可连接的方块时电线的模型将由一个中心正方体六个长方体构成。于是在blockbench中将他们搭好。这里为了显示出层次感把设置中的“阴影”启用了
![image-20200714195941072](./picture/customblock/model-a-17.png)
4. 如果细心观察可以发现,那六个长方体中的每一个,都会有其中两个面是永远看不到的,可以进行优化,把他们设置为透明。跳过这一步不会影响实际效果,但还是推荐开发者们进行性能优化。
![image-20200714200050901](./picture/customblock/model-a-18.png)
5. 使用MCStudio导入后打开`resourcepack/models/netease_block`中导出的json在六个长方体的骨骼中添加enable字段该字段的详细解释见[模型文件结构](#模型文件结构)
<img src="./picture/customblock/model-3-4.png" alt="image-20200308172042542" style="zoom:67%;" />
6. 示例中将中间root骨骼的正方体手动拆成了六个骨骼每个骨骼分别只有其中的一个面。这是因为如果某些方向连接了其他方块时中间正方体的某些面是看不到的不需要渲染。跳过这一步不会影响实际效果但还是推荐开发者们进行性能优化。
![image-20200308172753618](./picture/customblock/model-3-5.png)
7. 额外制作一张用于物品形式渲染的贴图并配置到模型json中。
对于可变模型物品形式下具有enable条件的骨骼都不会绘制一般需要使用单独的物品贴图。
![image-20200308180112542](./picture/customblock/model-3-8.png)
![image-20200308180201587](./picture/customblock/model-3-7.png)
8. 开启环境光遮蔽,可以与自身相连的方块模型一般需要开启,可以改善在室内或夜晚时,相邻方块亮度不一样时的情况。
<img src="./picture/customblock/model-3-9.png" alt="image-20200308181036127" style="zoom:67%;" />
9. 在behavior的方块json中将aabb同样拆分为中间一个正方体以及周围的六个长方体。该组件的详细解释见[netease:aabb](./1-JSON组件#netease:aabb)
<img src="./picture/customblock/model-3-6.png" alt="image-20200308175056402" style="zoom:67%;" />
<span name="moxingwenjianjiegou"></span>
## 模型文件结构
- `resource/models/netease_block`中模型json的详细参数解释
| 键 | 类型 | 解释 |
| ---------------------- | ------ | -------------------------------------------- |
| format_version | string | 目前为1.13.0对应blockbench 3.3.1及以上版本 |
| netease:block_geometry | object | |
- netease:block_geometry结构
| 键 | 类型 | 解释 |
| ----------- | ------------- | ---------------------- |
| description | object | 模型的基本信息 |
| bones | array(object) | 模型的骨骼及立方体信息 |
- description结构
| 键 | 类型 | 解释 |
| --------------------- | ------------- | ------------------------------------------------------------ |
| identifier | string | 模型的标识符,建议使用命名空间加名称的方式命名 |
| textures | array(string) | 该模型用到的贴图与terrain_texture.json中对应 |
| item_texture | string | 可选<br>该方块的物品形态的贴图与terrain_texture.json中对应。<br>配置了该项时手持、UI物品格子、掉落物等物品形态使用该贴图渲染而非方块模型 |
| use_ao | bool | 可选,是否启用环境光遮蔽。<br>启用时方块的亮度会更加自然,但总体会比不启用时要暗一点<br>默认不开启 |
| textures_descriptions | array(dict) | 每张模型贴图的实际分辨率的长和宽配置长宽最大不能超过64超过则会使用64。与textures数组中的同一下标位置的贴图一一对应。即第一张贴图的长宽配置为"textures_descriptions"中第一个长宽对,第二张贴图的长宽配置对应"textures_descriptions"中第二个长宽对如此类推。如果textures中定义的贴图没有在"textures_descriptions"找到对应的贴图长宽配置则会使用默认值width = 16 length = 16。<br/>填写示例:<br/>`"textures_descriptions":[ { "width": 32, "length":32} , { "width": 64, "length":64} , { "width": 16, "length":16} ]`<br/>**width和length的值请根据贴图的实际分辨率进行填写。** |
- bones每个元素的结构
除了texture及enable项需要另外配置其余均可使用blockbench生成。
| 键 | 类型 | 解释 |
| -------- | ------------- | ------------------------------------------------------------ |
| name | string | 该骨骼的名称 |
| parent | string | 父骨骼的名称 |
| pivot | array(float) | 该骨骼的旋转中心 |
| rotation | array(float) | 该骨骼绕旋转中心的旋转 |
| texture | int | 可选<br>该骨骼使用的贴图对应description中textures数组的下标。<br>默认为0 |
| enable | molang | 可选。控制该骨骼是否渲染。默认返回true<br>目前仅支持is_connect查询详见[netease:connection](./1-JSON组件.md#netease_connection) |
| cubes | array(object) | 该骨骼所包含的立方体的信息 |
- cubes每个元素的结构
除了texture需要另外配置其余均可使用blockbench生成。
| 键 | 类型 | 解释 |
| -------- | ------------ | ------------------------------------------------------------ |
| origin | array(float) | 该立方体最小点的位置 |
| size | array(float) | 该立方体的大小 |
| pivot | array(float) | 该立方体的旋转中心 |
| rotation | array(float) | 该立方体绕旋转中心的旋转 |
| texture | int | 可选。该立方体使用的贴图对应description中textures数组的下标。<br>缺省时会继承所在骨骼使用的贴图 |
| uv | object | 该立方体包含的面的信息<br>可选的面包括updownnorthsouthwesteast<br>可以只选其中若干个面渲染。 |
- uv中每个元素的结构
除了texture需要另外配置其余均可使用blockbench生成。
| 键 | 类型 | 解释 |
| ------- | ---------- | ------------------------------------------------------------ |
| uv | array(int) | 起始uv坐标 |
| uv_size | array(int) | uv的大小 |
| texture | int | 可选。该立方体使用的贴图对应description中textures数组的下标。<br/>缺省时会继承所在立方体使用的贴图 |
| rot | int | 将uv顺时针旋转的角度<br>可选90180270 |
## 注意事项
- 目前每张贴图尺寸不能超过64x64
- **[特殊方块](./3-特殊方块/0-特殊方块概述.md)不支持自定义方块模型**(农作物除外)
- **使用模型的方块支持[netease:face_directional](./1-JSON组件.md#netease_face_directional)中的四面向,但不支持六面向**。当使用多面向时is_connect查询会根据当前的面向自动匹配
- 使用自定义方块模型时,需要配合[minecraft:block_light_absorption](./1-JSON组件.md#minecraft_block_light_absorption)使用,否则模型会变黑
- 需要用到全透明或半透明时,可配合[netease:render_layer](./1-JSON组件.md#netease_render_layer)使用,但是属性会应用到整个模型
- 请勿将自定义模型方块用于自定义群系的构成中,也避免在频繁出现的自定义特征中放入大量自定义模型方块
- 立方体不支持inflate功能
![image-20200309171920798](./picture/customblock/model-4-1.png)

View File

@@ -0,0 +1,15 @@
---
front:
hard: 入门
time: 分钟
---
# 常见报错
1. JSON: xxx has an error
一般为json格式有问题可以检查一下逗号是否漏写或多写括号是否对应。
下图为多写逗号的报错:
![error-1](./picture/customblock/error-1.png)

View File

@@ -0,0 +1,94 @@
---
front:
hard: 入门
time: 分钟
---
# demo解释
[CustomBlocksMod](../../13-模组SDK编程/60-Demo示例.md#CustomBlocksMod)中定义了以下自定义方块:
- customblocks:customblocks_test0
上表面与其他面不同的方块。
`resource/blocks.json`中将isotropic的up设置为true使其上表面在放置时会随机旋转可以达到视觉上没有明显的贴图重复的效果属于微软自定义方块的功能
演示了构成自定义群系,村民交易,自定义配方,方块组合的功能
- customblocks:customblocks_test_ore
性质与矿物相似的自定义方块
演示了挖掘,掉落物的功能
- customblocks:customblocks_test_face4
拥有4个面向的方块
演示了多面向中四面向的功能
- customblocks:customblocks_test_face6
拥有6个面向的方块
演示了多面向中六面向的功能
- customblocks:customblocks_test_mobspawner
自定义刷怪箱方块-原生生物
演示了“特殊方块-自定义刷怪箱”中生成原生生物的功能
- customblocks:customblocks_test_mobspawner1
自定义刷怪箱方块-微软自定义生物
演示了“特殊方块-自定义刷怪箱”中生成微软自定义生物的功能
- customblocks:customblocks_test_portal_blue
前往维度3的自定义传送门方块
演示了“特殊方块-自定义传送门方块”的功能
- customblocks:customblocks_test_block_entity<span id="demo解释_block_entity"></span>
含自定义方块实体的自定义方块
演示了自定义方块实体相关功能,详细解释见[自定义方块实体](./4-自定义方块实体.md#demo)文档
- customblocks:customblocks_model_flower
花形状的自定义方块
演示了自定义方块模型,亮度,碰撞盒,渲染材质,是否实心,是否可寻路的功能
- customblocks:customblocks_flower_extend
除了涵盖customblocks_model_flower花形状的自定义方块的基本功能外额外拓展了实体穿过时减速、重力方块下落时被破坏等功能。
- customblocks:customblocks_model_decoration
四面向的使用自定义模型的方块
- customblocks:customblocks_model_wire
电线形状的自定义方块,可与旁边的其他电线,熔炉或草方块相连
演示了可变模型与可变碰撞箱
- customblocks:customblocks_test_heavy
演示了自定义重力方块
- customblocks:customblocks_slime
利用netease:block_properties组件和python事件复刻了一个原版粘液块特性
演示了自定义实体方块外观功能
- customblocks:custom_block_squirrel
包含了自定义实体方块的实体模型配置,网易版粒子、序列帧特效、微软原版粒子特效及音效配置。

View File

@@ -0,0 +1,183 @@
---
front:
hard: 入门
time: 分钟
---
# 自定义熔炉Demo
### 概述
[CustomFurnaceMod](../../13-模组SDK编程/60-Demo示例.md#CustomFurnaceMod)利用自定义方块以及ModSDK相关事件及接口复刻了原版熔炉的UI及逻辑。
**注在该demo中采用的是PE的尺寸在PC上更改窗口大小可能会造成背包界面一定的显示误差**
### 已支持功能
- 一个自定义方块
- 点击该方块会打开熔炉界面
- 界面包含以下功能:
- 界面和原版熔炉一致
- 界面的背包可以正常显示玩家背包的物品
- 点击背包格子,再点击输入格子,可以交换两个格子的物品
- 点击背包格子,再点击燃料格子,可以交换两个格子的物品
- 当燃料格子和输入格子中都有物品且物品组合在配置中存在时隔一定时间消耗燃料和输入在输出格子生成1个物品
- 交换物品时有飞行动画
- 燃烧时有对应的火焰燃烧动画和进度动画
- 输出格子物品达到叠加上限时,停止生成
- 输入格子和燃料格子、输出格子中的物品会存储在blockentity中即使没有打开熔炉也会继续烧炼
### 1.18新增功能
- 长按分堆操作
- 双击合堆操作
- 点击物品格子显示tips
- 装备耐久度显示
- 物品附魔状态显示
- 正确显示灾厄旗帜及各种经织布机织过的旗帜
- 点选物品格子之后点击其他地方丢弃物品
- 方块破坏后会掉落方块中的物品
- 方块被破坏、玩家死后正确关闭UI
- 在打开UI的情况下获取物品能够正确更新UI
- 生成物品时不需要再由开发者控制生成的最大堆叠数,由相应的接口直接获取
### Demo主要文件介绍
- recipeMgrBase.py
- 实现烧炼配方基类的管理,一类自定义熔炉方块对应一个熔炉配方类,熔炉配方类继承自该基类,需实现如下基础接口:
- `GetFurnaceResult(self, inputItem)`:根据原料返回生成物
- `GetBurnDuration(self, fuelItem)`:根据燃料返回燃料燃烧时间
- `IsFuelItem(self, item)`根据传入item判断是否为燃料
- 烧炼配方及燃烧列表在各子类中初始化的时候配置,如果燃料不在烧炼列表中将无法放置到燃料槽
- furnaceMgrBase.py
- 熔炉管理基类实现熔炉的烧炼逻辑需要在ServerBlockEntityTickEvent事件中对自定义熔炉方块进行Tick主要烧炼判断在Tick函数中进行如果Tick结束有UI或者数据发生变动需要更新客户端UI以及服务端blockEntityData
- 一类自定义熔炉方块对应一个熔炉管理类,熔炉管理类继承自该类,需实现如下接口:
- `CanBurn(self)`:判断是否能够烧炼
- `Burn(self)`:烧炼过程,消耗原料生成烧料物
- `CanSet(self, slotName, item)`:传入槽名和物品,返回是否可以放置
- customFurnaceServer.py
- 自定义熔炉服务端继承自CustomContainerServerSystem基类实现了打开容器、破坏容器以及基础的交换物品和丢弃物品功能需在子类实现如下接口
- `GetCustomContainerItems(self, dimension, blockName, blockPos)`传入自定义容器方块的数据返回容器中所有item信息
- `OnCustomContainerItemSwap(self, playerId, fromSlot, fromItem, toSlot, toItem)`当交换的物品涉及自定义容器时调用返回True表示允许交换返回False禁止交换交换成功时需要更新对应容器方块的blockEntityData
- `ResetCustomContainer(self, dimension, blockName, blockPos)`当自定义熔炉被摧毁的时候调用需要在该函数下删除对应的furnaceManager
- `OnCustomContainerItemDrop(self, playerId, slot)`当丢弃自定义容器的物品时调用返回True表示允许丢弃返回False禁止丢弃丢弃成功时需要更新对应容器方块的blockEntityData
- OnBlockEntityTick:在该事件下实现自定义熔炉的tick逻辑
- customFurnaceClient.py
- OnCustomFurnaceChanged处理服务端发来的烧炼状态发生变化的事件包括燃烧状态发生变化以及熔炉数据发生变化更新UI显示
- OpenCustomFurnace处理服务端发来的打开UI事件
- OnItemSwap处理服务端发来的物品交换事件
- customFurnaceUI.py
- 对熔炉界面进行管理继承自CustomContainerUIScreenBase需实现以下接口
- `InitCustomContainerUI(self, args)`初始化自定义容器的UIdemo中是初始化自定义熔炉中输入、燃料和生成三个槽的UI
- `UpdateCustomContainerUI(self, args)`更新自定义容器的UIdemo中更新了燃烧状态、燃料数据以及自定义槽位的UI
- `Update(self)`该函数每帧调用需先执行父类的Update然后再实现自己的Update逻辑。其中父类的Update实现了交换物品时的飞行动画
- modConfig.py
- 需在该文件配置以下数据
- BURN_INTERVAL燃烧时间间隔int单位秒每经过该间隔可烧炼生成物品目前是所有熔炉统一的如有需求开发者可以自行修改
- FLY_ANIMATION_DURATION飞行动画时间间隔int单位帧开发者可以根据自己想要的表现形式来配置该帧数
- CUSTOM_CONTAINER_LISTlist存放所有自定义熔炉方块的identifier
- FURNACE_SLOT_NUM_DICTdict存放所有自定义熔炉方块对应的自定义槽数至少3个原料槽、燃料槽和生成槽各一个目前架构仅支持1个生成槽+1个燃料槽+n个原料槽大于等于1
- FURNACE_SLOT_PREFIX自定义熔炉槽前缀用于UI文件中命名必须严格满足“前缀+数字”的格式,比如`furnaceSlot0`在本demo中序号0为生成槽1为燃料槽大于1为原料槽
- UI_DEFS自定义容器的UI对应关系为字典类型key是自定义容器对应的自定义方块的identifiervalue为其配置包括以下几个字段
- `uiName`对应ui的json文件名不含.json
- `uiClassPath`对应容器的ui管理类
- `uiScreenDef`对应UI的根节点
- furnaceManagerFactory.py
- 熔炉管理工厂类,根据方块名称创建不同的熔炉管理类,如果开发者有创建不同自定义熔炉的需求需要在这里加上对应的工厂生成方法
### UI实现细节
- neteaseCommonUI.json
- 该文件提供了一些模板控件比如itemBtn可以作为背包格子或者熔炉格子
- 可以通过继承来使用这些控件参考customFurnaceUI.json中的`furnaceSlot0`
- 背包界面
- 采用ScrollView滑动窗口
- 窗口内容采用Grid网格排列
- Grid的模板组件主要分为4部分可复用该控件模板参考自定义熔炉槽位
- ImageButton负责相应点击
- Image负责显示点击状态
- Label负责显示堆叠数
- ItemRenderer负责显示物品渲染
- 点选时候的物品信息Tips使用了alpha属性来控制透明度同时通过binding绑定来控制该alpha属性以实现渐隐效果
- 熔炉界面
- 熔炉槽实现同Grid模板组件
- 火焰及烧炼进度调用SetSpriteClipRatio新图片裁剪接口实现燃烧动画
- 飞行动画
- 通过一个imagePool来管理飞行的ItemRenderer在交换物品时显示其他时候隐藏并在Update中调用SetPosition来更新其位置实现飞行动画效果
- 其他
- 背景图片采用Image原生九宫格裁剪
### 基于Demo扩展开发流程参考
假设我们的需求是开发一个使用不同配方的自定义熔炉
1. 创建一个自定义方块并把其identifier添加到modConfig.py的CUSTOM_FURNACE_LIST和FURNACE_SLOT_NUM_DICT中因为UI没有做改动FURNACE_SLOT_NUM_DICT中对应的槽数同样是3
2. 创建一个newFurnaceRecipeMgr.py继承自RecipeManagerBase配方管理基类并实现GetFurnaceResult、GetBurnDuration、IsFuelItem三个接口在初始化函数中配置对应的配方列表及燃料列表可参考furnaceRecipeManager.py
3. 创建一个newFurnaceManagerGas.py继承自FurnaceManagerBase熔炉管理基类在初始化函数中初始化对应的配方管理类使用第二步中创建的配方管理类`self.recipeMgr = NewFurnaceRecipeManager()`并实现CanBurn、Burn、CanSet三个接口可参考furnaceManagerGas.py
4. 在furnaceManagerFactory.py中添加自定义方块名对应的工厂创建方法
目前所有自定义熔炉使用同一个UI如果有添加原料槽的需求除了需要改动上述地方外还需要修改customFurnaceUI.json文件增加对应槽的UI命名方式必须严格满足“前缀+数字”的格式,比如`furnaceSlot3`0、1、2依次为生成槽、燃料槽和默认原料槽新增的槽编号从3开始逐个添加槽位UI可以直接继承`neteaseCommonUI.itemBtn`,并将该控件节点放置于`rightPanel`下即可,代码如下:
```json
"furnaceSlot0@neteaseCommonUI.itemBtn" : {
"$item_button_layer" : 14,
"$item_button_offset" : [ 42, -16 ],
"$item_button_size" : [ 32.0, 32.0 ],
"$item_button_anchor_from" : "center",
"$item_button_anchor_to" : "center"
}
```
其中各字段数据解释如下:
| 字段名 | 描述 | 默认值 |
| :----------------------: | :--------------------: | :------: |
| $item_button_layer | 显示层级 | 1 |
| $item_button_offset | 偏移 | [0, 0] |
| $item_button_size | 尺寸 | [28, 28] |
| $item_button_anchor_from | 挂接在父节点锚点的位置 | "center" |
| $item_button_anchor_to | 自身挂接锚点的位置 | "center" |
### 基于Demo扩展开发流程
现在我们的自定义熔炉demo可以用于任何需要背包实现的容器比如我们现在创建一个自定义箱子没有其他逻辑仅用于保存物品其参考开发流程如下
1. 创建一个自定义方块并把其identifier添加到modConfig.py的CUSTOM_CONTAINER_LIST
2. 参考customFurnaceUI.json文件修改其rightPanel下的控件以实现一个箱子的UI
3. 实现对应的UI控制器需继承CustomContainerUIScreenBase类可参考CustomFurnaceUIScreen.py其中下列两个函数必须实现
1. `InitCustomContainerUI()`用于初始化自定义容器的UI需要把所有物品格子的信息保存至两个变量存放该信息后会自动注册对应槽位的按键监听事件物品格子的UI需继承自neteaseCommonUI中的itemBtn可参考customFurnaceUI.json中furnaceSlot0的实现
1. `self.mBagInfo`以字典形式存放所有物品格子的信息其中key为`slotPath`也就是ui控件的路径value有两个一个是"slot"槽位名约定背包槽位名用int自定义熔炉的槽位名用str**需严格遵守**;另一个是"itme"存放该物品格子中物品的itemDict。
2. `self.mSlotToPath`以字典形式存放槽位名到ui控件的路径的映射key为槽位名value为ui控件的路径
2. `UpdateCustomContainerUI()`用于更新自定义容器中的UI需结合对应的服务端事件实现
4. 实现对应的服务端系统需继承CustomContainerServerSystem可参考CustomFurnaceServerSystem.py其中下列几点必须实现
1. 在初始化函数中需初始化可以进行右键打开的容器列表这里使用了modConfig中的CUSTOM_CONTAINER_LIST来进行初始化
```python
self.mCustomContainer = modConfig.CUSTOM_CONTAINER_LIST
```
2. `GetCustomContainerItems()`该函数会在父类中调用需要在这里实现从blockEntityData中获取自定义容器的所有物品的信息返回一个dict其中key为槽位名上面第3点中有说约定为strvalue为该槽位的物品信息也就是其itemDict
3. `ResetCustomContainer(self, dimension, blockName, blockPos)`,该函数会在已放置的自定义容器被破坏时调用,需要处理一些重置操作,比如自定义熔炉需要在这个时候删除对应的熔炉管理器
4. `UpdateCustomContainer()`该函数会在右键打开自定义容器以及发生相关交换物品操作时调用用于更新自定义容器除物品槽以外的其他状态信息比如自定义熔炉通过该函数更新燃烧状态及燃烧动画并通过modConfig.OnCustomContainerChangedEvent该事件通知客户端调用`UpdateCustomContainerUI()`去更新自定义容器的UI传的参数可由开发者自定义
5. `OnCustomContainerItemSwap()`该函数会在自定义容器和背包之间发生物品交换的时候调用之前的槽位名约定就是用于此处分辨是哪个容器的物品。需要在该函数中返回False表示禁止交换如果返回True允许交换需要先调用`SpawnItemToPlayerInv()`或`SetInvItemNum()`更新对应背包槽位的物品同时更新blockEntityData中的数据。如果有其他逻辑相关的比如自定义熔炉需要熔炉管理器来tick物品的生成与消耗还需要在此函数中更新对应管理器的数据。
6. `OnCustomContainerItemDrop()`该函数会在丢弃自定义容器中的物品的时候触发返回False表示禁止丢弃返回True允许丢弃前需要先更新blockEntityData中的数据。如果有其他逻辑相关的比如自定义熔炉需要熔炉管理器来tick物品的生成与消耗还需要在此函数中更新对应管理器的数据。

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 KiB

Some files were not shown because too many files have changed in this diff Show More