Merge branch 'catb0t/1528-camera-zoom-lock-toggle' into 'master'

Allow locking camera zoom

Closes #1528

See merge request veloren/veloren!3802
This commit is contained in:
Isse 2023-03-06 18:17:06 +00:00
commit a25edef40e
15 changed files with 347 additions and 7 deletions

View File

@ -18,6 +18,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Unlockable door blocks.
- Sprite rotation for Spots.
- Better entity placement options for spots.
- Camera zoom can now be locked, to prevent accidental zooming while rolling in combat. It comes
with a keybind to enable/disable the setting, and an Auto/Toggle behavior setting. Auto behavior
will only lock the camera zoom while movement and combat inputs are also being pressed.
### Changed
- Bats move slower and use a simple proportional controller to maintain altitude

View File

@ -49,6 +49,7 @@ gameinput-togglewield = Waffe ziehen/wegstecken
gameinput-interact = Interagieren
gameinput-freelook = Freie Sicht
gameinput-autowalk = Automatisch Laufen/Schwimmen
gameinput-zoomlock = Kamera-Zoomsperre
gameinput-cameraclamp = Kamera fixieren
gameinput-dance = Tanzen
gameinput-select = Einheit auswählen

View File

@ -35,6 +35,9 @@ hud-diary = Tagebuch
hud-free_look_indicator = Freie Sicht aktiv. Drücke { $key } zum deaktivieren.
hud-camera_clamp_indicator = Vertikale Kamerafixierung aktiv. Drücke { $key } zum deaktivieren.
hud-auto_walk_indicator = Auto Laufen/Schwimmen aktiv
hud-zoom_lock_indicator-remind = Zoom gesperrt
hud-zoom_lock_indicator-enable = Kamerazoom gesperrt
hud-zoom_lock_indicator-disable = Kamerazoom entsperrt
hud-collect = Aufsammeln
hud-pick_up = Aufheben
hud-open = Öffnen

View File

@ -2,6 +2,8 @@ hud-settings-general = Allgemein
hud-settings-none = Keine
hud-settings-press_behavior-toggle = Umschalten
hud-settings-press_behavior-hold = Halten
hud-settings-autopress_behavior-toggle = Umschalten
hud-settings-autopress_behavior-auto = Auto
hud-settings-help_window = Hilfe zu Fenstern
hud-settings-debug_info = Debug-Informationen
hud-settings-show_hitboxes = Hitboxen anzeigen
@ -50,10 +52,12 @@ hud-settings-enable_mouse_smoothing = Kamera-Glättung
hud-settings-free_look_behavior = Verhalten bei freiem Kameramodus
hud-settings-auto_walk_behavior = Verhalten bei automatischem Gehen
hud-settings-camera_clamp_behavior = Verhalten bei starrer Kamera
hud-settings-zoom_lock_behavior = Verhalten bei Kamera-Zoomsperre
hud-settings-player_physics_behavior = Spielerphysik (experimentell)
hud-settings-stop_auto_walk_on_input = Automatisches Gehen bei Spieleraktivität anhalten
hud-settings-auto_camera = Auto Kamera
hud-settings-bow_zoom = Hinein zoomen, wenn der Bogen aufgeladen wird
hud-settings-zoom_lock = Kamera-Zoomsperre
hud-settings-reset_gameplay =
Einstellungen
zurücksetzen

View File

@ -49,6 +49,7 @@ gameinput-togglewield = Toggle Wield
gameinput-interact = Interact
gameinput-freelook = Free Look
gameinput-autowalk = Auto Walk/Swim
gameinput-zoomlock = Camera zoom lock
gameinput-cameraclamp = Camera Clamp
gameinput-dance = Dance
gameinput-select = Select Entity

View File

@ -35,6 +35,9 @@ hud-diary = Diary
hud-free_look_indicator = Free look active. Press { $key } to disable.
hud-camera_clamp_indicator = Camera vertical clamp active. Press { $key } to disable.
hud-auto_walk_indicator = Auto walk/swim active
hud-zoom_lock_indicator-remind = Zoom locked
hud-zoom_lock_indicator-enable = Camera zoom locked
hud-zoom_lock_indicator-disable = Camera zoom unlocked
hud-collect = Collect
hud-pick_up = Pick up
hud-open = Open

