#proper camera movement
1 messages · Page 1 of 1 (latest)
player setup
fn setup(
mut commands: Commands,
level_assets: Res<LevelAssets>,
player_assets: Res<PlayerAssets>,
models: Res<Assets<Gltf>>,
) {
let scene_gltf = models.get(level_assets.level.clone()).unwrap();
let player_gltf = models.get(player_assets.level.clone()).unwrap();
commands.spawn((
SceneBundle {
scene: scene_gltf.scenes[0].clone(),
..default()
},
Name::new("Scene"),
));
commands
.spawn((
SceneBundle {
scene: player_gltf.scenes[0].clone(),
..default()
},
Name::new("Player"),
))
.with_children(|child| {
child.spawn((
Visibility::Visible,
Camera3dBundle {
camera: Camera {
hdr: true,
..default()
},
transform: Transform::from_xyz(0.0, 3.0, -1.0),
..default()
},
PlayerCamera,
));
});
}
camera move
fn move_camera(
cursor_lock_state: Res<CursorLockState>,
mut motion_evr: EventReader<MouseMotion>,
mut cam_q: Query<&mut Transform, With<PlayerCamera>>,
mut player_q: Query<&mut Transform, (With<Player>, Without<PlayerCamera>)>,
primary_window: Query<&Window, With<PrimaryWindow>>,
) {
if cursor_lock_state.state {
let window = primary_window.get_single().unwrap();
let mut cam_t = cam_q.get_single_mut().unwrap();
let mut player_t = player_q.get_single_mut().unwrap();
for ev in motion_evr.read() {
let (mut yaw, mut pitch, _) = cam_t.rotation.to_euler(EulerRot::YXZ);
let window_scale = window.height().min(window.width());
pitch -= (SENSITIVITY * ev.delta.y * window_scale).to_radians();
yaw -= (SENSITIVITY * ev.delta.x * window_scale).to_radians();
pitch = pitch.clamp(-1.54, 1.54);
cam_t.rotation =
Quat::from_axis_angle(Vec3::Y, yaw) * Quat::from_axis_angle(Vec3::X, pitch);
player_t.rotation.y = cam_t.rotation.z;
}
}
}
here's the code, please help
Putting a pin in this, I’ll come back to it later when I have time.
thanks
what's your goal? any examples? third person shooter?
your biggest issue is here: player_t.rotation.y = cam_t.rotation.z;
Taking a look at this now. The issue is that rotation.y thing. You are correctly using MouseMotion events, but then your math is wrong.
You probably want to use Transform::rotate_y and Transform::rotate_z rather than accessing the rotation quaternions directly.
for ev in motion_evr.read() {
...
cam_t.rotate_x(pitch)
player_t.rotate_y(yaw)
}
@toxic idol that should work. Might need to fiddle with the signs or the axies. The y rotation on the player should automatically propagate down to the camera.
Otherwise great job! It was really close.
And this will also change the cameras global transform position since it is the child of the player?
I'll try this in a bit
Yes
it looks like the player is rotating but the camera is locked in place for some reason (like it moves but it returns to the original position)
Hmmm
i can share my screen and show you if you want
.rotate_y() DOESN'T actually move its child components
something like this?
https://learnbevy.com/playground?share=e0c0cbfc51f669eccd8675ebe35aad23368c9947f1f2ad1c0add3cecad1e8528
Experiment with Bevy apps in your browser
wow i had no idea there was a bevy playground
now that I think about it, I guess it should be this instead since the camera is a child of the player:
camera_tx.rotate_around(
//player_tx.translation,
Vec3::ZERO,
Quat::from_axis_angle(*axis, ev.delta.y * -0.01)
);
I didn't have pitch limiting in the previous link, here is a version with something I've used that seems to work
the limits might be what is causing weird behavior in your code
Experiment with Bevy apps in your browser
I will try this, thank you, also I should multiply this by delta time right? So the sensitivity is the same for any fps
thanks, this works, but when trying with an actualy player model from blender instead of a pbrbundle (i used SceneBundle) it didn't work and only rotated the player in place, the camera didnt move with it, is there a way to fix that?
can i add the model to meshes: field in the pbrbundle?