mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added auto camera setting
This commit is contained in:
parent
25f18229d3
commit
60e2ed3e7d
@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Buy and sell prices in tooltips when trading with a merchant now have colors.
|
- Buy and sell prices in tooltips when trading with a merchant now have colors.
|
||||||
- Attacks now emit sound effects from the target on hit.
|
- Attacks now emit sound effects from the target on hit.
|
||||||
- Crafting menu tabs
|
- Crafting menu tabs
|
||||||
|
- Auto camera setting, making the game easier to play with one hand
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
"hud.settings.auto_walk_behavior": "Auto walk behavior",
|
"hud.settings.auto_walk_behavior": "Auto walk behavior",
|
||||||
"hud.settings.camera_clamp_behavior": "Camera clamp behavior",
|
"hud.settings.camera_clamp_behavior": "Camera clamp behavior",
|
||||||
"hud.settings.stop_auto_walk_on_input": "Stop auto walk on movement",
|
"hud.settings.stop_auto_walk_on_input": "Stop auto walk on movement",
|
||||||
|
"hud.settings.auto_camera": "Auto camera",
|
||||||
"hud.settings.reset_gameplay": "Reset to Defaults",
|
"hud.settings.reset_gameplay": "Reset to Defaults",
|
||||||
|
|
||||||
"hud.settings.view_distance": "View Distance",
|
"hud.settings.view_distance": "View Distance",
|
||||||
|
@ -434,6 +434,7 @@ pub enum Event {
|
|||||||
ChangeAutoWalkBehavior(PressBehavior),
|
ChangeAutoWalkBehavior(PressBehavior),
|
||||||
ChangeCameraClampBehavior(PressBehavior),
|
ChangeCameraClampBehavior(PressBehavior),
|
||||||
ChangeStopAutoWalkOnInput(bool),
|
ChangeStopAutoWalkOnInput(bool),
|
||||||
|
ChangeAutoCamera(bool),
|
||||||
CraftRecipe(String),
|
CraftRecipe(String),
|
||||||
InviteMember(Uid),
|
InviteMember(Uid),
|
||||||
AcceptInvite,
|
AcceptInvite,
|
||||||
@ -2663,6 +2664,9 @@ impl Hud {
|
|||||||
settings_window::Event::ChangeStopAutoWalkOnInput(state) => {
|
settings_window::Event::ChangeStopAutoWalkOnInput(state) => {
|
||||||
events.push(Event::ChangeStopAutoWalkOnInput(state));
|
events.push(Event::ChangeStopAutoWalkOnInput(state));
|
||||||
},
|
},
|
||||||
|
settings_window::Event::ChangeAutoCamera(state) => {
|
||||||
|
events.push(Event::ChangeAutoCamera(state));
|
||||||
|
},
|
||||||
settings_window::Event::ResetInterfaceSettings => {
|
settings_window::Event::ResetInterfaceSettings => {
|
||||||
self.show.help = false;
|
self.show.help = false;
|
||||||
self.show.debug = false;
|
self.show.debug = false;
|
||||||
|
@ -243,6 +243,8 @@ widget_ids! {
|
|||||||
camera_clamp_behavior_list,
|
camera_clamp_behavior_list,
|
||||||
stop_auto_walk_on_input_button,
|
stop_auto_walk_on_input_button,
|
||||||
stop_auto_walk_on_input_label,
|
stop_auto_walk_on_input_label,
|
||||||
|
auto_camera_button,
|
||||||
|
auto_camera_label,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,6 +352,7 @@ pub enum Event {
|
|||||||
ChangeAutoWalkBehavior(PressBehavior),
|
ChangeAutoWalkBehavior(PressBehavior),
|
||||||
ChangeCameraClampBehavior(PressBehavior),
|
ChangeCameraClampBehavior(PressBehavior),
|
||||||
ChangeStopAutoWalkOnInput(bool),
|
ChangeStopAutoWalkOnInput(bool),
|
||||||
|
ChangeAutoCamera(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -1703,7 +1706,7 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
self.imgs.checkbox_checked,
|
self.imgs.checkbox_checked,
|
||||||
)
|
)
|
||||||
.w_h(18.0, 18.0)
|
.w_h(18.0, 18.0)
|
||||||
.right_from(state.ids.auto_walk_behavior_text, 80.0)
|
.down_from(state.ids.smooth_pan_toggle_button, 8.0)
|
||||||
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
||||||
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
||||||
.set(state.ids.stop_auto_walk_on_input_button, ui);
|
.set(state.ids.stop_auto_walk_on_input_button, ui);
|
||||||
@ -1728,6 +1731,32 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
.color(TEXT_COLOR)
|
.color(TEXT_COLOR)
|
||||||
.set(state.ids.stop_auto_walk_on_input_label, ui);
|
.set(state.ids.stop_auto_walk_on_input_label, ui);
|
||||||
|
|
||||||
|
// Auto-camera toggle
|
||||||
|
let auto_camera_toggle = ToggleButton::new(
|
||||||
|
self.global_state.settings.gameplay.auto_camera,
|
||||||
|
self.imgs.checkbox,
|
||||||
|
self.imgs.checkbox_checked,
|
||||||
|
)
|
||||||
|
.w_h(18.0, 18.0)
|
||||||
|
.down_from(state.ids.stop_auto_walk_on_input_button, 8.0)
|
||||||
|
.hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo)
|
||||||
|
.press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked)
|
||||||
|
.set(state.ids.auto_camera_button, ui);
|
||||||
|
|
||||||
|
if self.global_state.settings.gameplay.auto_camera != auto_camera_toggle {
|
||||||
|
events.push(Event::ChangeAutoCamera(
|
||||||
|
!self.global_state.settings.gameplay.auto_camera,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Text::new(&self.localized_strings.get("hud.settings.auto_camera"))
|
||||||
|
.right_from(state.ids.auto_camera_button, 10.0)
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.graphics_for(state.ids.auto_camera_button)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.auto_camera_label, ui);
|
||||||
|
|
||||||
// Reset the gameplay settings to the default settings
|
// Reset the gameplay settings to the default settings
|
||||||
if Button::image(self.imgs.button)
|
if Button::image(self.imgs.button)
|
||||||
.w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)
|
.w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)
|
||||||
|
@ -52,6 +52,17 @@ pub struct Camera {
|
|||||||
frustum: Frustum<f32>,
|
frustum: Frustum<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clamp_and_modulate(ori: Vec3<f32>) -> Vec3<f32> {
|
||||||
|
Vec3 {
|
||||||
|
// Wrap camera yaw
|
||||||
|
x: ori.x.rem_euclid(2.0 * PI),
|
||||||
|
// Clamp camera pitch to the vertical limits
|
||||||
|
y: ori.y.min(PI / 2.0 - 0.0001).max(-PI / 2.0 + 0.0001),
|
||||||
|
// Wrap camera roll
|
||||||
|
z: ori.z.rem_euclid(2.0 * PI),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Camera {
|
impl Camera {
|
||||||
/// Create a new `Camera` with default parameters.
|
/// Create a new `Camera` with default parameters.
|
||||||
pub fn new(aspect: f32, mode: CameraMode) -> Self {
|
pub fn new(aspect: f32, mode: CameraMode) -> Self {
|
||||||
@ -156,23 +167,12 @@ impl Camera {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set the orientation of the camera about its focus.
|
/// Set the orientation of the camera about its focus.
|
||||||
pub fn set_orientation(&mut self, ori: Vec3<f32>) {
|
pub fn set_orientation(&mut self, ori: Vec3<f32>) { self.tgt_ori = clamp_and_modulate(ori); }
|
||||||
// Wrap camera yaw
|
|
||||||
self.tgt_ori.x = ori.x.rem_euclid(2.0 * PI);
|
|
||||||
// Clamp camera pitch to the vertical limits
|
|
||||||
self.tgt_ori.y = ori.y.min(PI / 2.0 - 0.0001).max(-PI / 2.0 + 0.0001);
|
|
||||||
// Wrap camera roll
|
|
||||||
self.tgt_ori.z = ori.z.rem_euclid(2.0 * PI);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the orientation of the camera about its focus without lerping.
|
/// Set the orientation of the camera about its focus without lerping.
|
||||||
pub fn set_ori_instant(&mut self, ori: Vec3<f32>) {
|
pub fn set_orientation_instant(&mut self, ori: Vec3<f32>) {
|
||||||
// Wrap camera yaw
|
self.set_orientation(ori);
|
||||||
self.ori.x = ori.x.rem_euclid(2.0 * PI);
|
self.ori = self.tgt_ori;
|
||||||
// Clamp camera pitch to the vertical limits
|
|
||||||
self.ori.y = ori.y.min(PI / 2.0 - 0.0001).max(-PI / 2.0 + 0.0001);
|
|
||||||
// Wrap camera roll
|
|
||||||
self.ori.z = ori.z.rem_euclid(2.0 * PI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Zoom the camera by the given delta, limiting the input accordingly.
|
/// Zoom the camera by the given delta, limiting the input accordingly.
|
||||||
@ -249,15 +249,16 @@ impl Camera {
|
|||||||
Lerp::lerp(a, b + *offs, rate)
|
Lerp::lerp(a, b + *offs, rate)
|
||||||
};
|
};
|
||||||
|
|
||||||
if smoothing_enabled {
|
let ori = if smoothing_enabled {
|
||||||
self.set_ori_instant(Vec3::new(
|
Vec3::new(
|
||||||
lerp_angle(self.ori.x, self.tgt_ori.x, LERP_ORI_RATE * dt),
|
lerp_angle(self.ori.x, self.tgt_ori.x, LERP_ORI_RATE * dt),
|
||||||
Lerp::lerp(self.ori.y, self.tgt_ori.y, LERP_ORI_RATE * dt),
|
Lerp::lerp(self.ori.y, self.tgt_ori.y, LERP_ORI_RATE * dt),
|
||||||
lerp_angle(self.ori.z, self.tgt_ori.z, LERP_ORI_RATE * dt),
|
lerp_angle(self.ori.z, self.tgt_ori.z, LERP_ORI_RATE * dt),
|
||||||
));
|
)
|
||||||
} else {
|
} else {
|
||||||
self.set_ori_instant(self.tgt_ori)
|
self.tgt_ori
|
||||||
};
|
};
|
||||||
|
self.ori = clamp_and_modulate(ori);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interp_time(&self) -> f32 {
|
pub fn interp_time(&self) -> f32 {
|
||||||
|
@ -732,6 +732,27 @@ impl PlayState for SessionState {
|
|||||||
// Get the current state of movement related inputs
|
// Get the current state of movement related inputs
|
||||||
let input_vec = self.key_state.dir_vec();
|
let input_vec = self.key_state.dir_vec();
|
||||||
let (axis_right, axis_up) = (input_vec[0], input_vec[1]);
|
let (axis_right, axis_up) = (input_vec[0], input_vec[1]);
|
||||||
|
let dt = global_state.clock.get_stable_dt().as_secs_f32();
|
||||||
|
|
||||||
|
// Auto camera mode
|
||||||
|
if global_state.settings.gameplay.auto_camera
|
||||||
|
&& matches!(
|
||||||
|
self.scene.camera().get_mode(),
|
||||||
|
camera::CameraMode::ThirdPerson | camera::CameraMode::FirstPerson
|
||||||
|
)
|
||||||
|
&& input_vec.magnitude_squared() > 0.0
|
||||||
|
{
|
||||||
|
let camera = self.scene.camera_mut();
|
||||||
|
let ori = camera.get_orientation();
|
||||||
|
camera.set_orientation_instant(Vec3::new(
|
||||||
|
ori.x
|
||||||
|
+ input_vec.x
|
||||||
|
* (3.0 - input_vec.y * 1.5 * if is_aiming { 1.5 } else { 1.0 })
|
||||||
|
* dt,
|
||||||
|
std::f32::consts::PI * if is_aiming { 0.015 } else { 0.1 },
|
||||||
|
0.0,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
match self.scene.camera().get_mode() {
|
match self.scene.camera().get_mode() {
|
||||||
camera::CameraMode::FirstPerson | camera::CameraMode::ThirdPerson => {
|
camera::CameraMode::FirstPerson | camera::CameraMode::ThirdPerson => {
|
||||||
@ -753,7 +774,6 @@ impl PlayState for SessionState {
|
|||||||
let right = self.scene.camera().right();
|
let right = self.scene.camera().right();
|
||||||
let dir = right * axis_right + forward * axis_up;
|
let dir = right * axis_right + forward * axis_up;
|
||||||
|
|
||||||
let dt = global_state.clock.get_stable_dt().as_secs_f32();
|
|
||||||
if self.freefly_vel.magnitude_squared() > 0.01 {
|
if self.freefly_vel.magnitude_squared() > 0.01 {
|
||||||
let new_vel = self.freefly_vel
|
let new_vel = self.freefly_vel
|
||||||
- self.freefly_vel.normalized() * (FREEFLY_DAMPING * dt);
|
- self.freefly_vel.normalized() * (FREEFLY_DAMPING * dt);
|
||||||
@ -1406,6 +1426,10 @@ impl PlayState for SessionState {
|
|||||||
global_state.settings.gameplay.stop_auto_walk_on_input = state;
|
global_state.settings.gameplay.stop_auto_walk_on_input = state;
|
||||||
global_state.settings.save_to_file_warn();
|
global_state.settings.save_to_file_warn();
|
||||||
},
|
},
|
||||||
|
HudEvent::ChangeAutoCamera(state) => {
|
||||||
|
global_state.settings.gameplay.auto_camera = state;
|
||||||
|
global_state.settings.save_to_file_warn();
|
||||||
|
},
|
||||||
HudEvent::CraftRecipe(r) => {
|
HudEvent::CraftRecipe(r) => {
|
||||||
self.client.borrow_mut().craft_recipe(&r);
|
self.client.borrow_mut().craft_recipe(&r);
|
||||||
},
|
},
|
||||||
|
@ -503,6 +503,7 @@ pub struct GameplaySettings {
|
|||||||
pub auto_walk_behavior: PressBehavior,
|
pub auto_walk_behavior: PressBehavior,
|
||||||
pub camera_clamp_behavior: PressBehavior,
|
pub camera_clamp_behavior: PressBehavior,
|
||||||
pub stop_auto_walk_on_input: bool,
|
pub stop_auto_walk_on_input: bool,
|
||||||
|
pub auto_camera: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for GameplaySettings {
|
impl Default for GameplaySettings {
|
||||||
@ -518,6 +519,7 @@ impl Default for GameplaySettings {
|
|||||||
auto_walk_behavior: PressBehavior::Toggle,
|
auto_walk_behavior: PressBehavior::Toggle,
|
||||||
camera_clamp_behavior: PressBehavior::Toggle,
|
camera_clamp_behavior: PressBehavior::Toggle,
|
||||||
stop_auto_walk_on_input: true,
|
stop_auto_walk_on_input: true,
|
||||||
|
auto_camera: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user