View File

@ -2,6 +2,8 @@ hud-settings-general = General
hud-settings-none = None
hud-settings-press_behavior-toggle = Toggle
hud-settings-press_behavior-hold = Hold
hud-settings-autopress_behavior-toggle = Toggle
hud-settings-autopress_behavior-auto = Auto
hud-settings-help_window = Help Window
hud-settings-debug_info = Debug Info
hud-settings-show_hitboxes = Show hitboxes
@ -49,10 +51,12 @@ hud-settings-enable_mouse_smoothing = Camera Smoothing
hud-settings-free_look_behavior = Free look behavior
hud-settings-auto_walk_behavior = Auto walk behavior
hud-settings-camera_clamp_behavior = Camera clamp behavior
hud-settings-zoom_lock_behavior = Camera zoom lock behavior
hud-settings-player_physics_behavior = Player physics (experimental)
hud-settings-stop_auto_walk_on_input = Stop auto walk on movement
hud-settings-auto_camera = Auto camera
hud-settings-bow_zoom = Zoom in when charging bow
hud-settings-zoom_lock = Camera zoom lock
hud-settings-reset_gameplay = Reset to Defaults
hud-settings-view_distance = View Distance
hud-settings-entity_view_distance = Entities View Distance

View File

@ -132,6 +132,8 @@ pub enum GameInput {
FreeLook,
#[strum(serialize = "gameinput-autowalk")]
AutoWalk,
#[strum(serialize = "gameinput-zoomlock")]
ZoomLock,
#[strum(serialize = "gameinput-cameraclamp")]
CameraClamp,
#[strum(serialize = "gameinput-cyclecamera")]

View File

@ -0,0 +1,86 @@
use serde::{Deserialize, Serialize};
use std::time::Duration;
/// Default initial alpha of a Notify
const NOTIF_START_ALPHA: f32 = 1.0;
/// Default time to live of a notify
const NOTIF_LIFETIME: f32 = 2.0;
/// Default fading time of a notify
const NOTIF_FADETIME: f32 = 1.5;
/// The reason this notification is being shown: the setting is being enabled or
/// disabled, or we are reminding the player of the current state.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub enum NotificationReason {
Remind = 2,
Enable = 1,
#[serde(other)]
Disable = 0,
}
/// A temporal, fading message that a setting
/// or other state was changed (probably by direct player input)
#[derive(Default)]
pub struct ChangeNotification {
pub reason: Option<NotificationReason>,
pub alpha: f32,
lifetime: Duration,
fadetime: Duration,
initial_fadetime: Duration,
}
impl ChangeNotification {
pub fn new(
reason: Option<NotificationReason>,
alpha: f32,
lifetime: Duration,
fadetime: Duration,
) -> Result<Self, Duration> {
if fadetime.is_zero() {
Err(fadetime)
} else {
Ok(Self {
reason,
alpha,
lifetime,
fadetime,
initial_fadetime: fadetime,
})
}
}
pub fn from_reason(reason: NotificationReason) -> Self {
ChangeNotification::new(
Some(reason),
NOTIF_START_ALPHA,
Duration::from_secs_f32(NOTIF_LIFETIME),
Duration::from_secs_f32(NOTIF_FADETIME),
)
.unwrap()
}
pub fn from_state(state: bool) -> Self {
ChangeNotification::from_reason(match state {
true => NotificationReason::Enable,
false => NotificationReason::Disable,
})
}
pub fn update(&mut self, dt: Duration) {
if self.reason.is_some() {
// Timer before fade
if !self.lifetime.is_zero() {
self.lifetime = self.lifetime.saturating_sub(dt);
// Lifetime expired, start to fade
} else if !self.fadetime.is_zero() {
self.fadetime = self.fadetime.saturating_sub(dt);
// alpha as elapsed duration fraction, multiply with this for nice fade curve
self.alpha = self.fadetime.as_secs_f32() / self.initial_fadetime.as_secs_f32();
// Done fading
} else {
self.reason = None;
}
}
}
}

View File

