Closed rrbox closed 1 month ago
Entity hierarchy と SKNode や SCNNode[^1] の hierarchy とで連携する必要があります(というより、それが一番の目的です)。SpriteKit や SceneKit[^1] での使用を前提とするなら、Graphic 関連の plugin に導入してもいいかもしれません。
[^1]: SceneKit のサポートは v0.1.0 時点では未実装です。あと、今後サポートするかも未定です...
自分に親がいたら、親に Graphic があるかをチェックし、親がグラフィックを持っていたら addChild
です。
Graphic を持っていたら、自分の Graphic の子ノードとして addChild
します。
Graphic と紐づいていないときもこのチェックは必要になります。
Graphic と紐づけることを必須とする場合は、SKNode が自動的に検知して実行時エラーになるので、特に注意する必要はないです。
WillDespawnEvent
を使えば多分できます。
注意点として、先に SKNode が削除されてしまう場合、unown let の参照先が消えることで despawn 時の自動 remove from parent 実行機能がエラーになる可能性があることです。SKNode 削除前に entity との繋がりをなくす何らかの仕組みを実装したいところです。
let child = commands.spawn().id()
commands.spawn()
.addChild(child)
struct Child: Component {
var _parent: Entity
var parent: Entity {
self._parent
}
}
struct Parent: Component {
var _children: Set<Entity>
var children: Set<Entity> {
self._children
}
}
Graphic が entity に紐づいていない場合はクラッシュする、という実装も考えられます。これは、entity hierarchy の機能が graphic の座標系に関するものだからです。
上記の実装の場合、setGraphic
の際に Child
と Parent
をコンポーネントとして追加し、entity hierarchy の管理を始めるのが最もシンプルだと思います。
また、一度 entity に紐づけられた SKNode, SCNNode を取り外せないようにするべきかもしれません。こうすることで、entity hierarchy 内の graphic が勝手に ECS 管理外になるのを観測する手間が省けます。
Graphic は spawn 後の entity に割り当てられ、基本的に Scene resource で指定された Scene に配置されます。したがって、Add child command はすでに scene を親に持った SKNode を操作することになります。SKNode の removeFromParent を実行すればエラーなしで階層に追加できますが、「親を複数持つ entity の禁止」ができなくなります。
内部コンポーネントとして _AddChildTransaction
を提案します。
親 entity を nil 許容型で保持します var parentEntity: Entity?
。nil の場合、コマンド実行時に SceneResource のノードが親ノードになります。
以下のような System を作成します。
Query3<Entity, _AddChildTransaction, Graphic<SKNode>>
Query<Graphic>
Resource<SceneResource>
Commands
addChild
addChild
commands.entity(entity).removeComponent(_AddChildTransaction.self)
を実行Set graphic 内の addChild 処理はすべて削除し、_AddChildTransaction
を追加する処理を記述します。
_AddChildTransaction
に parentEntity = nil
を指定します。追記
上記のシステムの中で、コンポーネント Child
と Parent
を追加する処理を加えましょう。
以下の Component を追加します。
Child
Entity 間で親子関係が作られた際に、Child と Parent がそれぞれ子と親に追加されます。Child は親の Entity が含まれています。Parent はこの Entity の配列が含まれます。