血量显示在玩家头顶

This commit is contained in:
2026-09-22 17:51:52 +08:00
parent b11da48e23
commit 414fcafe1d
5 changed files with 61 additions and 35 deletions
+5 -8
View File
@@ -10,8 +10,7 @@ extends CharacterBody3D
## │ └─ SpringArm (SpringArm3D) ← 承担俯仰 pitch,自动避障
## │ └─ Camera (Camera3D)
## ├─ Sync (MultiplayerSynchronizer) ← 同步 position 与 Body.rotation
## └─ Hud (CanvasLayer) ← 本地玩家的血条(节点配置,不是代码建的)
## └─ HealthLabel (Label)
## └─ HealthLabel (Label3D) ← 头顶血条(节点配置,不是代码建的)
##
## 操作:WASD/方向键移动,鼠标转视角,Shift 疾跑,空格跳跃,Esc 释放/锁定鼠标
@@ -50,9 +49,8 @@ const JUMP_BUFFER_FRAMES: int = 6
@onready var body: Node3D = $Body
@onready var camera_rig: Node3D = $CameraRig
@onready var spring_arm: SpringArm3D = $CameraRig/SpringArm
## 血条是 player.tscn 里的节点,不是代码建的 UI
@onready var _hud: CanvasLayer = $Hud
@onready var _health_label: Label = $Hud/HealthLabel
## 头顶血条是 player.tscn 里的 Label3D 节点(3D 世界里的文字,会跟着角色走)
@onready var _health_label: Label3D = $HealthLabel
var _gravity: float = float(ProjectSettings.get_setting("physics/3d/default_gravity", 9.8))
var _yaw: float = 0.0
@@ -68,11 +66,10 @@ func _ready() -> void:
if not _is_local:
# 远端玩家只是一具「回放身体」:
# 拆掉相机 —— 否则每多一个玩家就多一台 Camera3D 互相抢渲染;
# 关掉血条 —— 否则 N 份血条叠在同一位置,显示的血量可能是别人的;
# 关掉输入与物理 —— 否则与权威端双重模拟,表现为抖动、漂移、穿地。
# 它的 position 与 Body.rotation 由子节点 Sync 同步过来。
# 它的 position 与 Body.rotation 由子节点 Sync 同步过来;
# 头顶血条保留 —— health 同样是同步过来的,这样谁都能看到别人还剩多少血。
camera_rig.queue_free()
_hud.visible = false
set_physics_process(false)
set_process_unhandled_input(false)
return
+6 -7
View File
@@ -44,11 +44,10 @@ surface_material_override/0 = SubResource("StandardMaterial3D_yw30f")
[node name="Sync" type="MultiplayerSynchronizer" parent="." unique_id=1979575210]
replication_config = ExtResource("2_rkbax")
[node name="Hud" type="CanvasLayer" parent="." unique_id=425326662]
[node name="HealthLabel" type="Label" parent="Hud" unique_id=348125801]
offset_left = 16.0
offset_top = 56.0
offset_right = 17.0
offset_bottom = 79.0
[node name="HealthLabel" type="Label3D" parent="." unique_id=300336561]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.05, 0)
billboard = 1
no_depth_test = true
text = "HP 100 / 100"
font_size = 64
outline_size = 8