NEON-25: follow-up from code review (missing target warn, docs, E1.M2 status)
parent
f4b34316a6
commit
e96f70d889
|
|
@ -3,8 +3,9 @@ extends RefCounted
|
|||
## Client-local camera snapshot for consumers (risk UX, UI, debug). Refreshed each frame by
|
||||
## `isometric_follow_camera.gd`. No `class_name` — see repo Godot headless / CI notes.
|
||||
|
||||
## Orbit yaw (rad) around the follow target **vertical axis**, relative to [member presentation_yaw_deg]
|
||||
## on the rig. Prototype UX keeps this at **0** (`allow_yaw` false). Mid-project orbit would drive this.
|
||||
## Orbit yaw (rad) around the follow target **vertical axis**, **relative to** the rig’s fixed
|
||||
## presentation compass (`presentation_yaw_deg` on `isometric_follow_camera.gd`). This is **not** total
|
||||
## camera compass—only the optional orbit delta. Prototype UX keeps this at **0** (`allow_yaw` false).
|
||||
var yaw: float = 0.0
|
||||
|
||||
## Scene path to the follow anchor (typically `CharacterBody3D` / `Node3D`).
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ var camera_state:
|
|||
var _state = null
|
||||
var _smoothed_eye: Vector3 = Vector3.ZERO
|
||||
var _orbit_yaw_rad: float = 0.0
|
||||
var _warned_missing_follow_target: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
@ -57,6 +58,7 @@ func _ready() -> void:
|
|||
_sync_camera_state(focus0)
|
||||
else:
|
||||
_smoothed_eye = global_position
|
||||
_warn_missing_follow_target_once()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
|
|
@ -64,7 +66,10 @@ func _process(delta: float) -> void:
|
|||
return
|
||||
var target: Node3D = _resolve_target()
|
||||
if target == null:
|
||||
# No eye/state update until the path resolves — avoids chasing a freed or miswired node.
|
||||
_warn_missing_follow_target_once()
|
||||
return
|
||||
_warned_missing_follow_target = false
|
||||
|
||||
if not allow_yaw:
|
||||
_orbit_yaw_rad = 0.0
|
||||
|
|
@ -91,6 +96,7 @@ func _process(delta: float) -> void:
|
|||
|
||||
|
||||
func _sync_camera_state(focus: Vector3) -> void:
|
||||
# `CameraState.yaw` stores **orbit delta** only; world-fixed diagonal framing is `presentation_yaw_deg`.
|
||||
_state.follow_target_path = follow_target_path
|
||||
_state.distance = follow_distance
|
||||
_state.zoom_band_index = 0
|
||||
|
|
@ -107,6 +113,15 @@ func _resolve_target() -> Node3D:
|
|||
return null
|
||||
|
||||
|
||||
func _warn_missing_follow_target_once() -> void:
|
||||
if _warned_missing_follow_target:
|
||||
return
|
||||
_warned_missing_follow_target = true
|
||||
push_warning(
|
||||
"IsometricFollowCamera: follow_target_path is empty or does not resolve to a Node3D; camera not updating."
|
||||
)
|
||||
|
||||
|
||||
static func desired_eye_world(
|
||||
focus: Vector3, distance: float, pitch_elevation_rad: float, yaw_rad: float
|
||||
) -> Vector3:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
| **Module ID** | E1.M2 |
|
||||
| **Epic** | [Epic 1 — Core Player Runtime](../epics/epic_01_core_player_runtime.md) |
|
||||
| **Stage target** | Prototype |
|
||||
| **Status** | Planned (see [dependency register](module_dependency_register.md)) |
|
||||
| **Status** | In progress — follow + `CameraState` baseline shipped ([NEON-25](https://neon-sprawl.atlassian.net/browse/NEON-25)); zoom, occlusion, hardening open ([NEON-26](https://neon-sprawl.atlassian.net/browse/NEON-26)–[NEON-28](https://neon-sprawl.atlassian.net/browse/NEON-28)); see [dependency register](module_dependency_register.md) |
|
||||
| **Jira** | Feature [NEON-10](https://neon-sprawl.atlassian.net/browse/NEON-10); prototype backlog stories under parent [NEON-1](https://neon-sprawl.atlassian.net/browse/NEON-1) — [Jira backlog](#jira-backlog) |
|
||||
|
||||
## Purpose
|
||||
|
|
|
|||
|
|
@ -13,10 +13,12 @@ Fleshed-out scope, contracts, and integration notes live in **per-module documen
|
|||
| Module ID | Module Name | Depends On | Contract Needed | Phase Required | Status |
|
||||
|---|---|---|---|---|---|
|
||||
| E1.M1 | InputAndMovementRuntime | None | MoveCommand, PositionState, InteractionRequest | Prototype | Ready |
|
||||
| E1.M2 | IsometricCameraController | E1.M1 | CameraState, ZoomBandConfig, OcclusionPolicy | Prototype | Planned |
|
||||
| E1.M2 | IsometricCameraController | E1.M1 | CameraState, ZoomBandConfig, OcclusionPolicy | Prototype | In progress |
|
||||
| E1.M3 | InteractionAndTargetingLayer | E1.M1 | TargetState, InteractableDescriptor, SelectionEvent | Prototype | Planned |
|
||||
| E1.M4 | AbilityInputScaffold | E1.M3, E5.M1 | AbilityCastRequest, HotbarLoadout, CooldownSnapshot | Prototype | Planned |
|
||||
|
||||
**E1.M2 note:** Client follow rig + per-tick `CameraState` baseline is in repo ([NEON-25](https://neon-sprawl.atlassian.net/browse/NEON-25)). Discrete zoom bands, occlusion policy, and integration hardening remain ([NEON-26](https://neon-sprawl.atlassian.net/browse/NEON-26)–[NEON-28](https://neon-sprawl.atlassian.net/browse/NEON-28)).
|
||||
|
||||
### Epic 2 — Skills and Progression Framework
|
||||
|
||||
| Module ID | Module Name | Depends On | Contract Needed | Phase Required | Status |
|
||||
|
|
|
|||
Loading…
Reference in New Issue