@ -2,6 +2,7 @@ mod animation;
mod bag;
mod buffs;
mod buttons;
mod change_notification;
mod chat;
mod crafting;
mod diary;
@ -33,6 +34,7 @@ pub use settings_window::ScaleChange;
use bag::Bag;
use buffs::BuffsBar;
use buttons::Buttons;
use change_notification::{ChangeNotification, NotificationReason};
use chat::Chat;
use chrono::NaiveTime;
use crafting::Crafting;
@ -329,6 +331,10 @@ widget_ids! {
auto_walk_txt,
auto_walk_bg,
// Temporal (fading) camera zoom lock indicator
zoom_lock_txt,
zoom_lock_bg,
// Camera clamp indicator
camera_clamp_txt,
camera_clamp_bg,
@ -797,6 +803,16 @@ pub enum PressBehavior {
#[serde(other)]
Toggle = 0,
}
/// Similar to [PressBehavior], with different semantics for settings that
/// change state automatically. There is no [PressBehavior::update][update]
/// implementation because it doesn't apply to the use case; this is just a
/// sentinel.
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum AutoPressBehavior {
Auto = 1,
#[serde(other)]
Toggle = 0,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct ChatTab {
pub label: String,
@ -889,6 +905,7 @@ pub struct Show {
stats: bool,
free_look: bool,
auto_walk: bool,
zoom_lock: ChangeNotification,
camera_clamp: bool,
prompt_dialog: Option<PromptDialogSettings>,
location_markers: MapMarkers,
@ -1367,6 +1384,7 @@ impl Hud {
stats: false,
free_look: false,
auto_walk: false,
zoom_lock: ChangeNotification::default(),
camera_clamp: false,
prompt_dialog: None,
location_markers: MapMarkers::default(),
@ -3522,6 +3540,31 @@ impl Hud {
.set(self.ids.auto_walk_txt, ui_widgets);
}
// Camera zoom lock
self.show.zoom_lock.update(dt);
if let Some(zoom_lock) = self.show.zoom_lock.reason {
let zoom_lock_message = match zoom_lock {
NotificationReason::Remind => "hud-zoom_lock_indicator-remind",
NotificationReason::Enable => "hud-zoom_lock_indicator-enable",
NotificationReason::Disable => "hud-zoom_lock_indicator-disable",
};
Text::new(&i18n.get_msg(zoom_lock_message))
.color(TEXT_BG.alpha(self.show.zoom_lock.alpha))
.mid_top_with_margin_on(ui_widgets.window, indicator_offset)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(20))
.set(self.ids.zoom_lock_bg, ui_widgets);
indicator_offset += 30.0;
Text::new(&i18n.get_msg(zoom_lock_message))
.color(TEXT_COLOR.alpha(self.show.zoom_lock.alpha))
.top_left_with_margins_on(self.ids.zoom_lock_bg, -1.0, -1.0)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(20))
.set(self.ids.zoom_lock_txt, ui_widgets);
}
// Camera clamp indicator
if let Some(cameraclamp_key) = global_state
.settings
@ -4562,6 +4605,20 @@ impl Hud {
pub fn camera_clamp(&mut self, camera_clamp: bool) { self.show.camera_clamp = camera_clamp; }
/// Remind the player camera zoom is currently locked, for example if they
/// are trying to zoom.
pub fn zoom_lock_reminder(&mut self) {
if self.show.zoom_lock.reason.is_none() {
self.show.zoom_lock = ChangeNotification::from_reason(NotificationReason::Remind);
}
}
/// Start showing a temporary notification ([ChangeNotification]) that zoom
/// lock was toggled on/off.
pub fn zoom_lock_toggle(&mut self, state: bool) {
self.show.zoom_lock = ChangeNotification::from_state(state);
}
pub fn handle_outcome(
&mut self,
outcome: &Outcome,

View File

@ -1,7 +1,7 @@
use super::{RESET_BUTTONS_HEIGHT, RESET_BUTTONS_WIDTH};
use crate::{
hud::{img_ids::Imgs, PressBehavior, MENU_BG, TEXT_COLOR},
hud::{img_ids::Imgs, AutoPressBehavior, PressBehavior, MENU_BG, TEXT_COLOR},
session::settings_change::{Gameplay as GameplayChange, Gameplay::*},
ui::{fonts::Fonts, ImageSlider, ToggleButton},
GlobalState,
@ -44,12 +44,16 @@ widget_ids! {
auto_walk_behavior_list,
camera_clamp_behavior_text,
camera_clamp_behavior_list,
zoom_lock_behavior_text,
zoom_lock_behavior_list,
stop_auto_walk_on_input_button,
stop_auto_walk_on_input_label,
auto_camera_button,
auto_camera_label,
bow_zoom_button,
bow_zoom_label,
zoom_lock_button,
zoom_lock_label,
}
}
@ -528,6 +532,68 @@ impl<'a> Widget for Gameplay<'a> {
.color(TEXT_COLOR)
.set(state.ids.bow_zoom_label, ui);
let zoom_lock_label_list = [
self.localized_strings
.get_msg("hud-settings-autopress_behavior-toggle"),
self.localized_strings
.get_msg("hud-settings-autopress_behavior-auto"),
];
// Camera zoom lock behavior
Text::new(
&self
.localized_strings
.get_msg("hud-settings-zoom_lock_behavior"),
)
.down_from(state.ids.auto_walk_behavior_list, 10.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.zoom_lock_behavior_text, ui);
let zoom_lock_selected = self.global_state.settings.gameplay.zoom_lock_behavior as usize;
if let Some(clicked) = DropDownList::new(&zoom_lock_label_list, Some(zoom_lock_selected))
.w_h(200.0, 30.0)
.color(MENU_BG)
.label_color(TEXT_COLOR)
.label_font_id(self.fonts.cyri.conrod_id)
.down_from(state.ids.zoom_lock_behavior_text, 8.0)
.set(state.ids.zoom_lock_behavior_list, ui)
{
match clicked {
0 => events.push(ChangeZoomLockBehavior(AutoPressBehavior::Toggle)),
1 => events.push(ChangeZoomLockBehavior(AutoPressBehavior::Auto)),
_ => unreachable!(),
}
}
// Camera zoom lock toggle
let zoom_lock_toggle = ToggleButton::new(
self.global_state.settings.gameplay.zoom_lock,
self.imgs.checkbox,
self.imgs.checkbox_checked,
)
.w_h(18.0, 18.0)
.down_from(state.ids.bow_zoom_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.zoom_lock_button, ui);
if self.global_state.settings.gameplay.zoom_lock != zoom_lock_toggle {
events.push(ChangeZoomLock(
!self.global_state.settings.gameplay.zoom_lock,
));
}
Text::new(&self.localized_strings.get_msg("hud-settings-zoom_lock"))
.right_from(state.ids.zoom_lock_button, 10.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.graphics_for(state.ids.zoom_lock_button)
.color(TEXT_COLOR)
.set(state.ids.zoom_lock_label, ui);
// Reset the gameplay settings to the default settings
if Button::image(self.imgs.button)
.w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)

View File

@ -43,8 +43,8 @@ use crate::{
error::Error,
game_input::GameInput,
hud::{
DebugInfo, Event as HudEvent, Hud, HudCollectFailedReason, HudInfo, LootMessage,
PromptDialogSettings,
AutoPressBehavior, DebugInfo, Event as HudEvent, Hud, HudCollectFailedReason, HudInfo,
LootMessage, PromptDialogSettings,
},
key_state::KeyState,
menu::char_selection::CharSelectionState,
@ -61,6 +61,25 @@ use target::targets_under_cursor;
#[cfg(feature = "egui-ui")]
use voxygen_egui::EguiDebugInfo;
/** The zoom scroll delta that is considered an "intent"
to zoom, rather than the accidental zooming that Zoom Lock
is supposed to help.
This is used for both [AutoPressBehaviors::Toggle] and [AutoPressBehaviors::Auto].
This value should likely differ between trackpad scrolling
and various mouse wheels, but we just choose a reasonable
default.
All the mice I have can only scroll at |delta|=15 no matter
how fast, I guess the default should be less than that so
it gets seen. This could possibly be a user setting changed
only in a config file; it's too minor to put in the GUI.
If a player reports that their scroll wheel is apparently not
working, this value may be to blame (i.e. their intent to scroll
is not being detected at a low enough scroll speed).
*/
const ZOOM_LOCK_SCROLL_DELTA_INTENT: f32 = 14.0;
/// The action to perform after a tick
enum TickAction {
// Continue executing
@ -83,6 +102,7 @@ pub struct SessionState {
free_look: bool,
auto_walk: bool,
camera_clamp: bool,
zoom_lock: bool,
is_aiming: bool,
target_entity: Option<specs::Entity>,
selected_entity: Option<(specs::Entity, std::time::Instant)>,
@ -152,6 +172,7 @@ impl SessionState {
free_look: false,
auto_walk: false,
camera_clamp: false,
zoom_lock: false,
is_aiming: false,
target_entity: None,
selected_entity: None,
@ -171,6 +192,24 @@ impl SessionState {
self.key_state.auto_walk = false;
}
/// Possibly lock the camera zoom depending on the current behaviour, and
/// the current inputs if in the Auto state.
fn maybe_auto_zoom_lock(
&mut self,
zoom_lock_enabled: bool,
zoom_lock_behavior: AutoPressBehavior,
) {
if let AutoPressBehavior::Auto = zoom_lock_behavior {
// to add Analog detection, update the condition rhs with a check for
// MovementX/Y event from the last tick
self.zoom_lock = zoom_lock_enabled && self.should_auto_zoom_lock();
} else {
// it's intentional that the HUD notification is not shown in this case:
// refresh session from Settings HUD checkbox change
self.zoom_lock = zoom_lock_enabled;
}
}
/// Gets the entity that is the current viewpoint, and a bool if the client
/// is allowed to edit it's data.
fn viewpoint_entity(&self) -> (specs::Entity, bool) {
@ -406,6 +445,45 @@ impl SessionState {
/// Clean up the session (and the client attached to it) after a tick.
pub fn cleanup(&mut self) { self.client.borrow_mut().cleanup(); }
fn should_auto_zoom_lock(&self) -> bool {
let inputs_state = &self.inputs_state;
for input in inputs_state {
match input {
GameInput::Primary
| GameInput::Secondary
| GameInput::Block
| GameInput::MoveForward
| GameInput::MoveLeft
| GameInput::MoveRight
| GameInput::MoveBack
| GameInput::Jump
| GameInput::Roll
| GameInput::Sneak
| GameInput::AutoWalk
| GameInput::Climb
| GameInput::ClimbDown
| GameInput::SwimUp
| GameInput::SwimDown
| GameInput::SwapLoadout
| GameInput::ToggleWield
| GameInput::Slot1
| GameInput::Slot2
| GameInput::Slot3
| GameInput::Slot4
| GameInput::Slot5
| GameInput::Slot6
| GameInput::Slot7
| GameInput::Slot8
| GameInput::Slot9
| GameInput::Slot10
| GameInput::SpectateViewpoint
| GameInput::SpectateSpeedBoost => return true,
_ => (),
}
}
false
}
}
impl PlayState for SessionState {
@ -547,6 +625,11 @@ impl PlayState for SessionState {
drop(client);
self.maybe_auto_zoom_lock(
global_state.settings.gameplay.zoom_lock,
global_state.settings.gameplay.zoom_lock_behavior,
);
if presence == PresenceKind::Spectator {
let mut client = self.client.borrow_mut();
if client.spectate_position(cam_pos) {
@ -609,7 +692,6 @@ impl PlayState for SessionState {
continue;
}
}
match event {
Event::Close => {
return PlayStateResult::Shutdown;
@ -950,6 +1032,14 @@ impl PlayState for SessionState {
self.key_state.auto_walk =
self.auto_walk && !self.client.borrow().is_gliding();
},
GameInput::ZoomLock => {
if state {
global_state.settings.gameplay.zoom_lock ^= true;
self.hud
.zoom_lock_toggle(global_state.settings.gameplay.zoom_lock);
}
},
GameInput::CameraClamp => {
let hud = &mut self.hud;
global_state.settings.gameplay.camera_clamp_behavior.update(
@ -1032,6 +1122,13 @@ impl PlayState for SessionState {
message: screenshot_message,
}),
Event::Zoom(delta) if self.zoom_lock => {
// only fire this Hud event when player has "intent" to zoom
if delta.abs() > ZOOM_LOCK_SCROLL_DELTA_INTENT {
self.hud.zoom_lock_reminder();
}
},
// Pass all other events to the scene
event => {
self.scene.handle_input_event(event, &self.client.borrow());

View File

@ -3,8 +3,8 @@ use crate::{
controller::ControllerSettings,
game_input::GameInput,
hud::{
BarNumbers, BuffPosition, ChatTab, CrosshairType, Intro, PressBehavior, ScaleChange,
ShortcutNumbers, XpBar,
AutoPressBehavior, BarNumbers, BuffPosition, ChatTab, CrosshairType, Intro, PressBehavior,
ScaleChange, ShortcutNumbers, XpBar,
},
render::RenderMode,
settings::{
@ -68,9 +68,11 @@ pub enum Gameplay {
ChangeFreeLookBehavior(PressBehavior),
ChangeAutoWalkBehavior(PressBehavior),
ChangeCameraClampBehavior(PressBehavior),
ChangeZoomLockBehavior(AutoPressBehavior),
ChangeStopAutoWalkOnInput(bool),
ChangeAutoCamera(bool),
ChangeBowZoom(bool),
ChangeZoomLock(bool),
ResetGameplaySettings,
}
@ -386,6 +388,9 @@ impl SettingsChange {
Gameplay::ChangeCameraClampBehavior(behavior) => {
settings.gameplay.camera_clamp_behavior = behavior;
},
Gameplay::ChangeZoomLockBehavior(state) => {
settings.gameplay.zoom_lock_behavior = state;
},
Gameplay::ChangeStopAutoWalkOnInput(state) => {
settings.gameplay.stop_auto_walk_on_input = state;
},
@ -395,6 +400,9 @@ impl SettingsChange {
Gameplay::ChangeBowZoom(state) => {
settings.gameplay.bow_zoom = state;
},
Gameplay::ChangeZoomLock(state) => {
settings.gameplay.zoom_lock = state;
},
Gameplay::ResetGameplaySettings => {
// Reset Gameplay Settings
settings.gameplay = GameplaySettings::default();

View File

@ -170,6 +170,7 @@ impl ControlSettings {
GameInput::ToggleWield => Some(KeyMouse::Key(VirtualKeyCode::R)),
GameInput::FreeLook => Some(KeyMouse::Key(VirtualKeyCode::L)),
GameInput::AutoWalk => Some(KeyMouse::Key(VirtualKeyCode::Period)),
GameInput::ZoomLock => Some(KeyMouse::Key(VirtualKeyCode::Semicolon)),
GameInput::CameraClamp => Some(KeyMouse::Key(VirtualKeyCode::Apostrophe)),
GameInput::CycleCamera => Some(KeyMouse::Key(VirtualKeyCode::Key0)),
GameInput::Slot1 => Some(KeyMouse::Key(VirtualKeyCode::Key1)),

View File

@ -1,4 +1,4 @@
use crate::hud::PressBehavior;
use crate::hud::{AutoPressBehavior, PressBehavior};
use serde::{Deserialize, Serialize};
/// `GameplaySettings` contains sensitivity and gameplay options.
@ -14,9 +14,11 @@ pub struct GameplaySettings {
pub free_look_behavior: PressBehavior,
pub auto_walk_behavior: PressBehavior,
pub camera_clamp_behavior: PressBehavior,
pub zoom_lock_behavior: AutoPressBehavior,
pub stop_auto_walk_on_input: bool,
pub auto_camera: bool,
pub bow_zoom: bool,
pub zoom_lock: bool,
}
impl Default for GameplaySettings {
@ -31,9 +33,11 @@ impl Default for GameplaySettings {
free_look_behavior: PressBehavior::Toggle,
auto_walk_behavior: PressBehavior::Toggle,
camera_clamp_behavior: PressBehavior::Toggle,
zoom_lock_behavior: AutoPressBehavior::Auto,
stop_auto_walk_on_input: true,
auto_camera: false,
bow_zoom: true,
zoom_lock: false,
}
}
}