From v0.5.X to v0.6.X
Overview
Version 0.6 brings new features such as Tiled world support and tiles colliders aggregation (which should improve performances when working with physics), bugfixes (mostly for infinite maps) and a rework of the API to make it more user-friendly.
For instance, we now use entity-scoped observers for our loading events instead of global ones, so it's easier to work with several maps at the same time.
Code base have also been re-organized to better fit the new world feature, but it should not impact end-users.
Plugin instanciation
You don't need to manually instanciate the TilemapPlugin from bevy_ecs_tilemap.
It is now automatically done when adding TiledMapPlugin to your application if not already done.
Before :
use bevy::prelude::*; use bevy_ecs_tiled::prelude::*; use bevy_ecs_tilemap::prelude::*; fn main() { App::new() // Main plugin from bevy_ecs_tilemap .add_plugins(TilemapPlugin) // Main plugin from bevy_ecs_tiled .add_plugins(TiledMapPlugin::default()); }
After :
use bevy::prelude::*; use bevy_ecs_tiled::prelude::*; fn main() { App::new() // Main plugin from bevy_ecs_tiled: // implicitely load bevy_ecs_tilemap main plugin .add_plugins(TiledMapPlugin::default()); }
Map loading events
Map loading events have been heavily updated :
- Instead of using a single global observer, we now trigger an entity-scoped observer and send a regular event
- Only use "safe" methods to retrieve data from events (no more
unwrap()internally) - Store an
AssetId<TiledMap>instead of aHandle<TiledMap>to acces Tiled map data, enforce the fact that we store a weak reference in the event and not a strong one. - Some fields from the events have been renamed
Before :
use bevy::prelude::*; use bevy_ecs_tiled::prelude::*; fn main() { App::new() .add_plugins(TiledMapPlugin::default()) .add_systems(Startup, startup) // Previously, we could only use a global observer .add_observer(|trigger: Trigger<TiledMapCreated>, map_asset: Res<Assets<TiledMap>>| { // Previously, the method to retrieve map data would panic in case of error let map = trigger.event().map(&map_asset); info!("(observer) Loaded map: {:?}", map); }); } fn startup( mut commands: Commands, asset_server: Res<AssetServer> ) { commands.spawn(TiledMapHandle(asset_server.load("map.tmx"))); }
After :
use bevy::prelude::*; use bevy_ecs_tiled::prelude::*; fn main() { App::new() .add_plugins(TiledMapPlugin::default()) .add_systems(Startup, startup) .add_systems(Update, read_map_events); } fn startup(mut commands: Commands, asset_server: Res<AssetServer>) { commands .spawn(TiledMapHandle(asset_server.load("map.tmx"))) // Now, you can use an entity-scoped observer .observe( |trigger: Trigger<TiledMapCreated>, map_asset: Res<Assets<TiledMap>>| { // Now, this method return an Option<T> and don't panic in case of error if let Some(map) = trigger.event().get_map(&map_asset) { info!("(observer) Loaded map: {:?}", map); } }, ); } // Or a regular event fn read_map_events(mut map_events: EventReader<TiledMapCreated>, map_asset: Res<Assets<TiledMap>>) { for event in map_events.read() { if let Some(map) = event.get_map(&map_asset) { info!("(event) Loaded map: {:?}", map); } } }
For more detailled informations, you should have a look to the dedicated example or the guide.
Physics
To get tile colliders aggregation working, we had to rework a bit the physics API :
- function
TiledPhysicsBackend::spawn_collider()can now spawn several colliders per call. To reflect that it now returns aVec<TiledColliderSpawnInfos>instead of anOption<TiledColliderSpawnInfos>. Also, it now takes aTiledNameFilteras input parameter to filter out unwanted objects - remove the
TiledColliderCreatedevents which added some complexity but did not have actual usage - rename
TiledColliderSourceTypetoTiledColliderand remove theTilevariant in favor of the newTilesLayer TiledPhysicsBackendnow requires to implement theClone,ReflectandDebugtraits- rename Rename
ObjectNameFiltertoTiledNameFiltersince we also use it for layer name
Schedules
To prevent potential Bevy error B0003 we changed a bit how our systems are scheduled.
Before, everything was done in the Update schedule.
Now, we schedule systems that spawn entities in the PreUpdate schedule and systems that could despawn entities in the PostUpdate schedule.
Misc API changes
- rename
TiledIdStoragecomponent toTiledMapStorageso we are consistent with the new world API - rename
ObjectNameFiltertype toTiledNameFiltersince we also use it for layer names - rename
from_tiled_coords_to_bevyfunction tofrom_tiled_position_to_world_space - split
TiledMapSettingscomponent in two:TiledMapAnchorandTiledMapLayerZOffset