同步官网文档

This commit is contained in:
kwiilh
2025-11-17 15:44:17 +08:00
parent fc5d4989a4
commit 6359cfa4b4
2 changed files with 37 additions and 385 deletions

View File

@@ -378,7 +378,7 @@ mc里的特效实例有两种承载方式一种是在世界空间单独存在
动画是否循环播放如果设置为false则会在每个发射器的生命周期开始时重新播放动画。
- `size`
设置发射出来的骨骼模型的大小支持molang表达式。
- `ignore_lighting`3.6beta版内容)
- `ignore_lighting`
设置粒子模型是否受到环境光照影响与实体json中ignore_lighting作用相同。该值设置为true时粒子模型不受环境光影响始终保持默认亮度。
```json

View File

@@ -1188,12 +1188,6 @@ JSON如下
"size": [100, 100],
"offset": "@UIDemo.animation_in",
"texture": "textures/netease/common/image/default",
"is_new_nine_slice": false,
"nine_slice_buttom" : 0,
"nine_slice_left" : 0,
"nine_slice_right" : 0,
"nine_slice_top" : 0,
"nineslice_size" : [0, 0, 0, 0],
"type": "image"
},
"animation_in": {
@@ -1246,104 +1240,6 @@ button是按钮控件按钮有四种状态分别为default/hover/pressed/l
下面是一个使用了三种状态的按钮我们继承common.button里的属性无需自己再定义default_control等属性。
```json
{
"button0@common.button" : {
"$default_texture" : "textures/netease/common/button/default",
"$hover_texture" : "textures/netease/common/button/hover",
"$is_new_nine_slice" : false,
"$label_color" : [ 1, 1, 1 ],
"$label_font_scale_factor" : 1.0,
"$label_font_size" : "large",
"$label_layer" : 3,
"$label_offset" : [ 0, 0 ],
"$label_text" : "Button",
"$nine_slice_buttom" : 0,
"$nine_slice_left" : 0,
"$nine_slice_right" : 0,
"$nine_slice_top" : 0,
"$nineslice_size" : [ 0, 0, 0, 0 ],
"$pressed_button_name" : "%fpsBattle.click",
"$pressed_texture" : "textures/netease/common/button/pressed",
"$texture_layer" : 2,
"anchor_from" : "center",
"anchor_to" : "center",
"is_handle_button_move_event" : true,
"button_mappings" : [],
"bindings" : [
{
"binding_collection_name" : "",
"binding_condition" : "always_when_visible",
"binding_type" : "collection_details"
}
],
"controls" : [
{
"default@fpsBattle.default" : {}
},
{
"hover@fpsBattle.hover" : {}
},
{
"pressed@fpsBattle.pressed" : {}
},
{
"button_label@fpsBattle.button_label" : {}
}
],
"default_control" : "default",
"hover_control" : "hover",
"layer" : 3,
"offset" : [ 0, 0 ],
"pressed_control" : "pressed",
"size" : [ 100, 50 ],
"type" : "button",
"visible" : true
},
"button_label" : {
"color" : "$label_color",
"font_scale_factor" : "$label_font_scale_factor",
"font_size" : "$label_font_size",
"font_type" : "smooth",
"layer" : "$label_layer",
"max_size" : [ "100%", "100%" ],
"offset" : [ 0, 0 ],
"shadow" : false,
"text" : "$label_text",
"text_alignment" : "center",
"type" : "label"
},
"default" : {
"is_new_nine_slice" : "$is_new_nine_slice",
"layer" : "$texture_layer",
"nine_slice_buttom" : "$nine_slice_buttom",
"nine_slice_left" : "$nine_slice_left",
"nine_slice_right" : "$nine_slice_right",
"nine_slice_top" : "$nine_slice_top",
"texture" : "$default_texture",
"type" : "image"
},
"hover" : {
"is_new_nine_slice" : "$is_new_nine_slice",
"layer" : "$texture_layer",
"nine_slice_buttom" : "$nine_slice_buttom",
"nine_slice_left" : "$nine_slice_left",
"nine_slice_right" : "$nine_slice_right",
"nine_slice_top" : "$nine_slice_top",
"texture" : "$hover_texture",
"type" : "image"
},
"pressed" : {
"is_new_nine_slice" : "$is_new_nine_slice",
"layer" : "$texture_layer",
"nine_slice_buttom" : "$nine_slice_buttom",
"nine_slice_left" : "$nine_slice_left",
"nine_slice_right" : "$nine_slice_right",
"nine_slice_top" : "$nine_slice_top",
"texture" : "$pressed_texture",
"type" : "image"
}
}
```
"button0@common.button": {
"size": [100, 50],
"button_mappings": [], //和$pressed_button_name只能二选一
@@ -2372,7 +2268,7 @@ hover事件的触发本质上是与鼠标悬浮相关在PC模式中当鼠
UI编辑器暂时不支持编辑
### MiniMap
### mini\_map
该控件可以在UI上画小地图需要继承mini_map命名空间下的mini_map_wrapper控件。
@@ -2423,290 +2319,19 @@ UI编辑器暂时不支持编辑
| $face_icon_size | 脸部icon的大小默认为[4,4] |
| $face_icon_bg_color | 标记icon底部背景颜色默认为白色 |
| $highest_y | 绘制的高度最大值,默认当前区块的最大值,当该值为-1时表示最大高度值为玩家当前位置所在的高度 |
| enable_scissor_test | 超出父控件区域后是否裁剪默认为false, [enable_scissor_test](https://wiki.bedrock.dev/json-ui/json-ui-documentation.html)|
### **颜色渐变控件gradientRenderer**
该控件可以用于在ui上绘制渐变颜色
```json
{
"gradient": {
"color1": [1, 0, 1, 1],
"color2": [0, 0, 1, 1],
"gradient_direction": "vertical",
"renderer": "gradient_renderer",
"type": "custom"
}
}
```
| 变量 | 解释 |
| ------------------ | -------------------------------------- |
| color1 | 渐变起始颜色的RGBA |
| color2 | 渐变结束颜色的RGBA |
| gradient_direction | 渐变方向,可选"vertical"或"horizontal" |
| renderer | 需要指定为gradient_renderer |
| type | 需要指定为custom |
<img src="./picture/IntroduceUI/IntroduceUI-50.png" alt="图片描述" style="display: block; margin-left: 0;" />
下图为UI编辑器中颜色渐变控件的属性编辑面板
<img src="./picture/IntroduceUI/IntroduceUI-51.png" alt="图片描述" style="display: block; margin-left: 0;" />
| 变量 | 解释 |
| ------------ | ------------------------------------------------------ |
| 渐变起始颜色 | 对应color1字段支持调整不透明度Alpha通道 |
| 渐变结束颜色 | 对应color2字段支持调整不透明度Alpha通道 |
| 渐变方向 | 对应gradient_direction字段可选“垂直排布”或“水平排布” |
### 继承控件
继承控件允许开发者选择并继承目标控件,继承成功后该控件拥有目标控件的所有属性,并可以重写其中任何一个属性的数据。
#### 继承写法简述
在界面json文件所有的编写技巧中最为好用和灵活的功能当属继承写法。当界面中有一个需求需要将若干个相同的控件按序排列除了可以通过复制粘贴出若干个控件副本外继承模板控件并只修改我们所需要修改的属性其他的属性依然沿用模板控件的数据才是最便捷也是最漂亮的写法。下面我们从一个简单的例子入手熟悉继承的写法从例子中我们可以快速熟悉继承技巧。
```json
{
"main" : {
"absorbs_input" : true,
"always_accepts_input" : false,
"controls" : [
{
"label0@myInherit.label0" : {}
},
{
"inheritor0@myInherit.label0" : {
"offset" : [ 10.0, 0.0 ]
}
},
{
"inheritor1@myInherit.label0" : {
"offset" : [ 20.0, 0.0 ]
}
}
],
"force_render_below" : false,
"is_showing_menu" : true,
"render_game_behind" : true,
"render_only_when_topmost" : true,
"should_steal_mouse" : false,
"type" : "screen"
},
"label0" : {
"anchor_from" : "center",
"anchor_to" : "center",
"color" : [ 1, 1, 1 ],
"font_scale_factor" : 1.0,
"font_size" : "normal",
"font_type" : "smooth",
"layer" : 0,
"offset" : [ 0, 0 ],
"shadow" : false,
"size" : [ 100, 100 ],
"text" : "Hello World!",
"text_alignment" : "center",
"type" : "label",
"visible" : true
},
"namespace" : "myInherit"
}
```
该段json描述了在main画布中创建了一个文本控件label0并使继承控件inherit0和inherit1均继承了label0控件并重写了offset属性在场景中就得到了三个文本控件这三个文本控件除了在场景中的位置因为重写而不同外其他的属性一模一样。但是要注意的是可以被继承的控件必须写在json文件的最外层和main处在同一层级即一个命名空间下有且仅有一个该名称的控件满足该条件的控件才可以被继承。
#### UI编辑器中的继承
新版的UI编辑器对继承提供了更可视化的方法请参考[继承和自定义控件](./13-继承和自定义控件.md)。
## Python编写说明
### 必要的属性
```python
import mod.client.extraClientApi as clientApi
ViewBinder = clientApi.GetViewBinderCls()
ViewRequest = clientApi.GetViewViewRequestCls()
ScreenNode = clientApi.GetScreenNodeCls()
```
| 变量 | 解释 |
| :------------: | :----------------------------------- |
| extraClientApi | 我们开发的Client端Api接口文件 |
| ViewBinder | 用于绑定回调函数的类型和响应的方法 |
| ViewRequest | 用于返回绑定函数的返回值 |
| ScreenNode | UI的基类用于继承基类的方法和UI管理 |
### UI界面初始化
```python
import mod.client.extraClientApi as clientApi
ScreenNode = clientApi.GetScreenNodeCls()
class TestScreen(ScreenNode):
def __init__(self, namespace, name, param):
ScreenNode.__init__(self, namespace, name, param)
```
ScreenNode是我们的UI节点基类必须继承。
```python
# Bind Type
class ViewBinder(object):
ButtonFilter = 0x10000000
BF_ButtonClickUp = 0 | ButtonFilter
BF_ButtonClickDown = 1 | ButtonFilter
BF_ButtonClick = 2 | ButtonFilter
BF_ButtonClickCancel = 3
BF_InteractButtonClick = 4
BindFilter = 0x01000000
BF_BindBool = 5 | BindFilter
BF_BindInt = 6 | BindFilter
BF_BindFloat = 7 | BindFilter
BF_BindString = 8 | BindFilter
BF_BindGridSize = 9 | BindFilter
BF_BindColor = 10 | BindFilter
EditFilter = 0x00100000
BF_EditChanged = 11 | EditFilter
BF_EditFinished = 12 | EditFilter
ToggleFilter = 0x00010000
BF_ToggleChanged = 13 | ToggleFilter
# Return Type
class ViewRequest(object):
Nothing = 0
Refresh = 1 << 0
PointerHeldEventsRequest = 1 << 1
PointerHeldEventsCancel = 1 << 2
Exit = 1 << 3
```
### UI绑定和返回
UI的绑定分为binding单个绑定和binding_collection集合绑定适合集合容器。
| 绑定类型 | 绑定方式 | 解释 |
| :--------------------- | :---------------------------: | :------------------------------------- |
| BF_ButtonClickUp | binding | 绑定按钮的Up事件 |
| BF_ButtonClickDown | binding | 绑定按钮的Down事件 |
| BF_ButtonClick | binding | 同时绑定Up和Down事件 |
| BF_ButtonClickCancel | binding | 绑定按钮的Cancel事件按钮down其他up |
| BF_InteractButtonClick | binding | 绑定游戏原生的按钮点击事件 |
| BF_BindBool | binding \| binding_collection | 绑定Bool变量 |
| BF_BindInt | binding \| binding_collection | 绑定Int变量 |
| BF_BindFloat | binding \| binding_collection | 绑定Float变量 |
| BF_BindString | binding \| binding_collection | 绑定String变量 |
| BF_BindGridSize | binding | 绑定GridSize变量 |
| BF_BindColor | binding \| binding_collection | 绑定颜色变量 |
| BF_EditChanged | binding | 绑定输入框输入改变事件 |
| BF_EditFinished | binding | 绑定输入框输入完成事件 |
| BF_ToggleChanged | binding | 开关状态改变事件 |
**binding(bind_flag, binding_name = None)**
bind_flag为上文中绑定类型binding_name为绑定名称。
binding_name为脚本绑定变量binding_name_override为引擎变量json格式如下
```json
{
"bindings": [
{
"binding_condition" : "always",
"binding_name" : "#scoreboard_grid.item_count",
"binding_name_override" : "#StackGridItemsCount"
}
]
}
```
对应的Python代码如下
```python
import mod.client.extraClientApi as clientApi
ViewBinder = clientApi.GetViewBinderCls()
@ViewBinder.binding(ViewBinder.BF_BindInt, "#scoreboard_grid.item_count")
def OnStarkGridResize(self):
return len(self.scoreBoardList)
```
**binding_collection(bind_flag, collection_name, binding_name = None)**
bind_flag为上文中的绑定类型collection_name为集合名称binding_name为绑定的变量名称。
集合的json如下
```json
{
"collection_name" : "scoreboard_stackgrid"
}
```
在集合的子控件中binding_collection_name为集合名binding_condition为绑定条件binding_name为绑定名称binding_type为collection绑定property_bag设置他的初始值text为它的绑定值。
```json
{
"label_score_board" : {
"bindings" : [
{
"binding_collection_name" : "scoreboard_stackgrid",
"binding_condition" : "always",
"binding_name" : "#label_score_board.text",
"binding_type" : "collection"
}
],
"offset" : [ "0%+0 px", "0%+0px" ],
"property_bag" : {
"#label_score_board.text" : "666666666666"
},
"text" : "#label_score_board.text",
"text_alignment" : "left",
"type" : "label",
"visible" : true
}
}
```
对应的Python代码如下其中index表示在集合中的哪一元素。
```python
import mod.client.extraClientApi as clientApi
ViewBinder = clientApi.GetViewBinderCls()
@ViewBinder.binding_collection(ViewBinder.BF_BindString, "scoreboard_stackgrid", "#label_score_board.text")
def OnRefreshScoreBoardLabel(self, index):
return self.scoreBoardList[index] if len(self.scoreBoardList) > index else ""
```
## 接口调用说明
### 参数命名说明
@Mod.Binding(name = myModName, version = myModVersion)
| 参数 | 类型 | 解释 |
| :----------: | :--: | :------ |
| myModName | str | Mod名称 |
| myModVersion | str | Mod版本 |
假设设置Mod名称为"myModName",示例:
```python
from mod.common.mod import Mod
@Mod.Binding(name = "myModName", version = "0.1")
class MyModClass(object):
def __init__(self):
pass
```
### 界面创建流程及生命周期
### 界面创建流程
界面在<a href="../../mcdocs/1-ModAPI/事件/UI.html#uiinitfinished" rel="noopenner"> UiInitFinished </a>事件发送之后就可以开始创建
创建UI的第一步是UI的注册通过调用<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#registerui" rel="noopenner"> RegisterUI </a>接口,将想开启UI的相关数据进行注册。同一UI只需要注册一次即可
创建UI的第一步是UI的注册通过调用<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#registerui" rel="noopenner"> RegisterUI </a>接口,传入UI类路径和JSON控件路径注册UI同一UI只需要注册一次即可
注册完成之后就可以在需要的时候实例化UI可使用的接口有<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#createui" rel="noopenner"> CreateUI </a><a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#pushscreen" rel="noopenner"> PushScreen </a>两种。使用<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#createui" rel="noopenner"> CreateUI </a>生成的界面都生成在操作UI下不同的生成参数UI层级不同而使用<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#pushscreen" rel="noopenner"> PushScreen </a>生成的界面以堆栈管理的方式生成,该界面生成时上一个<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#pushscreen" rel="noopenner"> PushScreen </a>生成的界面就会被隐藏。值得注意的是MC原生界面比如暂停界面背包界面等也是类似<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#pushscreen" rel="noopenner"> PushScreen </a>的方式加载进来,并以堆栈管理。
在UI创建完成之后可以调用<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#getui" rel="noopenner"> GetUI </a>接口拿到UI对应的ScreenNode实例。
如果想获取MC原生界面的实例则需要监听原生界面Push进来的事件<a href="../../mcdocs/1-ModAPI/事件/UI.html#pushscreenevent" rel="noopenner"> PushScreenEvent </a>,然后在事件回调中调用接口<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#gettoppushedui" rel="noopenner"> GetTopPushedUI </a>
每个ScreenNode都有生命周期函数生命周期函数会被自动在以下情况下调用重写函数可以完成一些逻辑。
@@ -2716,9 +2341,38 @@ class MyModClass(object):
| <a href="../../mcdocs/1-ModAPI/接口/自定义UI/UI界面.html#create" rel="noopenner"> Create </a> | UI创建成功时调用 |
| <a href="../../mcdocs/1-ModAPI/接口/自定义UI/UI界面.html#onactive" rel="noopenner"> OnActive </a> | UI重新回到栈顶时调用 |
| <a href="../../mcdocs/1-ModAPI/接口/自定义UI/UI界面.html#ondeactive" rel="noopenner"> OnDeactive </a> | 栈顶UI有其他UI入栈时调用 |
| <a href="../../mcdocs/1-ModAPI/接口/自定义UI/UI界面.html#update" rel="noopenner"> Update </a> | 客户端每帧调用1秒有30帧 |
| <a href="../../mcdocs/1-ModAPI/接口/自定义UI/UI界面.html#destroy" rel="noopenner"> Destroy </a> | UI销毁时调用 |
最后当UI需要销毁时可以调用ScreenNode实例的<a href="../../mcdocs/1-ModAPI/接口/自定义UI/UI界面.html#setremove" rel="noopenner"> SetRemove </a>接口,此外使用<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#pushscreen" rel="noopenner"> PushScreen </a>接口创建的界面还可以使用<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#popscreen" rel="noopenner"> PopScreen </a>接口进行销毁。
### 编写UI类
UI类用于编写界面逻辑需要在<a href="../../mcdocs/1-ModAPI/接口/自定义UI/通用.html#registerui" rel="noopenner"> RegisterUI </a>时传入UI类的路径。一个客户端类可以对应多个UI类。UI类一般包含以下内容
```python
import client.extraClientApi as clientApi
ScreenNode = clientApi.GetScreenNodeCls()
ViewBinder = clientApi.GetViewBinderCls()
ViewRequest = clientApi.GetViewViewRequestCls()
Client = clientApi.GetSystem('xxxxMod', 'xxxxClientSystem')
CF = clientApi.GetEngineCompFactory()
PID = clientApi.GetLocalPlayerId()
class uiName(ScreenNode):
def __init__(self, namespace, name, param):
ScreenNode.__init__(self, namespace, name, param)
def Create(self):
pass
def Destroy(self):
pass
def Update(self):
pass
```
| 变量 | 解释 |
| :------------: | :----------------------------------- |
| extraClientApi | 我们开发的Client端Api接口文件 |
@@ -2858,11 +2512,9 @@ button_data: {
在字符串中嵌入`<link>link_data</link>`样式会被解析成超链接外观和普通文本无异但可以被点击link_data为特殊化数据开发者可以在其中添加符合JSON格式的自定义数据在点击富文本中对应超链接时会将link_data通过回调函数整个返回以下属性为必须属性text表示显示文本format_code表示该段显示文本的样式代码注意基岩版的文本控件不支持下划线和删除线。
```json
{
"link_data":{
"text":"末影人",
"format_code":"§2"
}
link_data: {
"text": "末影人",
"format_code": "§2"
}
```