Trouv / bevy_ecs_ldtk

ECS-friendly ldtk plugin for bevy, leveraging bevy_ecs_tilemap
Other
627 stars 73 forks source link

Loaded entity position ignores pivot #290

Open Koopa1018 opened 5 months ago

Koopa1018 commented 5 months ago

In my LDtk project, I have defined a number of entities with a bottom pivot point: image

Based on my work in other apps, I expect the pivot to change how entities are placed relative to the position shown--and indeed, in LDtk I see this exact thing happening. image Left: origin on the bottom. Right: origin in center, moved to fill the same space. Note the changed Y coordinate.

But when those entities are loaded into Bevy: image What the pfargtl?! The Transform component stores the object's center instead of its origin!

I've compensated in my code. But it's a huge bother to have to do complicated math instead of just reading a component which, frankly, ought to match LDtk's behavior in the first place (apart from Y-down coordinates).

Trouv commented 5 months ago

Yep, I agree this is bad behavior. It's a holdover from when this plugin was originally written, which was before the Anchor in bevy sprites existed. Sprites were just anchored to their center, and so to make spawned entities w/ sprites have the same visual location in LDtk, the transform was adjusted instead. Now, it's well past time we switch to using the Anchor to pivot entities instead of the transform.

Koopa1018 commented 5 months ago

Ahh, historical workarounds....that makes sense 🙂

DavidHospital commented 3 weeks ago

Any update on this issue? Is there a workaround while https://github.com/Trouv/bevy_ecs_ldtk/pull/294 is still open?

Koopa1018 commented 3 weeks ago

I know I had one. Lemme see if I can find it.... Ah, here it is. Straight from my janky codebase.

use bevy::{prelude::*, math::{vec2, ivec2}};
use bevy_ecs_ldtk::EntityInstance;

pub fn position_pivoted(position: Vec2, entity: &EntityInstance) -> Vec2{
    // For some reason, the GlobalTransform position is the
    // CENTER POINT of the entity, not the point defined in LDtk.
    // Compensate for that by applying origin to the entity.

    // offset relative to pivot
    position + (
        // start with 0-1 pivot
        entity.pivot
        // adjusted so center is actually centered
        - vec2(0.5, 0.5)
    )
    // Scale it to object size
    * ivec2(entity.width, entity.height).as_vec2()
    // invert from Y-down to Y-up
    * vec2(1.0, -1.0)
}