bevy_rapier
bevy_rapier copied to clipboard
Limited RigidBody rotation in 2d
I've noticed that directly altering the rotation of an entity containing a RigidBody
component is only possible around the z-axis; however, entities without a RigidBody
(even entities containing a Collider
) can have their rotations directly altered:
use bevy::prelude::*;
use bevy_rapier2d::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(10.))
.add_startup_system(setup)
.add_system(flip_colliders)
.add_system(flip_rigid_bodies)
.add_system(test)
.run();
}
fn setup(
mut commands: Commands
) {
// spawn entity with collider
commands
.spawn()
.insert(Collider::cuboid(10., 10.))
.insert(Transform::from_rotation(Quat::IDENTITY))
.insert(GlobalTransform::default());
// spawn entity with rigid body
commands
.spawn()
.insert(RigidBody::Dynamic)
.insert(Transform::from_rotation(Quat::IDENTITY))
.insert(GlobalTransform::default());
}
fn flip_colliders(
mut colliders: Query<&mut Transform, Added<Collider>>,
) {
for mut transform in colliders.iter_mut() {
transform.rotation = Quat::from_rotation_y(std::f32::consts::PI);
}
}
fn flip_rigid_bodies(
mut rigid_bodies: Query<&mut Transform, Added<RigidBody>>
) {
for mut transform in rigid_bodies.iter_mut() {
transform.rotation = Quat::from_rotation_y(std::f32::consts::PI);
}
}
fn test(
colliders: Query<&Transform, With<Collider>>,
rigid_bodies: Query<&Transform, With<RigidBody>>
) {
// check if collider rotation changed
for transform in colliders.iter() {
assert_eq!(transform.rotation, Quat::from_rotation_y(std::f32::consts::PI),
"Collider rotation didn't change!");
}
// check if rigid body rotation changed
for transform in rigid_bodies.iter() {
assert_eq!(transform.rotation, Quat::from_rotation_y(std::f32::consts::PI),
"RigidBody rotation didn't change!");
}
}
The above code panics with the following:
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `Quat(0.0, 0.0, 0.0, 1.0)`,
right: `Quat(0.0, 1.0, 0.0, -4.371139e-8)`: RigidBody rotation didn't change!', src\main.rs:61:9
Is there an effective way to instantly change the rotation of a RigidBody
? I understand that bevy_rapier2d
is a 2d physics engine, but the ability to rotate the entity around the x- and y-axes is especially useful for changing its orientation (e.g., flipping the player sprite in a platformer).
You can use TextureAtlasSprite flip_x = true or false
Flipping the sprite would only change its orientation visibly, while changing the entity's rotation would both change its orientation and the orientation of its child entities.
For example, if I coded an attack hitbox to spawn as a child of an attacker, the attack's Transform
would be relative to that of its parent attacker. Thus, if said attack always spawned with a positive translation from the parent attacker, and the attacker was facing to the right, the attack would spawn right of the attacker and thusly be correctly orientated in front of the attacker.
However, if I faced the attacker left by flipping its sprite, the attack's positive translation would still spawn it right of the attacker, thereby incorrectly orientating the attack behind the attacker.
If I instead faced the attacker left by rotating it 180 degrees about its y-axis, the attack's positive translation would again spawn it right of the attacker, but the parent attacker's Transform
would then rotate the attack 180 degrees around the attacker's y-axis, thereby placing the attack left of its attacker and correctly orienting the attack in front of its attacker. This rotation would also "flip" the attack's sprite like the attacker's.
Sorry,I didn't take into account attacks and other features. I am learning BEVY, and when I write about MOVEMENT and SPRITE ANIMATION, I also encounter the same problem.Simply thought that inverting the sprite would solve it, but it looks like there are more problems to be solved.
that's not easy, how would a rotation of 45 degrees react ? A user could expect to have the collider shorter like this image:
I think a "flip" method/property is probably safer ; and/or opt out from bevy Transform
for a specific PhysicsTransform
so we don't end up in weird half 3d / half 2d components