实体关系与层级
第 8 章结尾留了一句话:长戟在小芙手里,小芙坐在车上。游戏世界里到处是这种“谁属于谁”——乘员属于载具,装备属于角色,角色属于队伍。这一章解决一个问题:实体之间的从属关系,该怎么记?
用现有的工具,你大概会这么做:给车定义一个 Passengers(Vec<Entity>) 组件,上车就往里 push。它能跑起来,但有三个越用越疼的破绽:
- 一本账不够。从车找人靠
Passengers,从人找车还得再发明一个RidingOn(Entity)——同一个事实记两本账,每次上下车都要改两处,漏掉一处,两本账就开始各说各话。 - 账上的号码会作废。乘客被
despawn后,车上的名单还留着他的Entity。第 3 章说过,实体编号带代际、会重用——拿着死人的号码去查询,轻则查空,重则查到一个毫不相干的新实体。 - 销毁要手工递归。马车坠崖,车上的人、人身上的行李都该一起消失——你得自己写递归,挨个
despawn,少一层就留一地孤儿实体。
Bevy 把这三件事打包成一套机制:Relationship(关系)——用一对组件表达“谁连着谁”,由引擎保证两本账永远一致。你在第 8 章刚学过它的地基:维护这套一致性的,正是组件钩子。
本章先学这套机制最重要的实例——ChildOf/Children 父子树:怎么建树、怎么拆、怎么沿树上下遍历、销毁一个实体时整棵子树如何级联消失。然后掀开引擎的手心:父子树没有任何特权,它只是 Relationship 机制的内置用例——你可以用同一套 derive 宏,把“装备在谁身上”“瞄准谁”这样的业务关系定义成自己的关系组件。
本章的舞台是一支商队:车队载着乘员翻山越岭,乘员身上带着装备。出发。