How to rotate and move object in bevy

Viewed 2573

I want to rotate my object by a given amount and translate it forward to create a steerable tank.

I couldn't find out how to do it, all the matrices, vectors, and quaternions make it difficult for me to find a solution.

This is the Unity equivalent of what i want to do:

transform.Rotate(0, 0, -turn_input * turnSpeed * Time.deltaTime);
transform.position += transform.forward * drive * speed * Time.deltaTime;

I used to use this code in Bevy 0.2.1 but it broke after updating to 0.4

*transform.value_mut() = *transform.value()
    * Mat4::from_rotation_translation(
        Quat::from_rotation_z(-turn_input * tank.turn_speed * time.delta_seconds),
        Vec3::unit_y() * drive * tank.speed * time.delta_seconds,
    );
2 Answers

That was changed in Bevy 0.3 with "Move transform data out of Mat4" (PR #596)

This changed, so instead of Transform having a value: Mat4 field, then instead it would have translation: Vec3, rotation: Quat, and scale: Vec3.

If you want a literal translation of your code, then that would be:

transform = Transform::from_matrix(
    transform.compute_matrix()
        * Mat4::from_rotation_translation(
            Quat::from_rotation_z(-turn_input * tank.turn_speed * time.delta_seconds),
            Vec3::unit_y() * drive * tank.speed * time.delta_seconds,
        ),
);

However, it might be more straightforward to use transform.rotate() and/or assign directly to transform.translation and transform.rotation.

I found the answer thanks to @Sleepyhead on discord. It's close to the Unity code but 3 lines because you can't read and update on the same line.

Bevy only has transform.forward() (suggested by @Sleepyhead) which goes into the Z direction: https://docs.rs/bevy/0.4.0/bevy/prelude/struct.Transform.html#method.forward

#[inline]
pub fn forward(&self) -> Vec3 {
    self.rotation * Vec3::unit_z()
}

I modified this code for the Y direction transform.rotation * Vec3::unit_y() and use this in the final solution:

transform.rotate(Quat::from_rotation_z(-turn_input * tank.turn_speed * time.delta_seconds()));
let move_dir = transform.rotation * Vec3::unit_y() * drive * tank.speed * time.delta_seconds();
transform.translation += move_dir;

There is currently an open issue for adding more directions to Transform: https://github.com/bevyengine/bevy/issues/1298

Related