Avatars actually show; camera stops hugging the player
checkpoint / checkpoint (push) Successful in 1m40s
checkpoint / checkpoint (push) Successful in 1m40s
- SpringArm3D was colliding with the player's own capsule (same layer) -> camera yanked up against the head. add_excluded_object(self) in _ready + gentler default pitch, shorter arm, lower pivot. - AvatarSystem.build_current_avatar() is now self-sufficient: loads the catalog itself and falls back to a bare default loadout if login didn't prime one. So the in-world player always shows an avatar, never the capsule, as long as the assets are packed (they are now). - New AvatarSystem.assemble_avatar(): builds a standalone avatar with a throwaway loader, touching no shared state -- so it's safe to call once for the local player AND once per remote peer. (load_avatar()'s shared loader reset()s and freed the previous avatar on every call.) - game.gd: remote players render as the assembled avatar too (shared default look, tinted per-peer, name tag) instead of a plain capsule. Client-side -- rebuild the exe. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
This commit is contained in:
+12
-7
@@ -25,7 +25,7 @@ const MOUSE_SENSITIVITY: float = 0.003
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
var _input_direction := Vector2.ZERO
|
||||
var _camera_pitch: float = -0.25
|
||||
var _camera_pitch: float = -0.12
|
||||
|
||||
## Vertical offset applied to the assembled avatar so its feet (origin y=0)
|
||||
## line up with the bottom of the player's collision capsule.
|
||||
@@ -70,6 +70,12 @@ func _ready() -> void:
|
||||
push_warning("player.gd: no PlayerSpawn marker found; spawning at origin")
|
||||
global_position = Vector3(0, 1.0, 0)
|
||||
|
||||
# The spring arm must not collide with the player's own capsule (they're
|
||||
# on the same layer), or the camera gets yanked right up against the
|
||||
# player's head.
|
||||
var arm := $CameraPivot/SpringArm3D as SpringArm3D
|
||||
arm.add_excluded_object(self)
|
||||
|
||||
# Start the camera arm tilted down a little so the avatar is framed.
|
||||
_camera_pivot.rotation.x = _camera_pitch
|
||||
|
||||
@@ -81,18 +87,17 @@ func _ready() -> void:
|
||||
_apply_avatar()
|
||||
|
||||
|
||||
## Replace the placeholder capsule with the player's assembled avatar, if the
|
||||
## AvatarSystem has a loadout primed (set at login by main_menu.gd). Falls back
|
||||
## to the capsule silently when there's no avatar to show -- e.g. running this
|
||||
## scene directly in a test, or an offline/failed catalog load.
|
||||
## TODO(PC3): a third-person camera so the local player actually sees this;
|
||||
## for now it's mainly for other players (Phase 2) and looking down.
|
||||
## Show the player's assembled avatar and hide the placeholder capsule.
|
||||
## AvatarSystem.build_current_avatar() is self-sufficient now (loads the
|
||||
## catalog + falls back to a default loadout), so this only no-ops if the
|
||||
## avatar assets themselves are missing.
|
||||
func _apply_avatar() -> void:
|
||||
var avatars := get_node_or_null("/root/AvatarSystem")
|
||||
if avatars == null or not avatars.has_method("build_current_avatar"):
|
||||
return
|
||||
var avatar: Node3D = avatars.build_current_avatar()
|
||||
if avatar == null:
|
||||
push_warning("player.gd: no avatar to show; keeping the placeholder capsule")
|
||||
return
|
||||
avatar.position = Vector3(0.0, AVATAR_FEET_OFFSET, 0.0)
|
||||
add_child(avatar)
|
||||
|
||||
Reference in New Issue
Block a user