bbi.experimental.spawn¶
- class SpawningStrategy¶
Bases:
ABC
- abstract asset_factory() Asset ¶
Factory method to create assets.
Perform all attachments here but only return a single parent asset.
- pydantic model SpawnZoneV2UpdateParam¶
Bases:
AnimationFrame
- field force_respawn: bool | None = None¶
- field quantity: int | None = None¶
- field spawning_strategy: SpawningStrategy | None = None¶
- class SpawnZoneV2(node_id: str, spawning_strategy: SpawningStrategy, quantity: int, max_attempts: int = 10, force_respawn: bool = False)¶
Bases:
Node
,Animatable
[SpawnZoneV2UpdateParam
]Scattering of assets using a custom spawning strategy.
The spawning strategy must implement 2 methods: - asset_factory(): Returns a single Asset. The Asset can be a parent of other Assets. - placement_strategy(): Returns a Transform for positioning the returned Asset.
There are also 2 optional methods: - validation_strategy(asset) returns bool indicating if the placement is valid.
If not provided, it defaults to checking if the asset has collisions.
post_spawn_hook(asset) is called after the asset is spawned. Use this to configure properties of the asset.
- Parameters:
node_id (str) – The node ID of the spawnzone.
spawning_strategy (SpawningStrategy) – The spawning strategy to use. Must implement asset_factory(), placement_strategy(), validation_strategy() and post_spawn_hook() methods.
quantity (int) – The max number of objects to spawn.
max_attempts (int, optional) – The maximum number of attempts to try and spawn an asset. Defaults to 10.
force_respawn (bool, optional) – Whether to forcibly remove all existing assets and spawn new ones at each frame. Defaults to False.
Example:
class MySpawningStrategy(SpawningStrategy): def __init__(self, polygon: Polygon): self.polygon = polygon def asset_factory(self) -> Asset: parent_asset = Asset( SpawningStrategy.NODE_ID_PLACEHOLDER, asset_name=... ) child_asset = Asset( SpawningStrategy.NODE_ID_PLACEHOLDER, asset_name=... ) child_asset.attach_to(parent_asset) return parent_asset def placement_strategy(self) -> Transform: position = self.polygon.uniform_random_points(1)[0] return Transform( position=position, rotation=Vector3.zero(), scale=Vector3.one() ) def validation_strategy(self, asset: Asset) -> bool: all_nodes = [asset, *get_all_children(asset)] return not any(n.get_collisions() for n in all_nodes if isinstance(n, Asset)) def post_spawn_hook(self, asset: Asset) -> None: asset.enable_wakes(True) spawn_zone = SpawnZoneV2( node_id="my_spawn_zone", spawning_strategy=MySpawningStrategy(polygon=polygon), quantity=10 )
- pre_execute(frame_id: int | None = None, frame_max: int | None = None, delta_seconds: float | None = None) None ¶
Removes spawned assets if respawning is needed. This is to ensure that the old assets are not present during collision checks, especially in the case where there are multiple SpawnZones and they overlap
- Parameters:
frame_id (int | None, optional) – The frame ID. Defaults to None.
frame_max (int | None, optional) – Max frame count in the current loop. Defaults to None.
delta_seconds (float | None, optional) – The target real-time in seconds between frames. This is used to calculate physical displacement for certain assets. Defaults to None.
- execute(frame_id: int | None = None, frame_max: int | None = None, delta_seconds: float | None = None) None ¶
Update the spawnzone state up to the specified frame.
- Parameters:
frame_id (int | None, optional) – The frame ID. Defaults to None.
frame_max (int | None, optional) – Max frame count in the current loop. Defaults to None.
delta_seconds (float | None, optional) – The target real-time in seconds between frames. This is used to calculate physical displacement for certain assets. Defaults to None.