Schema_zh - Gamepiaynmo/CustomModel GitHub Wiki
概况
自定义玩家模型(CPM)允许您使用JSON来自定义骨骼,方块,平面,飘带和粒子,结合强大的表达式功能来自定义模型外观。这里可以找到一些例子以供参考:这里。
主JSON文件
每个模型包必须包含一个名为“ model.json”的json文件。 一个典型的json结构如下所示:
{
"modelId": ...,
"modelName": ...,
"version": ..., // 可选
"author": ..., // 可选
"fpLeft": [ ... ], // 可选
"fpRight": [ ... ], // 可选
"skeleton": { ... }, // 可选,可使用动画
"eyeHeight": { ... }, // 可选
"boundingBox": { ... }, // 可选
"variables": { ... }, // 可选,可使用动画
"hide": [ ... ], // 可选
"bones": [ ... ]
}
基本信息
- modelId:每个模型应具有唯一ID,否则将被视为不同版本的同一模型,因此在提供ID时请避免冲突。模型ID只能包含小写字母,数字和下划线(_)。
- modelName:模型名称是玩家使用命令/custommodel list时在游戏中看到的模型名称。模型名称可以有冲突,并且可以包含任何字符。
- version:当加载具有相同模型ID的不同模型时,系统会选择版本最大的模型(按字典顺序比较字符串)。
- author:写上您的名字,加入名人堂。
原有骨骼
玩家模型是用骨骼构成的,方块均附加在骨骼上,骨骼定义了模型如何运动。 原有骨骼是构建原版玩家模型的骨骼,包含以下骨骼:
- head
- body
- left_arm
- right_arm
- left_leg
- right_leg
以及它们的第二层:
- head_overlay
- body_overlay
- left_arm_overlay
- right_arm_overlay
- left_leg_overlay
- right_leg_overlay
这些骨骼的运动由游戏代码控制,此mod不会干涉以保持兼容性。您可以做的是调整其位置以更改模型的身高,或隐藏它们并制作全新的替代骨骼。
第一人称渲染
此mod允许您选择要在第一人称视角中渲染的骨骼。 您可以将这些骨骼添加到“fpLeft”或“fpRight”列表中,这取决于您的主手。请仅添加原有手臂骨骼的子骨骼(“left_arm”或“right_arm”及其第二层),并不要在其上添加“physics”,除非您清楚地知道自己要做什么。
骨架
骨架定义了原有骨骼的位置,可以用来改变模型的身材,例如使自己像末影人一样高,而无需进行复杂的修改。您可以参考末影人模型作为示例。
碰撞箱和眼睛高度
更改模型身材后,大多数情况下,您也希望对碰撞箱做相应更改以适合您的新身材。现在,您可以为不同的玩家姿势定义它们:
- standing
- fall_flying
- sleeping
- swimming
- spin_attack
- sneaking
- dying
在大多数情况下,定义三个姿势(standing,sneaking和dying)的碰撞箱和眼睛高度就足够了。 因此,以下是json的大致情况:
{
"eyeHeight": {
"standing": 1.215,
"dying": 1.215,
"sneaking": 0.9525
},
"boundingBox": {
"standing": [0.45, 1.35],
"dying": [0.45, 1.35],
"sneaking": [0.45, 1.125]
}
}
隐藏部分模型
您可以隐藏不希望看到的原有骨骼或特征,例如当您想要更改其位置/外观等时。游戏不会显示添加到此列表的骨骼或特征,但仍将计算其变换矩阵,因此它们仍然可以成为父骨骼。 数组的每个元素必须是原有玩家骨骼之一或原有特征之一:
- helmet_head
- helmet_head_overlay
- chestplate_body
- chestplate_left_arm
- chestplate_right_arm
- leggings_body
- leggings_left_leg
- leggings_right_leg
- boots_left_leg
- boots_right_leg
- held_item_left
- held_item_right
- cape
- head_wearing (头颅,南瓜等)
- elytra
- shoulder_parrot_left
- shoulder_parrot_right
还可以是它们的组合:
-
head_all: head, head_overlay
-
body_all: body, body_overlay
-
left_arm_all: left_arm, left_arm_overlay
-
right_arm_all: right_arm, right_arm_overlay
-
arms_all: left_arm_all, right_arm_all
-
left_leg_all: left_leg, left_leg_overlay
-
right_leg_all: right_leg, right_leg_overlay
-
legs_all: left_leg_all, right_leg_all
-
model_all: head_all, body_all, arms_all, legs_all
-
helmet_all: helmet_head, helmet_head_overlay
-
chestplate_all: chestplate_body, chestplate_left_arm, chestplate_right_arm
-
leggings_all: leggings_body, leggings_left_leg, leggings_right_leg
-
boots_all: boots_left_leg, boots_right_leg
-
armor_body_all: chestplate_body, leggings_body
-
armor_arms_all: chestplate_left_arm, chestplate_right_arm
-
armor_left_leg_all: leggings_left_leg, boots_left_leg
-
armor_right_leg_all: leggings_right_leg, boots_right_leg
-
armor_legs_all: armor_left_leg_all, armor_right_leg_all
-
armor_all: helmet_all, armor_body_all, armor_arms_all, armor_legs_all
-
held_item_all: held_item_left, held_item_right
-
shoulder_parrot_all: shoulder_parrot_left, shoulder_parrot_right
-
feature_all: armor_all, held_item_all, shoulder_parrot_all, cape, head_wearing, elytra
隐藏它们之后,您可以将这些特征(不能是骨骼)附加到自定义骨骼上以更改其原始位置。 骨骼的缩放/可见性也将应用于附加的特征。
坐标系
与原始模型坐标系不同,CPM使用的坐标系与Minecraft的世界坐标系相同,玩家模型面朝北方,即-Z方向。
Direction | XYZ |
---|---|
East | +X |
West | -X |
North | -Z |
South | +Z |
Up | +Y |
Down | -Y |
骨骼
骨骼是构成模型的基础,它们构成了玩家模型的整体框架,并定义了每个部分的运动规律。 一个典型的骨骼json如下所示:
{
"id": ...,
"parent": ..., // 可选
"texture": ..., // 可选,可使用动画
"textureSize": [ ..., ... ], // 可选
"position": [ ..., ..., ... ], // 可选,可使用动画
"rotation": [ ..., ..., ... ], // 可选,可使用动画
"scale": [ ..., ..., ... ], // 可选,可使用动画
"visible": ..., // 可选,可使用动画
"emissive": ..., // 可选,可使用动画
"color": [ ..., ..., ... ], // 可选,可使用动画
"alpha": ..., // 可选,可使用动画
"physics": [ ... ], // 可选
"attached": [ ... ], // 可选
"boxes": [ ... ], // 可选
"quads": [ ... ], // 可选
"particles": [ ... ], // 可选
"items": [ ... ] // 可选
}
- id: 每个骨骼必须具有唯一的ID,并且不能与原有的骨骼或特征(body, head, etc)相同。
- parent: 父骨骼必须是原有的骨骼之一,或者是之前定义的自定义骨骼。 父骨骼和子骨骼必须按顺序出现。 子骨骼将遵循父骨骼的变换(纹理,位置,旋转,缩放和可见性),就好像它是父骨骼的一部分一样。 如果为空,则将默认选择身体骨骼作为父骨骼。
- texture: 带有前缀“tex.”的贴图文件名,不包含路径或后缀(例如“tex.hair”对应的贴图文件名为“ hair.png”)。 贴图文件与“model.json”存储在同一文件夹中。 如果为空,则使用与其父骨骼相同的纹理。若父骨骼为原有的骨骼之一,则使用玩家的皮肤贴图。有三个默认存在的贴图:“tex.skin”代表玩家皮肤,“tex.cape”代表玩家披风(如果有的话),“tex.elytra”代表鞘翅贴图(如果有的话)。 对于没有披风的玩家,可以使用“tex.cape>0”来测试当前玩家是否拥有披风。
- textureSize: 当指定贴图时必须指定贴图大小。 在大多数情况下,它与贴图的分辨率相同。 贴图大小不能使用动画,因此在为贴图设置动画时,请确保所有使用的纹理具有相同的分辨率。
- position: 定义子骨骼的相对位置。 请注意,这不会更改当前骨骼的位置,而仅仅影响子骨骼和附加的方块、特征、粒子等等的位置。默认值[0,0,0]。
- rotation: 定义当前骨骼的欧拉旋转角度。 默认值[0,0,0]。
- scale: 定义当前骨骼的缩放比例。 默认值[1,1,1]。
- visible: 指定是否渲染可见元素(附加的方块,特征等)。 如果未指定,它将具有与其父骨骼相同的可见性。
- emissive: 是否自发光,例如蜘蛛或末影人的眼睛。
- color & alpha: 改变模型的默认颜色(255,255,255,255)。
- physics, boxes, quads, particles & items: 请见下面的章节。
- attached: 当需要更改原有特征(盔甲,持有的物品等)的位置,就可以隐藏它们并将其附加到新骨骼上。 将相同的特征附加到多个骨骼将使特征渲染多次。
方块和平面
Minecraft中的大多数实体模型都是由方块构成的。 一个典型的方块json如下所示:
{
"textureOffset": [ ..., ... ], // 可选
"coordinates": [ ... ], // 可选
"sizeAdd": ..., // 可选
"mirror": ... // 可选
}
- textureOffset: 方块UV坐标的左上角。 每个方块包含六个面,其UV按照与玩家皮肤相同的方式排列。 默认值[0,0]。
- coordinates: 定义方块的偏移位置和大小。 前三个参数是偏移量,后三个参数是大小。 默认值[0,0,0,0,0,0]。 方块坐标与实际世界坐标之间的比例为16:1。
- sizeAdd: 像玩家模型的二层皮肤一样拓展方块。 默认值0。
- mirror: 有一些模型使用了相同的贴图但是方向相反,例如左右手的贴图。此选项可以让贴图左右翻转。
平面json与方块几乎相同,除了它们是二维的,因此“coordinates”仅包含5个参数。
粒子
粒子系统已经广泛应用于现代的3D游戏中。 CPM为粒子发射器提供了各种参数,供您自定义特殊效果。
{
"posRange": [ ..., ..., ... ], // 可选,可使用动画
"dirRange": ..., // 可选,可使用动画
"angle": [ ..., ... ], // 可选,可使用动画
"speed": [ ..., ... ], // 可选,可使用动画
"rotSpeed": [ ..., ... ], // 可选,可使用动画
"lifeSpan": [ ..., ... ], // 可选,可使用动画
"density": ..., // 可选,可使用动画
"animation": [ ..., ... ], // 可选
"colorR": [ ..., ... ], // 可选,可使用动画
"colorG": [ ..., ... ], // 可选,可使用动画
"colorB": [ ..., ... ], // 可选,可使用动画
"colorA": [ ..., ... ], // 可选,可使用动画
"size": [ ..., ... ], // 可选,可使用动画
"gravity": ..., // 可选,可使用动画
"collide": ... // 可选,可使用动画
}
- posRange: 发射粒子相对于当前骨骼位置的最大初始偏移量。 默认值[0,0,0]。
- dirRange: 粒子生成时的最大方向偏移角(以度为单位)。 如果为0,则新粒子将沿当前骨骼的Z轴移动,如果不为0,则将在圆锥中随机选取一个方向。默认值为0。
- angle: 初始粒子旋转角度的最小值和最大值(以度为单位)。 默认值[0,0]。
- speed: 粒子移动速度的最小和最大值,以米/秒为单位。 默认值[0,0]。
- rotSpeed: 粒子旋转速度的最小值和最大值,以度/秒为单位。 默认值[0,0]。
- lifeSpan: 每个粒子存在多少个游戏刻,最小值和最大值。 默认值[1,1]。
- density: 每个游戏刻中产生多少新粒子。 默认值1。
- animation: 可以将粒子的贴图拆分为子图像以制作动画。 此参数指定每列/每行有多少个子图像。 默认值[1,1]。
- color(R|G|B|A): 粒子颜色的最小值和最大值。 默认值[1,1]。
- size: 粒子尺寸的最小值和最大值。 默认值[1,1]。
- gravity: 如果不为0,将对所有粒子施加方向为-Y的重力。 可以为负。默认值0。
- collide: 粒子是否会与方块/实体碰撞。 默认为false。
物品模型
您可以将物品模型作为玩家模型的一部分。
{
"itemId": "item. ... ", // 可使用动画
"enchanted": ... // 可选,可使用动画
}
- itemId:您要附加的物品ID。使用物品常量,例如item.apple,item.diamond_sword等。
- 附魔:物品模型是否附魔。
物理系统
骨骼json中的“physics”条目指定当前骨骼运动符合的物理规律。 物理骨骼不会像刚体那样严格保持与其父骨骼的相对变换,而是会像弹簧一样遵循物理规则,可用于模拟头发,围巾等的移动。此条目包含5个参数:
- elasticity: [0, +inf), 弹性:父骨骼移动时所施加的力的强度,指向运动方向。
- stiffness: [0, +inf), 刚度:不断施加于骨骼,以保持与父骨骼的相对变换的力的强度。
- damping1: [0, 1), 阻尼1:在每个游戏周期内乘以当前骨骼的速度,以模拟空气阻力。
- damping2: [0, +inf), 阻尼2:在玩家实体移动速度的相反方向上施加的力的强度。
- gravity: [0, +inf), 重力的强度。
动画
CPM使玩家能够使用表达式创建自己的动画。 例如,以下骨骼:
{
"id": "bounce".
"position": [ 0, "sin(age)", 0 ],
"boxes": [ ... ]
}
它将在Y方向上反复横跳。
有两种表达式类型:浮点型和布尔型。 它们可以与各种变量和功能结合使用,以实现复杂的运动。 动画表达式可以被应用于以上章节中标记有“可使用动画”的所有参数。
您还可以在json根节点中添加自定义变量:
{
"variables": {
"bounce": "sin(age)",
"should_bounce": "is_sneaking"
}
}
然后,您可以在之后的表达式中使用“var.bounce”和“var.should_bounce”来访问它们。请注意,这些变量不能引用其自身。
还有另外一种变量——刻更新变量,它们在每个游戏刻进行更新,重要的是它们能够引用其自身!这就意味着这些变量实际是图灵完备的——使用它们能够完成任何可实现的算法。一个典型的刻更新变量如下所示:
{
"tickVars": {
"selfAdd": ["float", 0, "if(tvl.selfAdd<10,tvl.selfAdd+1,0)]
}
}
变量名为selfAdd,float为变量类型,目前只有浮点型和布尔型两种,0为变量的初始值。这个变量的值将在0到10之间循环。有三种方法可以引用这个变量的值:
- tvl.xxx: 获取变量在上一游戏刻的值。
- tvc.xxx: 获取变量在当前游戏刻的值。
- tvp.xxx: 获取一个在上面两者之间的值,使用游戏的partial变量进行插值。
这里有一个使用刻更新变量实现的俄罗斯方块游戏可供参考。
以下是可用于形成表达式的所有变量和函数:
name | type | arguments | description |
---|---|---|---|
limb_swing | 浮点变量 | 胳膊摆动的角度 | |
limb_speed | 浮点变量 | 胳膊摆动的距离 | |
age | 浮点变量 | 玩家实体存在的时间 | |
head_yaw | 浮点变量 | 头部和身体旋转欧拉角之差 | |
head_pitch | 浮点变量 | 头部旋转的欧拉角 | |
scale | 浮点变量 | 模型的比例 (一般是0.0625) | |
health | 浮点变量 | 玩家当前生命值 | |
food_level | 浮点变量 | 玩家当前饱食度 | |
hurt_time | 浮点变量 | 被攻击的剩余时间(渲染为红色) | |
pos_x | 浮点变量 | X坐标 | |
pos_y | 浮点变量 | Y坐标 | |
pos_z | 浮点变量 | Z坐标 | |
speed_x | 浮点变量 | X速度 | |
speed_y | 浮点变量 | Y速度 | |
speed_z | 浮点变量 | Z速度 | |
yaw | 浮点变量 | 头部旋转的欧拉角 | |
body_yaw | 浮点变量 | 身体旋转的欧拉角 | |
pitch | 浮点变量 | 头部旋转的欧拉角 | |
swing_progress | 浮点变量 | 胳膊摆动的进度 [0, 1] (攻击或放置方块时) | |
is_alive | 布尔变量 | 是否存活 | |
is_burning | 布尔变量 | 是否在燃烧 | |
is_glowing | 布尔变量 | 是否在发光 | |
is_hurt | 布尔变量 | 是否被攻击(渲染为红色) | |
is_in_lava | 布尔变量 | 是否在岩浆中 | |
is_in_water | 布尔变量 | 是否在水中 | |
is_invisible | 布尔变量 | 是否不可见 | |
is_on_ground | 布尔变量 | 是否在陆地上 | |
is_riding | 布尔变量 | 是否在骑乘中 | |
is_sneaking | 布尔变量 | 是否在潜行 | |
is_sprinting | 布尔变量 | 是否在奔跑 | |
is_wet | 布尔变量 | 是否变湿(下雨或者在水中) | |
is_first_person | 布尔变量 | 是否在渲染第一视角 | |
pi | 浮点常量 | 3.1415926 ... | |
time | 浮点变量 | 当前的昼夜循环时间 [0, 24000) | |
+, -, *, /, % | 浮点函数 | float x 2 | 基本运算 |
sin, asin, cos, acos, tan, atan | 浮点函数 | float | 三角函数 |
atan2 | 浮点函数 | float x 2 | 三角函数 |
torad, todeg | 浮点函数 | float | 角度/弧度转换 |
min, max | 浮点函数 | float x n | 最小值/最大值 |
clamp | 浮点函数 | float x 3 | max(f2, min(f1, f3)) |
abs, floor, ceil, exp, frac, log, pow, round, signum, sqrt | 浮点函数 | float | 初等函数 |
fmod | 浮点函数 | float x 2 | 浮点数取余 |
random | 浮点函数 | - | 返回 [0, 1) 的随机数 |
!, &&, || | 布尔函数 | boolean x 2 | 布尔运算 |
>, >=, <, <=, ==, != | 布尔函数 | float x 2 | 浮点数比较 |
equals | 布尔函数 | float x 3 | 带误差的浮点数比较 abs(f1 - f2) < f3 |
between | 布尔函数 | float x 3 | f1是否在f2和f3之间 |
in | 布尔函数 | float x n | f1是否为{f2, f3, ..., fn}中的一个 |
if | 浮点函数 | boolean, float, (boolean, float) x n, float | if (b1) f1 {else if (b2) f2} x n else fn |
(bone name).(t|r|s)(x|y|z) | 浮点变量 | 获取骨骼的相对位移、旋转、缩放变换。例如 head.rx, body.tz, 等 | |
tex.(texture name) | 浮点常量 | 获取指定名称的贴图 | |
inv.(mainhand|offhand| helmet|chestplate|leggings| boots|main(0 - 35)) | 浮点变量 | 获取玩家背包中的物品。例如 inv.main4 表示背包的第五格 | |
item.(item id) | 浮点常量 | 获取指定物品的id。例如 inv.mainhand==item.apple 可判断玩家是否持有苹果. | |
pose.(pose id) | 浮点常量 | 获取指定姿势的id。 | |
current_pose | 浮点变量 | 获取玩家当前的姿势。 | |
effect.(effect id) | 浮点变量 | 获取玩家身上的药水效果等级。(没有的话为-1) |