制作第一个刚体
本章从一个半边长 0.25 格的立方刚体开始。目标不是复制骰子,而是掌握业务模块最小闭环:生成骨架、定义 plate、创建实例、每 tick 推进、同步显示、销毁。
1. 选择模板
这个物体需要旋转、会撞地,但暂时不要求其他动态物体撞到它,因此选择 vve_block_1.0:
- 八个顶点作为碰撞点;
- 标量质量与惯量;
- 不承担实体介质职责;
- 比张量模型和
cublock更容易验证。
假设项目命名空间为 demo,模块函数前缀为 demo:crate/。
2. 用 MOT 生成骨架
在 MOT 记忆栈依次执行:
push vve_block_1.0
run
init
sync
stop
pop生成后先不要大范围改文件。确认至少存在:
data/demo/function/crate/
├─ init.mcfunction
├─ _class.mcfunction
├─ _consts.mcfunction
├─ _new.mcfunction
├─ _del.mcfunction
├─ _get.mcfunction
├─ _store.mcfunction
├─ _proj.mcfunction
├─ _model.mcfunction
├─ _update_display.mcfunction
├─ main_c.mcfunction
└─ tick.mcfunction这些文件里许多是机械生成的字段搬运代码。业务修改优先集中在 _class、_consts、set_operation、显示和调度入口,避免手工改 _get/_store/_proj/_model 后字段不对称。
3. 定义默认数据
_class 的职责是生成未来实例使用的 plate:
# demo:crate/_class
function demo:crate/_zero
execute positioned 0 0 0 rotated 0 0 as 0-0-0-0-0 run function vve:object/_anchor_to
# 半边长 0.25 格
scoreboard players set a int 2500
# 质量 17(业务单位)
scoreboard players set mass int 17
# 标量惯量 5.00
scoreboard players set inertia int 500
function demo:crate/_model
data modify storage demo:class crate_plate set from storage demo:io result尺寸翻倍时,若质量不变,惯量应按尺寸平方放大;质量再翻三倍,惯量还应再乘三。不要只把 display scale 改成 2 而保留 a=2500。
4. 设置视觉实体
模板的 _new 会创建根/展示实体,并调用 set_operation。在业务设置里指定物品模型:
# demo:crate/set_operation
function demo:crate/_get
function demo:crate/_update_display
item replace entity @s container.0 with minecraft:barrel若使用自定义 item_model,资源包必须提供对应 definition/model/texture。物理不依赖这个模型;资源缺失只影响外观。
5. 创建实例
封装一个 demo:crate/spawn:
# 载入默认模板
data modify storage demo:io input set from storage demo:class crate_plate
function demo:crate/_proj
# 当前执行位置/朝向成为初始姿态
execute as @e[tag=math_marker,limit=1] run function vve:object/_anchor_to
# 可选:设置向前的初速度或调用 _poke_here/_apply_impulse
function demo:crate/_model
data modify storage demo:io input set from storage demo:io result
function demo:crate/_new调用:
execute positioned 0 105 0 rotated 20 -15 run function demo:crate/spawn_new 约定把根实体放进 @e[tag=result,limit=1]。如果随后要设置销毁回调或业务 tag,立即使用这个结果,别等其他函数覆盖 result。
6. 调度物理
最简单的 tick:
# demo:crate/tick
execute as @e[tag=demo_crate] run function demo:crate/main_c再把它放入你自己的模拟器 tick_funcs,或由项目的 #minecraft:tick 入口调用。只能选一条活动路径;不要既在函数标签里调用 crate/tick,又把同一实例加入另一个模拟器。
7. 加入测试模板
骨架能运行后,再叠加 vve_test_1.0:
push vve_test_1.0
run
init
sync
stop
pop至少验证:自由落体、方块反弹、摩擦停止、倾斜接触与坐标安全。vve_block_1.0 不支持物体间实体碰撞,所以 inter-bounce 中相互穿过是模型边界,不是测试框架坏了。
8. 完成定义
“能看到方块落下”还不够。一个可交付模块应该明确:
- plate 的每个业务字段与缩放;
- 创建函数需要的执行位置/执行者;
- 实例 tag、结果选择器和生命周期;
- 使用哪个介质入口与碰撞点方案;
- 谁负责调度、每 tick 几次;
- 显示资源缺失时如何回退;
- 速度/坐标安全边界与销毁规则;
- 至少一份自动化回归。