Asset Dump
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
---
|
||||
date: 2026-06-03
|
||||
type: session
|
||||
tags: [session, input, controls, aiming, gamepad, netcode, presentation]
|
||||
---
|
||||
|
||||
# Session 2026-06-03 — Aim controls: mouse cursor + gamepad twin-stick
|
||||
|
||||
## Goal
|
||||
|
||||
Fix janky aiming: on mouse+keyboard show a cursor and make the character **face/fire toward the cursor** (instead of only along movement), **preserve gamepad** support, and research how V Rising / similar do KBM+gamepad. Operator forks (asked up front): **per-scheme native** reticle (KBM crosshair + gamepad world ring) and **precise mouse / gamepad-only auto-aim**.
|
||||
|
||||
## Done
|
||||
|
||||
- **Root-caused** the jank: `PlayerInput.Aim` was bound only to `<Gamepad>/rightStick`; KBM had no aim path → `PlayerAimSystem` fell back to the movement heading.
|
||||
- **Mouse cursor aim** wired in `PlayerInputGatherSystem` (client): cursor → `Camera.main.ScreenPointToRay` → `AimMath.PlanarAimFromRay` (new pure, Burst-safe, unit-tested) → player→cursor direction written to the existing `PlayerInput.Aim` `[GhostField]`. **No new ghost/netcode surface**; strafe-while-aiming is free (movement already decoupled from facing).
|
||||
- **Active-scheme detection** (last-meaningful-actuation-wins, deadzone + `lastUpdateTime` tiebreak) → new replicated **`byte PlayerInput.Scheme`** (`InputSchemeId`, byte not enum for Burst).
|
||||
- **Auto-target gated to gamepad** in `AbilityFireSystem` (precise mouse): cone applied only when `applied.InternalInput.Scheme == Gamepad`.
|
||||
- **Per-scheme presentation** in new `AimReticleSystem` (client `PresentationSystemGroup`, asset-free): KBM procedural crosshair cursor; gamepad hidden cursor + flat world reticle ring along replicated `PlayerFacing`. Static bridge `AimPresentation.Scheme` (resets on play-enter). `DebugInputInjectionSystem` stamps `Scheme` for editor validation.
|
||||
- **Validation:** compile/Burst clean, 0 new warnings, **EditMode 81/81** (7 new `AimMathTests`). Runtime: worlds boot, no exceptions, `Scheme` replicates to server (`=1`), `Aim=(1,0)`→server `Facing=(1,0)`, reticle activates/flat/positioned/material, cursor hides on gamepad.
|
||||
- **Adversarial review workflow** (5 dims, verified): 5 confirmed / 5 rejected → fixed the static-reset (major), `Shader.Find` guard, debug-injection scheme sync; declined the `mainTexture` nit (verified correct).
|
||||
|
||||
## Decisions
|
||||
|
||||
- [[DR-012_Aim_Controls_Cursor_Gamepad]] — client-derived cursor aim on the existing `[GhostField]` direction; replicated `byte Scheme` gates gamepad-only assist; per-scheme native cursor/reticle; reset-static-presentation-bridge idiom.
|
||||
|
||||
## Refinement — world-space cursor (follow-up)
|
||||
|
||||
After the first pass landed and tested well, the operator asked to make KBM aiming feel more natural / world-space. A research workflow (V Rising action-mode cursor-hide, Last Epoch / PoE2 / Diablo, TopDown Engine `ReplaceMousePointer`, dual-stick feel) confirmed the perspective-mismatch artifact (a flat screen crosshair sits visually *above* the angled ground point it targets) and recommended **reticle-only**.
|
||||
|
||||
- **KBM now shows the world ground ring at the cursor's ground-projection point** — re-raycast **inside `AimReticleSystem`** (PresentationSystemGroup runs after the camera's LateUpdate move, so the ring tracks the cursor with no 1-frame follow-cam drift), NOT latched from the gather. The screen crosshair is gone; the OS cursor is hidden while aiming + focused and restored on focus-loss/destroy. New pure `AimMath.TryGroundHit` returns the world point; last valid point held on a miss.
|
||||
- **Radial dead-zone** (`AimMath.PlanarAimFromRay` `deadZoneRadius`, 0.6u in the gather) holds facing when the cursor is over/near the character (no spin).
|
||||
- **Camera look-ahead** — `PrototypeCameraRig.AimLeadDistance` (tunable, default 2.5u, 0 = off) leads the framed point toward the replicated `PlayerFacing` (driven off facing, not the cursor projection → no feedback loop); `PrototypeCameraTargetSystem` now publishes `TargetFacing`.
|
||||
- Validated: EditMode **86/86** (5 new AimMath tests), console clean; runtime KBM ring active at the cursor ground point, OS cursor hidden when focused, `TargetFacing` published, no exceptions.
|
||||
|
||||
## Open / deferred
|
||||
|
||||
- Real mouse-cursor path + live KBM↔gamepad auto-switch need a **focused** Game view (unfocused editor can't inject mouse position); operator focused click-test pending. Headless validation covered math/replication/gate/reticle.
|
||||
- Auto-target priority/feel tuning; optional controller soft-target reticle snap; rebindable controls; multi-ability slots.
|
||||
|
||||
## Next
|
||||
|
||||
- Operator focused click-test of cursor aim + device switching; then consider ability-slot expansion or controller aim-assist tuning.
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
date: 2026-06-03
|
||||
type: session
|
||||
tags: [session, dots, netcode, art, synty, urp, vfx, presentation, environment, world, visual]
|
||||
permalink: gamevault/07-sessions/2026/2026-06-03-synty-world-and-vfx
|
||||
---
|
||||
|
||||
# Session 2026-06-03 (B) — Synty grounded world + GabrielAguiar VFX
|
||||
|
||||
## Goal
|
||||
|
||||
Second art pass (after [[2026-06-03_Visual_Upgrade_HomeBase]]). Operator: "implement the VFX (now imported), change the world to be **not a floating plane** — make it feel grounded (terrain or otherwise), deepen the environment; I imported a ton of Synty packs — inventory and use them; whatever works best; **it should all look cohesive**." Two forks were resolved by the operator: **go full Synty** (cohesive — retire the BefourStudios base) and **keep primitives** for player/enemies (DOTS has no easy skeletal animation; static rigged meshes would slide as T-poses). Locked in [[DR-011_Synty_World_VFX_Integration]].
|
||||
|
||||
## Inventory (what landed)
|
||||
|
||||
- **GabrielAguiar VFX — now extracted:** 499 prefabs + 27 `.vfx`. **472/499 are Shuriken ParticleSystems** (pool/instantiate-friendly), URP-compatible; only the HitsImpactsV2 + beams are VFX Graph (deferred). Packs: Magic Abilities, Projectiles Vol2/3, SciFi Vol1, Stylized Explosions.
|
||||
- **Synty — 6 POLYGON packs**, all **URP-native** (`Synty/Generic_Basic` etc — no HDRP→URP conversion). `SciFiCity + SciFiSpace + Mech` = a fully cohesive flat-shaded sci-fi set (buildings, walls, landing pads, **14 planets + asteroids** for a horizon, hangar floors, characters); `Generic` = ground/cliffs (earth-toned); `DungeonRealms` = fantasy (clashes, skip); `ParticleFX` = extra particles.
|
||||
|
||||
## Process
|
||||
|
||||
- 3 read-only Explore agents inventoried VFX, Synty, and the current scene/VFX hook points; 2 operator forks via `AskUserQuestion`.
|
||||
- **Implementation sequential via MCP** (single editor). World built as **classic-URP cosmetic GameObjects in SampleScene** — sidesteps the Synty-shader-in-Entities-Graphics question entirely (only the gameplay subscene needs EG/physics).
|
||||
- **Adversarial review workflow (3 lenses)** over the diff — caught a real blocker (below) + perf notes; all fixed/verified.
|
||||
|
||||
## Done
|
||||
|
||||
- **Retired BefourStudios from the subscene** — deleted the `EnvDecor` root (13 props); **disabled** `Wall_North`/`Wall_East`/`Pillar_Center` MeshRenderers while **keeping their BoxColliders** (gameplay collision intact, no invisible RenderMesh); disabled the old grey `Ground` renderer. Subscene re-bakes dome-less on Play.
|
||||
- **Grounded Synty world** (`SyntyWorld` root in SampleScene, ~60 cosmetic objects): large Synty ground plane (top at y=0), a 16-tile paved tech plaza over the play area, a **16-building skyline ring** (facing centre) + perimeter city walls/tower for depth, **boundary barriers aligned to the collision walls**, scattered props (crates/pipes/light-bars/antenna/landing-pad), a **planet on the horizon** + asteroid field, a Synty **space skybox** (`Skybox/6 Sided`), brighter flat ambient + light fog. Kills the floating-plane: it reads as a colony on a planet under a nebula.
|
||||
- **GabrielAguiar VFX wired into combat** — new `VFXConfig` MonoBehaviour bridge (`ProjectM.Client`, static `Instance`, 5 prefab slots; mirrors `PrototypeCameraRig`) on a SampleScene object, assigned cyan-energy muzzle/trail/hit + orange stylized explosions for death. `CombatFeedbackSystem` now `Burst()`es the authored prefab at each hook (muzzle/hit/enemy-death/player-death) with the procedural ParticleSystem as fallback, plus `UpdateProjectileTrails` (a trail GameObject follows each projectile ghost, pruned on despawn). Verified: blue hit VFX fires on husk-on-player contact, no errors.
|
||||
|
||||
## Validation
|
||||
|
||||
- **EditMode 74/74** (unchanged). Both worlds boot, **11 ghosts replicate**; the re-bake correctly drops the dome; **player collision with the (now-invisible) subscene walls intact**; the world reads as a cohesive grounded Synty sci-fi colony (hero shot `Assets/Screenshots/synty_hero_final.png`); **hit VFX visibly fires** with no console errors (only the unfocused-editor tick-batching warning). Cosmetic Synty world has **zero** sim/netcode/physics impact (classic PhysX colliders are separate from the baked DOTS PhysicsWorld; nothing in SampleScene is a ghost).
|
||||
- **Adversarial review (3 lenses):** **1 blocker + perf findings, all fixed** (below); the scene/netcode isolation reasoning verified end-to-end.
|
||||
|
||||
## Review fixes (this session)
|
||||
|
||||
- **BLOCKER — the `ProjectileTrail` prefab was a GA demo *projectile*, not a passive trail** (`vfx_Projectile_Orb01_Blue` ships a non-kinematic Rigidbody + collider + `ProjectileMoveScript` speed 25). Instantiated per projectile, it self-propelled (fighting the per-frame reposition), collided with classic scene colliders, and spawned secondary muzzle/hit VFX. **Fixed** with `StripCosmetic()` — strips `Rigidbody`/`Collider` and disables any `Projectile`/`Move`-named MonoBehaviour (before its `Start` runs) on every spawned VFX, so only the ParticleSystems remain. Future-proofs all VFX slots.
|
||||
- **TTL** now derived from the prefab's longest ParticleSystem (`main.duration + startLifetime`, clamped 1–6 s) instead of a blanket 3 s; **`MaxActiveVfx=40`** caps one-shot VFX churn under swarms; trails are cleared if `VFXConfig` goes null mid-run.
|
||||
- Verified single active global Volume; the lone modified PDF `.meta` is the operator's GA import artifact (not ours).
|
||||
|
||||
## Diagnosis notes (for future me / future Synty packs)
|
||||
|
||||
- **Synty is URP-native — no conversion** (unlike the HDRP BefourStudios art). Place Synty as **classic-URP GameObjects in SampleScene** (cosmetic, client-only) and the custom `Synty/Generic_Basic` shader just renders; only the gameplay subscene needs Entities Graphics + physics. This sidesteps verifying Synty-shader DOTS-instancing.
|
||||
- **"Grounded" = surround + horizon, not a bigger plane.** A skyline ring of tall buildings + a planet/asteroid backdrop + a space skybox + fog killed the floating-plane far better than extending the ground; the ground edge curving to a starfield reads as a planetoid surface.
|
||||
- **A GA "projectile" prefab is NOT a trail** — it's a self-moving demo with physics + secondary-VFX spawns. Any authored VFX dropped into a cosmetic slot must be **stripped to particles** (kill Rigidbody/Collider/mover). Same "grabbed the wrong prefab kind" trap as last pass's HDRP-vs-trail material bug — verify the prefab's components, not just its name.
|
||||
- **Disabled MeshRenderer + kept BoxCollider** in a subscene = invisible wall with collision (collider still bakes to the static PhysicsCollider; no RenderMesh entity). The clean way to keep gameplay bounds while swapping the visual to another scene/style.
|
||||
- **Cosmetic SampleScene colliders are inert to gameplay** — they live in classic PhysX, separate from the DOTS PhysicsWorld baked from the subscene; the planar-pinned CC never sees them. So a cosmetic world needs no collider stripping for *gameplay* (only stripped on VFX to stop demo movers).
|
||||
- **VFX prefab bridge pattern:** a `MonoBehaviour` with a static `Instance` + prefab fields (assigned in the bootstrap scene) is the clean way to hand authored assets to a managed client `SystemBase` — mirrors `PrototypeCameraRig`. Keep a procedural fallback so a null slot still runs.
|
||||
- **Projectile-follow VFX:** query `SystemAPI.Query<RefRO<LocalTransform>>().WithAll<Projectile>()` client-side each presentation frame; dict-by-`Entity` spawn/reposition/prune (same idiom as the Health cache). Destroy the trail when the projectile entity vanishes.
|
||||
- **One-shot Fire still drops under the unfocused editor** — so muzzle / projectile-trail / enemy-death VFX (which need the player to fire/kill) weren't visually fired this session; they use the same verified `SpawnVfx` path as the confirmed hit VFX. Confirm with a focused editor or a real client.
|
||||
|
||||
## Open / deferred
|
||||
|
||||
- **Confirm fire-driven VFX visually** (muzzle, projectile trail, enemy-death explosion) with a focused editor / real client.
|
||||
- **Ghost-prop cohesion gap:** Storage/UpgradePickup ghosts still use the BefourStudios converted meshes/materials (they render via Entities Graphics; a Synty mesh there would need the Synty shader's DOTS-instancing verified). Reskin to flat Synty-style or simple emissive later.
|
||||
- **Orphaned `Materials/Env/` (BefourStudios)** — the decorative converted materials are now unused (EnvDecor deleted); a few are still referenced by the ghosts/hidden walls. Prune the truly-orphaned ones in a cleanup pass.
|
||||
- **Characters** — player/enemies remain primitives; revisit with DOTS skeletal animation as its own task (Synty has crew/alien/mech meshes ready).
|
||||
- **Perf**: top-down Bloom + ~60 Synty objects + a 300-unit planet — fine in-editor; budget bloom + confirm frustum/distance culling for a build. VFX Graph hit/beam packs need separate URP setup if wanted.
|
||||
- **Mixed-theme arena** — BioHorror/Synty corrupted zones for danger areas (deferred from the scope gate).
|
||||
|
||||
## Next
|
||||
|
||||
Confirm the fire-driven VFX with a focused editor, then either polish (ghost-prop reskin + orphaned-material prune + a reflection probe) or resume the milestone track. The Synty-in-SampleScene world pattern + the `VFXConfig` bridge generalize to all future packs.
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
date: 2026-06-03
|
||||
type: session
|
||||
tags: [session, dots, netcode, art, urp, entities-graphics, materials, presentation, home-base, visual]
|
||||
permalink: gamevault/07-sessions/2026/2026-06-03-visual-upgrade-homebase
|
||||
---
|
||||
|
||||
# Session 2026-06-03 — Art import + home-base visual upgrade (Synty/BefourStudios → URP)
|
||||
|
||||
## Goal
|
||||
|
||||
The operator imported a large art/VFX asset bundle (commit `e362aae`, ~4,830 files) and asked to **inventory it and use it to make the project look visually better**, with more Synty packs coming later. Scope was set via a 4-question gate: **render pass + curated home-base dressing**, enemies/player stay primitives (no character meshes in these packs), VFX deferred, theme = **clean orbital base**. Locked in [[DR-010_Art_Import_URP_Conversion_Visual_Upgrade]].
|
||||
|
||||
## Inventory (what was actually imported)
|
||||
|
||||
- **BefourStudios/Art** (orbital-base modular kit — domes, batteries, crates, plants, modular blocks, lights, solar, storage), **/SciFiEngineersRoom** (interior), **/BioHorrorSciFiEnvironment** (organic/decay). ~560 prefabs, hundreds of FBX + PBR textures (`T_*_B/_N/_ORM`).
|
||||
- **GabrielAguiarProductions VFX = NOT in the repo** — only 3 PDF docs committed; zero `.unitypackage`/`.vfx`/prefabs. VFX deferred until imported.
|
||||
- **No character meshes anywhere** — packs are environment/props only.
|
||||
- **Pipeline mismatch:** the art is **HDRP-authored** (`Shader Graphs/S_General`, HDRP/Lit; `_DISABLE_SSR_TRANSPARENT`, `RayTracingPrepass`) while the project runs **URP 17.4 + Entities Graphics** → source materials render **magenta** under URP. Meshes + textures are fully usable; materials must be re-authored to stock URP/Lit (`933532a4…`, the same shader the project's working prototypes use → Entities-Graphics-compatible). Blank auto-generated `MI_*` URP stubs exist but carry no textures.
|
||||
|
||||
## Process
|
||||
|
||||
- **Plan-gated** (read-only): 3 Explore agents inventoried the packs + current visual/render setup; a Plan agent pressure-tested the execution sequence (corrected several of my assumptions by reading files). Operator approved.
|
||||
- **Implementation = sequential via MCP** (single editor, domain-reload-ordered; NOT a parallel swarm): a reusable Editor converter, ghost-prefab mesh swaps (PrefabUtility round-trip), subscene dressing (open additive → place → save → re-bake), and a SampleScene render pass.
|
||||
- **Adversarial review workflow (3 lenses: code / netcode / conventions)** over the diff. It **earned its keep** — caught 2 blockers + 1 major that the dark lighting masked in the screenshot. All fixed; minors triaged.
|
||||
|
||||
## Done
|
||||
|
||||
- **`Assets/_Project/Scripts/Editor/EnvArtTools.cs`** (new; Assembly-CSharp-Editor, `#if UNITY_EDITOR`) — reusable HDRP→URP material converter for future packs. Reads source texture refs across HDRP/Lit + ShaderGraph property names (`_BaseColorMap`/`_BaseTexture`→`_BaseMap`, `_NormalMap`/`_NormalTexture`→`_BumpMap`), **type-guards every color/float/texture read** (verify `ShaderPropertyType` before `GetColor`/`GetFloat`), low metallic (no reflection probe ⇒ high-metallic reads black), source-flag-gated emission, alpha-clip from source flags. `ConvertCurated()` menu item + `RemapRenderersToEnv(go)`. GUID-preserving overwrite (refs survive re-runs). Outputs to `Assets/_Project/Materials/Env/` (20 materials).
|
||||
- **Ghost prop mesh swaps** — `Storage.prefab` → `SM_Storage_LOD0` (scale 0.6), `UpgradePickup.prefab` → `SM_Battery_LOD0` + emissive `M_Env_PickupGlow` (scale 2.5). GhostAuthoring/LinkedEntityGroup/gameplay authoring preserved; only mesh+material+scale changed.
|
||||
- **Two server spawners patched to preserve baked scale** (`UpgradePickupSpawnSystem`, `SharedStorageSpawnSystem`): `LocalTransform.FromPosition()` hard-sets Scale=1, which silently discarded the prefab scale — now they read the prefab's baked `LocalTransform` and only override Position.
|
||||
- **Gameplay subscene dressed** — `EnvDecor` root of 13 collider-stripped, unpacked static props (dome backdrop, modular blocks, batteries/charger, crates, plants, light poles, solar panels) with URP materials; existing `Wall_North/East`/`Pillar_Center` re-skinned (colliders/positions kept) with tiled `M_Env_Wall`. No GhostAuthoring on scenery.
|
||||
- **SampleScene render pass** — cool key light @1.45–1.75; dark-space procedural skybox; flat dark ambient; exp fog @0.006 (keeps the z=26 dome visible); `Ground` re-skinned to tiled `M_Env_Floor`; **`PostFX_DarkSciFi` profile populated** (Bloom / ACES Tonemapping / ColorAdjustments / Vignette) and made the single active global volume (overlapping `GlobalPostFX` disabled).
|
||||
|
||||
## Validation
|
||||
|
||||
- **EditMode 74/74 green** (unchanged; the spawner edits compiled clean — note: EditMode test *init* timed out once on the unfocused editor, passed on retry with `init_timeout=180000`).
|
||||
- **Runtime (single in-editor client, 6.4.7):** both worlds boot, **11 ghosts replicate** server↔client; player input → prediction → replication works and the **character is blocked by the east wall** (static PhysicsWorld survived the dressing); ghost **scales now apply** (Storage 0.60, pickups 2.50, others 1.0). Console clean of code/Burst/material/bake errors (only "Server Tick Batching" warnings — the documented unfocused-editor symptom; decor adds **zero** server-sim load). Screenshots `Assets/Screenshots/result_clean_base.png` (after) vs `baseline_editmode.png` (before) confirm the jump.
|
||||
- **Adversarial review (3 lenses):** **2 blockers + 1 major, all fixed** (below); remaining findings are minor/future-pack robustness, addressed or noted.
|
||||
|
||||
## Diagnosis notes (for future me / future Synty packs)
|
||||
|
||||
- **The art is HDRP, the project is URP.** Source `M_*` materials render magenta. Convert to **stock URP/Lit** via `EnvArtTools` (do NOT switch the project to HDRP — it would break Entities Graphics). Meshes + `_B/_N/_ORM` textures are reusable as-is.
|
||||
- **A screenshot under dark lighting MASKS material bugs.** The adversarial review caught a **black-`_BaseColor` blocker** on ~16/20 materials: `HasProperty("_BaseColorMultiply")` was true (it's a *float* on `S_General`), `GetColor()` on a float returns (0,0,0) and logs a "doesn't have a color property" warning — the very warning I'd dismissed as cosmetic. **Always `shader.GetPropertyType(idx)`-guard before `GetColor`/`GetFloat`;** the real tint is `_AlbedoTint`. Verify material *values*, not just the render.
|
||||
- **Source emission needs the `_Emissive` (0/1) flag gate.** `S_General` carries a non-zero default `_EmissiveColor` even when emission is off → reading the color unconditionally made crates/dome/walls glow. Emit only when `_Emissive>0.5` AND the name marks a light fixture; flat color emission can't reproduce the source's emission mask anyway.
|
||||
- **`VolumeProfile.Add<T>()` does NOT persist the override as a sub-asset** — on save the `components` list serializes 4 `{fileID:0}` nulls (works in-session, gone after reload). Must `AssetDatabase.AddObjectToAsset(component, profile)` for each, then `SaveAssets`. Verify on disk (non-null refs + N+1 MonoBehaviour blocks).
|
||||
- **`LocalTransform.FromPosition()` resets Scale to 1** — any ghost spawned via it ignores its prefab's authored scale (and Scale *is* a replicated `[GhostField]`, so it's consistent-but-wrong, not a desync). Read the prefab's baked `LocalTransform` and override only Position to keep authored scale.
|
||||
- **High metallic + no reflection probe + dark skybox = near-black surfaces.** Keep converted env metallic low (0.1–0.2); rely on albedo + direct light. (A baked reflection probe would let metallic read correctly later.)
|
||||
- **Metallic without reflections looked "too dark" before the tint bug was even found** — two compounding causes (black albedo + high metallic); fixing both gave a bright, readable base.
|
||||
- **Editing a subscene via MCP:** `manage_scene load … additive` opens the authoring scene (the baked-entity view it was showing goes away — empty game view is expected), edit + `SaveScene`, then `close_scene` so the SubScene re-bakes from the saved file on Play. Verify placement via `execute_code` enumerating the scene roots, not the game view.
|
||||
- **HUD-free beauty shot:** a **positioned `game_view` capture** (`view_position`/`view_rotation`) uses direct camera rendering, which *excludes* Screen-Space-Overlay UI — so the gameplay death overlay doesn't bleed into the render. (`scene_view` rejects positioned capture.)
|
||||
- **`execute_code` is a method body** (no usings; fully-qualify). Reusable converter logic belongs in a committed Editor script, not repeated `execute_code` blobs — the operator is importing more packs.
|
||||
|
||||
## Open / deferred
|
||||
|
||||
- **VFX** — import the GabrielAguiar `.unitypackage`s, then wire the **Shuriken** packs (projectiles/explosions/shields/auras) into the existing client `ParticleSystem` pool; the **VFX Graph** packs (hits/beams) need separate URP setup.
|
||||
- **Characters** — player/enemies are still primitives; swap for real models when a character/Synty pack arrives (the prefab+material pattern generalizes).
|
||||
- **Decor LODs bake into both worlds** — the 13 props' full LOD hierarchies are in the shared subscene, so the server carries renderable+`MeshLODGroup` entities for nothing. For more decor, move pure cosmetics to a client-only/cosmetic subscene or flatten to LOD0.
|
||||
- **Higher material fidelity** — current converter uses uniform metallic/smoothness (ORM channels don't map to URP); a per-channel ORM→URP repack (or a small ORM ShaderGraph) + a baked reflection probe would deepen the look.
|
||||
- **More dressing** — mine `S_OrbitalBase.unity` for a fuller layout once the pipeline is proven; the BioHorror pack fits future "corrupted" arena zones (mixed-theme option from the scope gate).
|
||||
|
||||
## Next
|
||||
|
||||
Either **import + wire the VFX** (biggest feel win, needs the operator to import the packs) or **deepen the environment** (more orbital-base dressing + a reflection probe + ORM fidelity). The reusable `EnvArtTools` converter + the duplicate-and-reskin prefab pattern are the foundation for every future Synty pack.
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
id: DR-010
|
||||
title: Art import + home-base visual upgrade — HDRP→URP material conversion pipeline for Synty/BefourStudios packs
|
||||
status: accepted
|
||||
date: 2026-06-03
|
||||
tags:
|
||||
- decision
|
||||
- art
|
||||
- urp
|
||||
- entities-graphics
|
||||
- materials
|
||||
- presentation
|
||||
- home-base
|
||||
- tooling
|
||||
permalink: gamevault/07-sessions/decisions/dr-010-art-import-urp-conversion-visual-upgrade
|
||||
---
|
||||
|
||||
# DR-010 — Art import + home-base visual upgrade (HDRP→URP conversion pipeline)
|
||||
|
||||
## Context
|
||||
|
||||
The operator imported a large art/VFX asset bundle (commit `e362aae`, ~4,830 files: BefourStudios orbital-base + sci-fi-interior + bio-horror kits, plus GabrielAguiar VFX) and asked to inventory it and **make the project look better**, with more Synty packs coming. The project ([[Identity]] sci-fi frontier colony, see [[DR-009_GameFeel_Identity_FirstBlood]]) was a primitive-shape debug scene under a cool URP post-FX look. Inventory surfaced three constraints that shaped everything:
|
||||
|
||||
1. **The art is HDRP-authored; the project is URP 17.4 + Entities Graphics.** BefourStudios props reference `Shader Graphs/S_General` and HDRP/Lit (`_DISABLE_SSR_TRANSPARENT`, `RayTracingPrepass`, `_BaseColorMultiply`/`_AlbedoTint`/`_Emissive` props) → they render **magenta** under URP. The **meshes + PBR textures** (`T_*_B/_N/_ORM`) are fully usable; the auto-generated `MI_*` URP material stubs are blank.
|
||||
2. **The VFX packs were never extracted** — only 3 PDF docs are committed (no `.unitypackage`/`.vfx`/prefabs).
|
||||
3. **No character meshes** exist in any pack — they are environment/props only.
|
||||
|
||||
Operator scope gate (4 questions): **render pass + curated home-base dressing**; enemies/player stay primitives; **defer VFX**; theme = **clean orbital base**.
|
||||
|
||||
## Decision
|
||||
|
||||
1. **Convert HDRP art to stock URP/Lit; do NOT switch the project to HDRP.** Switching pipelines would break the Entities Graphics setup the whole game depends on. Instead a **reusable Editor tool** (`Assets/_Project/Scripts/Editor/EnvArtTools.cs`, Assembly-CSharp-Editor, `#if UNITY_EDITOR`) reads each source material's texture refs across HDRP/Lit + ShaderGraph property names and builds a **stock URP/Lit** material (shader `933532a4…`, the same one the project's working prototypes use → DOTS-instancing/Entities-Graphics compatible) in `Assets/_Project/Materials/Env/`. It is **GUID-preserving on overwrite** (scene/prefab refs survive re-runs) and built for the incoming Synty packs (edit `CuratedPrefabNames` or call the public statics). Key correctness rules baked in after the adversarial review: **type-guard every `GetColor`/`GetFloat`/`GetTexture`** (verify `shader.GetPropertyType(idx)` first — the real tint is `_AlbedoTint`, NOT the float `_BaseColorMultiply` which `GetColor()` reads as black); **low metallic** (0.1–0.2 — high metallic + no reflection probe + dark skybox = near-black); **emission gated on the source `_Emissive` flag AND a light-fixture name** (the shader graph carries a non-zero default `_EmissiveColor` even when off); alpha-clip read from source flags.
|
||||
|
||||
2. **Ghost props swap mesh+material only; spawners preserve baked scale.** `Storage.prefab`→`SM_Storage_LOD0` (0.6), `UpgradePickup.prefab`→`SM_Battery_LOD0`+emissive `M_Env_PickupGlow` (2.5), preserving `GhostAuthoringComponent`/`LinkedEntityGroupAuthoring`/gameplay authoring (single-GameObject, no added children — interpolated replication unchanged). Because `LocalTransform.FromPosition()` hard-sets Scale=1, **the two server spawners (`UpgradePickupSpawnSystem`, `SharedStorageSpawnSystem`) were patched** to read the prefab's baked `LocalTransform` and override only Position — otherwise authored ghost scale is silently discarded (Scale is a replicated `[GhostField]`, so it was consistent-but-wrong, not a desync). This is the one gameplay-code change, and it's a latent-bug fix that future ghost-prefab sizing depends on.
|
||||
|
||||
3. **Static decor lives in the gameplay subscene; cosmetics-only.** An `EnvDecor` root of 13 **collider-stripped, unpacked** static props (dome backdrop, modular blocks, batteries/charger, crates, plants, light poles, solar panels) with converted URP materials, plus re-skinned existing walls/pillar (colliders + positions kept — predicted-physics collision intact). **No GhostAuthoring on scenery** (stays non-replicated, deterministic, present in both worlds). Decor renders via Entities Graphics from the subscene bake; the SampleScene `Ground`/skybox/fog render via classic URP — both coexist under the one camera.
|
||||
|
||||
4. **Render pass on SampleScene + the project-owned post-FX profile.** Cool key light; dark-space procedural skybox; flat dark ambient; exp fog @0.006 (keeps the z=26 dome backdrop visible); `Ground` re-skinned to a tiled sci-fi floor. The **`PostFX_DarkSciFi` volume profile is populated** (Bloom / **ACES** Tonemapping / ColorAdjustments / Vignette) and made the single active global volume (overlapping `GlobalPostFX` disabled). Effects are persisted as **sub-assets via `AssetDatabase.AddObjectToAsset`** — `VolumeProfile.Add<T>()` alone serializes null component refs that vanish on reload.
|
||||
|
||||
## Consequences
|
||||
|
||||
- **Validated at runtime (6.4.7, single in-editor client):** both worlds boot, 11 ghosts replicate, player input→prediction→replication works and the character is still **blocked by the static walls**; ghost scales now apply (Storage 0.60, pickups 2.50); console clean of code/Burst/material/bake errors (only "Server Tick Batching" — the documented unfocused-editor symptom; decor adds zero server-sim load). **EditMode 74/74.** Before/after screenshots confirm the jump from a primitive debug scene to a textured, lit orbital base under a dome.
|
||||
- **The adversarial review was decisive.** A "looks good" dark-lit screenshot **masked two blockers** (black-`_BaseColor` on ~16/20 materials; post-FX that never persisted to disk) + one major (inert ghost scale). All fixed. The lesson: under stylized dark lighting, **verify material/asset *values*, not just the render.**
|
||||
- **Reusable for every future pack** — `EnvArtTools` + the duplicate-and-reskin prefab pattern + the spawner-preserves-scale fix generalize. The remaining cost ceilings (uniform metallic/smoothness vs ORM; decor LODs baking into both worlds) are documented for later.
|
||||
- **No vendor assets modified, no shared-material bleed** — converted materials are new assets in `Materials/Env/`; the project's `M_Dummy` and all originals untouched; the two ghost prefabs changed only mesh/material/scale.
|
||||
|
||||
## Open / deferred
|
||||
|
||||
- **VFX** — packs aren't in the repo; once imported, wire the Shuriken ones into the existing client `ParticleSystem` pool ([[DR-009_GameFeel_Identity_FirstBlood]]'s presentation layer); VFX-Graph hits/beams need separate URP setup.
|
||||
- **Characters** — player/enemies stay primitives (no character meshes in these packs).
|
||||
- **Server LOD bloat** — pure decor's full LOD hierarchies bake into both worlds; move to a client-only/cosmetic subscene or flatten to LOD0 as decor grows.
|
||||
- **Material fidelity** — uniform metallic/smoothness (ORM channels don't map to URP); a per-channel ORM repack + a baked reflection probe would deepen the look.
|
||||
- **Mixed-theme arena** — the BioHorror pack fits future "corrupted edge" zones (a scope-gate option not taken this pass).
|
||||
|
||||
Expresses [[Identity]]; builds on [[DR-008_M5_HomeBase_BaseLayer_Storage]] (BaseAnchor, duplicate-an-existing-ghost) and [[DR-009_GameFeel_Identity_FirstBlood]] (URP post-FX look, client-only presentation). Session: [[2026-06-03_Visual_Upgrade_HomeBase]].
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: DR-011
|
||||
title: Grounded Synty sci-fi world (SampleScene/classic-URP) + GabrielAguiar Shuriken VFX integration
|
||||
status: accepted
|
||||
date: 2026-06-03
|
||||
tags:
|
||||
- decision
|
||||
- art
|
||||
- synty
|
||||
- urp
|
||||
- vfx
|
||||
- presentation
|
||||
- environment
|
||||
- world
|
||||
permalink: gamevault/07-sessions/decisions/dr-011-synty-world-vfx-integration
|
||||
---
|
||||
|
||||
# DR-011 — Grounded Synty world + GabrielAguiar VFX
|
||||
|
||||
## Context
|
||||
|
||||
After [[DR-010_Art_Import_URP_Conversion_Visual_Upgrade]] (BefourStudios HDRP→URP base on a small grey plane), the operator imported the GabrielAguiar VFX (now extracted) and a batch of **Synty POLYGON** packs and asked to: implement the VFX, **stop the world looking like a floating plane** (terrain/grounded, deepen the environment), inventory + use the Synty packs, and keep everything **cohesive**. Inventory found: GA is **94% Shuriken** (pool-friendly, URP-ok); Synty is **URP-native** (`Synty/Generic_Basic`, no conversion) with `SciFiCity+SciFiSpace+Mech` forming a cohesive flat-shaded sci-fi set (buildings, walls, 14 planets, asteroids, hangar floors). The semi-realistic BefourStudios base would clash with stylized Synty. Operator forks: **go full Synty** (retire BefourStudios) and **keep primitives** for player/enemies (no DOTS skeletal animation → static rigged meshes would slide as T-poses).
|
||||
|
||||
## Decision
|
||||
|
||||
1. **Build the grounded world as COSMETIC classic-URP GameObjects in SampleScene — not the DOTS subscene.** Synty materials use a custom shader (`Synty/Generic_Basic`); as plain SampleScene GameObjects under the client camera they render via classic URP with zero risk, and we never have to verify the Synty shader's Entities-Graphics DOTS-instancing. Only the gameplay subscene needs Entities Graphics + the baked PhysicsWorld. A `SyntyWorld` root holds ~60 objects: a large ground plane, a paved tech plaza over the play area, a 16-building skyline ring + perimeter walls (depth), boundary barriers aligned to the collision walls, props, a planet + asteroid backdrop, a space skybox, brighter flat ambient + light fog. **"Grounded" was achieved by surrounding the arena (skyline + planet horizon + fog) rather than by a bigger plane.**
|
||||
|
||||
2. **Retire BefourStudios for cohesion.** Delete the subscene `EnvDecor` (dome/props); **disable** the `Wall_North`/`Wall_East`/`Pillar_Center` MeshRenderers but **keep their BoxColliders** — a disabled renderer still bakes its static `PhysicsCollider` (gameplay collision intact) and no RenderMesh, so the boundary is invisible while the cosmetic Synty barriers + skyline define the space. The old grey `Ground` renderer is disabled (its classic MeshCollider is harmless — not in the DOTS world).
|
||||
|
||||
3. **GabrielAguiar Shuriken VFX via a `VFXConfig` bridge + `CombatFeedbackSystem`.** `VFXConfig` (a `ProjectM.Client` MonoBehaviour with a static `Instance` + 5 prefab slots, in the bootstrap scene — mirrors `PrototypeCameraRig`) hands authored prefabs to the client presentation system. `CombatFeedbackSystem.Burst()` instantiates the authored prefab at each hook (muzzle / hit / enemy-death / player-death), falling back to the existing procedural ParticleSystem when a slot is null. `UpdateProjectileTrails()` makes a trail GameObject follow each projectile ghost (query `WithAll<Projectile>()` each presentation frame; dict-by-`Entity` spawn/reposition/prune). Still pure client presentation — observes replicated state, never mutates the sim.
|
||||
|
||||
4. **Every spawned cosmetic VFX is stripped to particles (`StripCosmetic`).** GA "projectile" prefabs are self-moving demos (non-kinematic Rigidbody + collider + `ProjectileMoveScript` + secondary muzzle/hit spawns). On instantiate we destroy any `Rigidbody`/`Collider` and disable any `Projectile`/`Move`-named MonoBehaviour (before its `Start` runs), so only the ParticleSystems remain and our per-frame reposition is authoritative. VFX lifetime is derived from the prefab's longest ParticleSystem (clamped 1–6 s); a `MaxActiveVfx` cap bounds GC churn under swarms.
|
||||
|
||||
5. **Player/enemies stay primitives.** No character-mesh swap this pass — Entities Graphics has no easy skeletal animation, so a static rigged Synty character would slide as a T-pose (worse than a clean glowing shape). The world + VFX carry the upgrade; revisit characters when DOTS animation is added.
|
||||
|
||||
## Consequences
|
||||
|
||||
- **Validated at runtime (6.4.7, single in-editor client):** both worlds boot, 11 ghosts replicate, the dome correctly gone after re-bake, **player collision with the invisible subscene walls intact**, the **blue hit VFX fires** on husk contact with no console errors, and the world reads as a cohesive grounded Synty sci-fi colony (planet horizon + city skyline + plaza, no floating edge). **EditMode 74/74.**
|
||||
- **Adversarial review caught 1 blocker** (the demo-projectile-as-trail physics rig) + perf notes — all fixed (`StripCosmetic`, duration-based TTL, VFX cap, single active Volume confirmed). The scene/netcode isolation (cosmetic classic-PhysX colliders vs the baked DOTS PhysicsWorld) was verified end-to-end: **the cosmetic world cannot affect gameplay/netcode/determinism.**
|
||||
- **Reusable patterns:** Synty-in-SampleScene (classic URP, no conversion), the `VFXConfig` bridge + `Burst`/`SpawnVfx`/`StripCosmetic` + projectile-follow trail, and disabled-renderer-kept-collider for swapping a subscene's visual style. The two server spawners' baked-scale fix from DR-010 carries the rescaled ghost props.
|
||||
|
||||
## Open / deferred
|
||||
|
||||
- Confirm fire-driven VFX (muzzle / projectile trail / enemy-death) visually with a focused editor / real client (one-shot Fire drops under the unfocused editor; same verified `SpawnVfx` path as the confirmed hit VFX).
|
||||
- Ghost-prop cohesion gap: Storage/UpgradePickup ghosts still use BefourStudios meshes (render via EG; a Synty mesh there needs the Synty shader's DOTS-instancing verified). Prune the now-orphaned `Materials/Env/` decoratives.
|
||||
- Characters (player/enemies) still primitives — pending DOTS skeletal animation.
|
||||
- Perf budgeting (top-down Bloom + ~60 Synty objects + planet) and VFX-Graph hit/beam setup if wanted; mixed-theme corrupted zones (BioHorror) deferred.
|
||||
|
||||
Expresses [[Identity]]; supersedes the BefourStudios environment of [[DR-010_Art_Import_URP_Conversion_Visual_Upgrade]] (its converter/ghost-scale fixes still stand); builds on [[DR-009_GameFeel_Identity_FirstBlood]] (client-only presentation, `CombatFeedbackSystem`). Session: [[2026-06-03_Synty_World_And_VFX]].
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
id: DR-012
|
||||
title: Mouse-cursor aim + gamepad twin-stick controls (client-derived aim, scheme-gated assist)
|
||||
status: accepted
|
||||
date: 2026-06-03
|
||||
tags:
|
||||
- decision
|
||||
- input
|
||||
- controls
|
||||
- netcode
|
||||
- aiming
|
||||
- presentation
|
||||
- gamepad
|
||||
permalink: gamevault/07-sessions/decisions/dr-012-aim-controls-cursor-gamepad
|
||||
---
|
||||
|
||||
# DR-012 — Mouse-cursor aim + gamepad twin-stick controls
|
||||
|
||||
## Context
|
||||
|
||||
Controls felt janky: on mouse+keyboard the character could only fire along its **movement** direction — there was no cursor aim. Root cause: `PlayerInput.Aim` was bound **only** to `<Gamepad>/rightStick` in `Project M Input.inputactions`, and `controlSchemes` was empty, so on KBM `Aim` was always zero and `PlayerAimSystem` fell back to the movement heading. The operator asked to: show a cursor for aiming on KBM, make the character **face the cursor** (fire while standing still), **preserve gamepad** support, and research how V Rising / similar handle KBM+gamepad.
|
||||
|
||||
Research (V Rising primary; Hades/Halls of Torment/Diablo 4/Brotato) confirmed: KBM = continuous face-cursor decoupled from movement (strafe while aiming) with a visible cursor; gamepad = right-stick 360° aim with a world reticle; auto-switch on last-used device; **aim-assist is gamepad-only** for multiplayer fairness. Operator forks chosen: **per-scheme native** reticle (KBM crosshair + gamepad world ring) and **precise mouse / gamepad-only auto-aim**.
|
||||
|
||||
Key enabling insight: `PlayerInput.Aim` is already a replicated `[GhostField]` direction consumed by predicted `PlayerAimSystem` (facing) + `AbilityFireSystem` (shot dir), and `PlayerControlSystem` already drives movement from `Move` (decoupled from facing). So the fix is almost entirely **client input + presentation** — strafe-while-aiming comes free the moment `Aim` reflects the cursor.
|
||||
|
||||
## Decision
|
||||
|
||||
1. **Mouse aim is computed client-side and streamed via the EXISTING `PlayerInput.Aim` — no new ghost/netcode surface.** In `PlayerInputGatherSystem` (managed `SystemBase`, `GhostInputSystemGroup`, once per frame) the KBM path reads `Mouse.current.position`, projects `Camera.main.ScreenPointToRay` onto the player's movement plane via the pure helper `AimMath.PlanarAimFromRay(...)`, and writes the player→cursor direction as `Aim`. The heavy managed math stays client-only; only the resulting normalized direction (+ a scheme byte) crosses the wire, so predicted/server systems are structurally unchanged and deterministic. `AimMath` is Burst-safe and **unit-tested** (`AimMathTests`, 7 cases: down/diagonal rays, parallel/away/over-player fallbacks, plane-Y).
|
||||
|
||||
2. **Active scheme = last-meaningful-actuation-wins, replicated as one `byte`.** Gather detects KBM vs gamepad each frame (stick/trigger/button past a 0.04 lengthsq deadzone vs mouse-delta >0.5px / click / movement key; `InputDevice.lastUpdateTime` breaks ties; holds last when idle) and writes `PlayerInput.Scheme` (`InputSchemeId.KeyboardMouse=0 / Gamepad=1`). It is a **`byte` GhostField, not an enum** — cross-assembly enum-in-Burst tripped the type-hash ICE before (cf. `ProjectileClassificationSystem`), and `Scheme` is compared inside the Burst-compiled `AbilityFireSystem`.
|
||||
|
||||
3. **Auto-target assist is gated to gamepad (precise mouse).** `AbilityFireSystem` (server) applies the 12u/35° `AutoTarget` cone only when `applied.InternalInput.Scheme == InputSchemeId.Gamepad` (read from the same `GetDataAtTick` lookup used for the fire-count key, so it matches the exact fire tick). Mouse shots fly exactly to the cursor; gamepad keeps the assist. Bonus: mouse now predicts == server (no assist on either) → fewer reconcile snaps.
|
||||
|
||||
4. **Per-scheme native presentation in a client `PresentationSystemGroup` SystemBase (`AimReticleSystem`) that OBSERVES, never mutates.** KBM → a procedural crosshair `Texture2D` via `Cursor.SetCursor` replaces the OS arrow (cursor visible); gamepad → OS cursor hidden + a flat world-space ring (primitive quad, `Sprites/Default`, procedural ring texture) placed `ReticleDistance` ahead of the local player along the replicated `PlayerFacing`. Asset-free (mirrors `HudSystem`/`CombatFeedbackSystem`); cursor is re-applied only on a scheme change and **restored to OS default on `OnDestroy`**. The active scheme is handed over by a static bridge `AimPresentation.Scheme` (mirrors `PrototypeCameraRig`/`VFXConfig`), which **resets on play-enter** via `[RuntimeInitializeOnLoadMethod(SubsystemRegistration)]` (statics survive fast-enter-playmode domain reloads → a stale gamepad value would flash wrong presentation for the first frames).
|
||||
|
||||
5. **Gamepad neutral-stick keeps the existing face-movement fallback.** When the right stick is resting, `Aim` is zeroed and `PlayerAimSystem` falls back to the movement heading (controller-first behaviour, unchanged). The `.inputactions` asset was **not edited** (mouse aim bypasses the action; Fire/Move already cover both devices) — no wrapper regeneration.
|
||||
|
||||
## Consequences
|
||||
|
||||
- **Validated (6.4.7, single in-editor client):** compile/Burst/source-gen clean, **0 new warnings**, **EditMode 81/81**. Runtime: both worlds boot, player spawns, **no exceptions**; the `Scheme` byte replicates to the server (read back `Scheme=1`), injected `Aim=(1,0)` drives server `PlayerFacing=(1,0)`, and under a forced gamepad scheme the world reticle activates, lies flat (`rotX=90`), positions 4u ahead of the player, has its material, and the hardware cursor hides.
|
||||
- **Adversarial multi-agent review (5 dimensions, verified):** 5 confirmed / 5 correctly rejected. Fixed: the `AimPresentation` static-reset (the major), a `Shader.Find` fallback+guard, and `DebugInputInjectionSystem` now syncs `AimPresentation.Scheme`. Declined (verified correct): `mainTexture` vs `_MainTex` (canonical API, renders fine).
|
||||
- **Reusable patterns:** client-derived input on an existing `[GhostField]` direction (no new netcode surface); a replicated scheme byte to gate server-only assist; `AimMath` as a pure unit-tested projection; the reset-static-presentation-bridge idiom.
|
||||
|
||||
## Refinement — world-space cursor (follow-up, 2026-06-03)
|
||||
|
||||
Operator feedback after the first pass: make KBM aiming feel more natural / world-space. A research workflow (V Rising action-mode cursor-hide; Last Epoch / PoE2 / Diablo; TopDown Engine `ReplaceMousePointer`; dual-stick feel — gamedeveloper.com) confirmed the perspective-mismatch artifact (a flat screen crosshair sits visually above the angled ground point it targets) and recommended reticle-only. Changes (these **supersede decision #4's KBM screen crosshair**):
|
||||
|
||||
- **KBM uses the world-space ground ring at the cursor's ground-projection point** (not a screen crosshair); the OS cursor is hidden while aiming. The point is **re-raycast inside `AimReticleSystem`** (PresentationSystemGroup, after the follow-cam's LateUpdate move) — NOT latched from the gather (`GhostInputSystemGroup`, before the move), else the ring drifts one frame behind under the moving camera. New pure `AimMath.TryGroundHit` returns the world point; the last valid point is held on a miss. Cursor restored on focus-loss/destroy (`Application.isFocused`-gated). Both schemes now use one grounded ring (KBM at the cursor point, gamepad a fixed distance ahead) — consistent UX.
|
||||
- **Radial dead-zone** (`PlanarAimFromRay` `deadZoneRadius`, 0.6u) holds facing when the cursor is on/near the character.
|
||||
- **Camera look-ahead** (`PrototypeCameraRig.AimLeadDistance`, tunable, default 2.5u, 0 = off): leads the framed point toward the replicated `PlayerFacing` — driven off facing, not the cursor projection, so there is no feedback loop with the camera-dependent ground raycast. `PrototypeCameraTargetSystem` publishes `TargetFacing`.
|
||||
- **Skipped** (with reasons): constant-screen-size scaling (fixed-distance cam), aim line (redundant with the ring), KBM enemy-magnetism (would undermine the intentional gamepad-only assist).
|
||||
- Validated: EditMode **86/86**, console clean; runtime (focused) KBM ring active at the cursor ground point, OS cursor hidden, `TargetFacing` published, no exceptions.
|
||||
|
||||
## Open / deferred
|
||||
|
||||
- The **real mouse-cursor path + live device auto-switch** need a **focused** Game view — the unfocused editor can't inject mouse position / device actuation (validated the replication, math, gate, and reticle headlessly via `DebugInputInjectionSystem` + forced scheme). Operator focused click-test pending.
|
||||
- Auto-target priority/feel tuning; optional controller soft-target reticle snap (V Rising / Diablo-style) deferred.
|
||||
- Future: rebindable controls, multiple ability slots, and `controlSchemes` population if the Input System's built-in scheme switching is later preferred over the manual detector.
|
||||
|
||||
See [[2026-06-03_Aim_Controls_Cursor_Gamepad]]. Builds on [[DR-007_M5b_Character_Controller_Package]] (movement decoupled from facing) and [[DR-003_M2_Combat_Netcode_Architecture]] (input/command pipeline, `AutoTarget`).
|
||||
Reference in New Issue
Block a user