chore: add macOS trackpad scroll and pinch camera zoom.
Map InputEventPanGesture and InputEventMagnifyGesture to the existing discrete zoom bands; document in client README. Unrelated to NEO-93. Co-authored-by: Cursor <cursoragent@cursor.com>pull/131/head
parent
056b0e77f0
commit
90e6cfea28
|
|
@ -284,7 +284,7 @@ On **Linux** (including GitHub Actions), the path must be **`gdUnit4`** with a c
|
|||
|
||||
**Scope:** Unit tests cover **`player.gd`**, **`player_locomotion_wasd.gd`** (pure WASD seam helpers), **`position_authority_client.gd`**, **`inventory_client.gd`**, **`item_definitions_client.gd`** (NEO-72), **`skill_progression_client.gd`**, **`gig_progression_client.gd`** (NEO-86), **`prototype_interactable_picker.gd`**, extended **`interaction_request_client_test.gd`**, **`gather_feedback_refresh_test.gd`** (NEO-73), **`craft_client.gd`**, **`recipe_definitions_client.gd`**, **`craft_feedback_refresh_test.gd`** (NEO-74), **`prototype_economy_hud_section.gd`** (NEO-75), **`combat_targets_client.gd`**, **`combat_feedback_refresh_test.gd`** (NEO-85), **`gig_feedback_refresh_test.gd`** (NEO-86), **`isometric_follow_camera.gd`** (eye math + effective zoom distance), **`camera_state.gd`**, and **`zoom_band_config.gd`**. **`main.gd`** and scene wiring are **not** automated here—use manual checks above.
|
||||
|
||||
**Camera zoom:** Input actions **`camera_zoom_in`** / **`camera_zoom_out`** (mouse wheel, **`=`** / **`-`**, keypad **+** / **−**) are defined in **`project.godot`**. On layouts where **`+`** requires **Shift**, remap or add a binding under **Project → Project Settings → Input Map** if needed.
|
||||
**Camera zoom:** Input actions **`camera_zoom_in`** / **`camera_zoom_out`** (mouse wheel, **`=`** / **`-`**, keypad **+** / **−**) are defined in **`project.godot`**. **`isometric_follow_camera.gd`** also maps **macOS trackpad** two-finger scroll ([`InputEventPanGesture`](https://docs.godotengine.org/en/stable/classes/class_inputeventpangesture.html)) and pinch ([`InputEventMagnifyGesture`](https://docs.godotengine.org/en/stable/classes/class_inputeventmagnifygesture.html)) to the same discrete zoom bands. On layouts where **`+`** requires **Shift**, remap or add a binding under **Project → Project Settings → Input Map** if needed.
|
||||
|
||||
**Dev (NEO-18):** **`dev_toggle_occluder_obstacle`** (default **Ctrl+Shift+K**) toggles the prototype `Obstacle` visibility/collision in **`main.gd`**. **F9** / **F10** are used by the embedded debugger; use this action instead when the game is running in the editor.
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,11 @@ extends Node3D
|
|||
## [signal zoom_band_changed] when schema exists; optional occlusion/perf counters per module doc.
|
||||
signal zoom_band_changed(new_index: int, distance: float)
|
||||
|
||||
const CameraStateScript := preload("res://scripts/camera_state.gd")
|
||||
## Minimum |delta.y| before a pan gesture advances one zoom band (macOS trackpad).
|
||||
const PAN_ZOOM_DELTA_THRESHOLD: float = 0.05
|
||||
|
||||
## Magnify factor must exceed 1.0 ± this before one zoom band step (trackpad pinch).
|
||||
const MAGNIFY_ZOOM_FACTOR_EPSILON: float = 0.02
|
||||
const ZoomBandConfigScript := preload("res://scripts/zoom_band_config.gd")
|
||||
const OcclusionPolicyScript := preload("res://scripts/occlusion_policy.gd")
|
||||
|
||||
|
|
@ -128,12 +132,46 @@ func _exit_tree() -> void:
|
|||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_echo():
|
||||
return
|
||||
var pan_step: int = zoom_step_from_pan_gesture(event)
|
||||
if pan_step != 0:
|
||||
_apply_zoom_step(pan_step)
|
||||
return
|
||||
var magnify_step: int = zoom_step_from_magnify_gesture(event)
|
||||
if magnify_step != 0:
|
||||
_apply_zoom_step(magnify_step)
|
||||
return
|
||||
if event.is_action_pressed("camera_zoom_in"):
|
||||
_apply_zoom_step(-1)
|
||||
elif event.is_action_pressed("camera_zoom_out"):
|
||||
_apply_zoom_step(1)
|
||||
|
||||
|
||||
## Maps macOS trackpad two-finger scroll to a discrete zoom band step, or **0** when ignored.
|
||||
static func zoom_step_from_pan_gesture(event: InputEvent) -> int:
|
||||
if event == null or not event is InputEventPanGesture:
|
||||
return 0
|
||||
var pan: InputEventPanGesture = event as InputEventPanGesture
|
||||
if absf(pan.delta.y) <= absf(pan.delta.x):
|
||||
return 0
|
||||
if pan.delta.y <= -PAN_ZOOM_DELTA_THRESHOLD:
|
||||
return -1
|
||||
if pan.delta.y >= PAN_ZOOM_DELTA_THRESHOLD:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
## Maps trackpad pinch ([InputEventMagnifyGesture]) to a discrete zoom band step, or **0**.
|
||||
static func zoom_step_from_magnify_gesture(event: InputEvent) -> int:
|
||||
if event == null or not event is InputEventMagnifyGesture:
|
||||
return 0
|
||||
var mag: InputEventMagnifyGesture = event as InputEventMagnifyGesture
|
||||
if mag.factor >= 1.0 + MAGNIFY_ZOOM_FACTOR_EPSILON:
|
||||
return -1
|
||||
if mag.factor <= 1.0 - MAGNIFY_ZOOM_FACTOR_EPSILON:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
## **Near** = lower band index. Zoom in → closer → decrease index (clamped).
|
||||
func _apply_zoom_step(delta_bands: int) -> void:
|
||||
if not _zoom_config_valid():
|
||||
|
|
|
|||
|
|
@ -138,3 +138,44 @@ func test_occluder_override_key_is_valid_false_after_free() -> void:
|
|||
var ok: bool = IsoScript.occluder_override_key_is_valid(n)
|
||||
# Assert
|
||||
assert_that(ok).is_false()
|
||||
|
||||
|
||||
func test_zoom_step_from_pan_gesture_ignores_non_pan() -> void:
|
||||
# Arrange
|
||||
var key := InputEventKey.new()
|
||||
# Act
|
||||
var step: int = IsoScript.zoom_step_from_pan_gesture(key)
|
||||
# Assert
|
||||
assert_that(step).is_equal(0)
|
||||
|
||||
|
||||
func test_zoom_step_from_pan_gesture_maps_vertical_scroll_to_bands() -> void:
|
||||
# Arrange
|
||||
var scroll_up := InputEventPanGesture.new()
|
||||
scroll_up.delta = Vector2(0.0, -0.2)
|
||||
var scroll_down := InputEventPanGesture.new()
|
||||
scroll_down.delta = Vector2(0.0, 0.2)
|
||||
var horizontal := InputEventPanGesture.new()
|
||||
horizontal.delta = Vector2(0.2, 0.0)
|
||||
# Act
|
||||
var up_step: int = IsoScript.zoom_step_from_pan_gesture(scroll_up)
|
||||
var down_step: int = IsoScript.zoom_step_from_pan_gesture(scroll_down)
|
||||
var horiz_step: int = IsoScript.zoom_step_from_pan_gesture(horizontal)
|
||||
# Assert
|
||||
assert_that(up_step).is_equal(-1)
|
||||
assert_that(down_step).is_equal(1)
|
||||
assert_that(horiz_step).is_equal(0)
|
||||
|
||||
|
||||
func test_zoom_step_from_magnify_gesture_maps_pinch_to_bands() -> void:
|
||||
# Arrange
|
||||
var pinch_in := InputEventMagnifyGesture.new()
|
||||
pinch_in.factor = 0.9
|
||||
var pinch_out := InputEventMagnifyGesture.new()
|
||||
pinch_out.factor = 1.1
|
||||
# Act
|
||||
var in_step: int = IsoScript.zoom_step_from_magnify_gesture(pinch_in)
|
||||
var out_step: int = IsoScript.zoom_step_from_magnify_gesture(pinch_out)
|
||||
# Assert
|
||||
assert_that(in_step).is_equal(1)
|
||||
assert_that(out_step).is_equal(-1)
|
||||
|
|
|
|||
Loading…
Reference in New Issue