mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-07-12 18:43:49 +00:00
refactor(*): Make hud more performant and maintainable
This commit is contained in:
+2
-70
@@ -1,6 +1,7 @@
|
|||||||
[gd_scene load_steps=5 format=3 uid="uid://p07epxnh8wwp"]
|
[gd_scene load_steps=5 format=3 uid="uid://p07epxnh8wwp"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://dyq1n7q1bqjps" path="res://scripts/ship.gd" id="1_efag7"]
|
[ext_resource type="Script" uid="uid://dyq1n7q1bqjps" path="res://scripts/ship.gd" id="1_efag7"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://c8kak2l3m4n5" path="res://scenes/HUD.tscn" id="2_hud_scene"]
|
||||||
|
|
||||||
[sub_resource type="BoxMesh" id="BoxMesh_efag7"]
|
[sub_resource type="BoxMesh" id="BoxMesh_efag7"]
|
||||||
size = Vector3(1, 1, 4)
|
size = Vector3(1, 1, 4)
|
||||||
@@ -8,9 +9,6 @@ size = Vector3(1, 1, 4)
|
|||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_dsjou"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_dsjou"]
|
||||||
size = Vector3(1, 1, 4)
|
size = Vector3(1, 1, 4)
|
||||||
|
|
||||||
[sub_resource type="LabelSettings" id="LabelSettings_efag7"]
|
|
||||||
font_size = 32
|
|
||||||
|
|
||||||
[node name="Ship" type="RigidBody3D"]
|
[node name="Ship" type="RigidBody3D"]
|
||||||
mass = 10.0
|
mass = 10.0
|
||||||
gravity_scale = 10.0
|
gravity_scale = 10.0
|
||||||
@@ -25,70 +23,4 @@ shape = SubResource("BoxShape3D_dsjou")
|
|||||||
[node name="Camera3D" type="Camera3D" parent="."]
|
[node name="Camera3D" type="Camera3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 0.867366, 0.497671, 0, -0.497671, 0.867366, 0, 2.04336, 3.31556)
|
transform = Transform3D(1, 0, 0, 0, 0.867366, 0.497671, 0, -0.497671, 0.867366, 0, 2.04336, 3.31556)
|
||||||
|
|
||||||
[node name="HUD" type="CanvasLayer" parent="."]
|
[node name="HUD" parent="." instance=ExtResource("2_hud_scene")]
|
||||||
|
|
||||||
[node name="Control" type="Control" parent="HUD"]
|
|
||||||
layout_mode = 3
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
|
|
||||||
[node name="TimerLabel" type="Label" parent="HUD/Control"]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 5
|
|
||||||
anchor_left = 0.5
|
|
||||||
anchor_right = 0.5
|
|
||||||
offset_left = -90.5
|
|
||||||
offset_right = 90.5
|
|
||||||
offset_bottom = 62.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
label_settings = SubResource("LabelSettings_efag7")
|
|
||||||
horizontal_alignment = 1
|
|
||||||
|
|
||||||
[node name="InfoPanel" type="VBoxContainer" parent="HUD/Control"]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 2
|
|
||||||
anchor_top = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = 10.0
|
|
||||||
offset_top = -200.0
|
|
||||||
offset_right = 300.0
|
|
||||||
offset_bottom = -10.0
|
|
||||||
grow_vertical = 0
|
|
||||||
|
|
||||||
[node name="SpeedLabel" type="Label" parent="HUD/Control/InfoPanel"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Speed: 0.0 m/s"
|
|
||||||
label_settings = SubResource("LabelSettings_efag7")
|
|
||||||
|
|
||||||
[node name="AltitudeLabel" type="Label" parent="HUD/Control/InfoPanel"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Altitude: 0.0 m"
|
|
||||||
label_settings = SubResource("LabelSettings_efag7")
|
|
||||||
|
|
||||||
[node name="AngularVelLabel" type="Label" parent="HUD/Control/InfoPanel"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Angular Vel: 0.0 rad/s"
|
|
||||||
label_settings = SubResource("LabelSettings_efag7")
|
|
||||||
|
|
||||||
[node name="CameraModeLabel" type="Label" parent="HUD/Control/InfoPanel"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Camera: Ball Cam"
|
|
||||||
label_settings = SubResource("LabelSettings_efag7")
|
|
||||||
|
|
||||||
[node name="AttitudeLabel" type="Label" parent="HUD/Control/InfoPanel"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Pitch: 0° Roll: 0°"
|
|
||||||
label_settings = SubResource("LabelSettings_efag7")
|
|
||||||
|
|
||||||
[node name="HeadingLabel" type="Label" parent="HUD/Control/InfoPanel"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Heading: 0°"
|
|
||||||
label_settings = SubResource("LabelSettings_efag7")
|
|
||||||
|
|
||||||
[node name="ThrustLabel" type="Label" parent="HUD/Control/InfoPanel"]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Thrust: 0%"
|
|
||||||
label_settings = SubResource("LabelSettings_efag7")
|
|
||||||
|
|||||||
@@ -47,5 +47,6 @@ lock_rotation = true
|
|||||||
|
|
||||||
[node name="Ball" parent="." instance=ExtResource("5_iywne")]
|
[node name="Ball" parent="." instance=ExtResource("5_iywne")]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.464103, 1.46401, -2.82393)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.464103, 1.46401, -2.82393)
|
||||||
|
mass = 3.0
|
||||||
|
|
||||||
[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]
|
[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://c8kak2l3m4n5"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://bx9j8k7l6m5n" path="res://scripts/HUDController.gd" id="1_hud_controller"]
|
||||||
|
|
||||||
|
[sub_resource type="LabelSettings" id="LabelSettings_hud"]
|
||||||
|
font_size = 32
|
||||||
|
|
||||||
|
[node name="HUD" type="CanvasLayer"]
|
||||||
|
script = ExtResource("1_hud_controller")
|
||||||
|
|
||||||
|
[node name="Control" type="Control" parent="."]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="TimerLabel" type="Label" parent="Control"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 5
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
offset_left = -90.5
|
||||||
|
offset_right = 90.5
|
||||||
|
offset_bottom = 62.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
label_settings = SubResource("LabelSettings_hud")
|
||||||
|
horizontal_alignment = 1
|
||||||
|
|
||||||
|
[node name="Instruments" type="Control" parent="Control"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="InfoPanel" type="VBoxContainer" parent="Control"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 2
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = 10.0
|
||||||
|
offset_top = -200.0
|
||||||
|
offset_right = 300.0
|
||||||
|
offset_bottom = -10.0
|
||||||
|
grow_vertical = 0
|
||||||
|
|
||||||
|
[node name="SpeedLabel" type="Label" parent="Control/InfoPanel"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Speed: 0.0 m/s"
|
||||||
|
label_settings = SubResource("LabelSettings_hud")
|
||||||
|
|
||||||
|
[node name="AltitudeLabel" type="Label" parent="Control/InfoPanel"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Altitude: 0.0 m"
|
||||||
|
label_settings = SubResource("LabelSettings_hud")
|
||||||
|
|
||||||
|
[node name="AngularVelLabel" type="Label" parent="Control/InfoPanel"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Angular Vel: 0.0 rad/s"
|
||||||
|
label_settings = SubResource("LabelSettings_hud")
|
||||||
|
|
||||||
|
[node name="CameraModeLabel" type="Label" parent="Control/InfoPanel"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Camera: Ball Cam"
|
||||||
|
label_settings = SubResource("LabelSettings_hud")
|
||||||
|
|
||||||
|
[node name="AttitudeLabel" type="Label" parent="Control/InfoPanel"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Pitch: 0° Roll: 0°"
|
||||||
|
label_settings = SubResource("LabelSettings_hud")
|
||||||
|
|
||||||
|
[node name="HeadingLabel" type="Label" parent="Control/InfoPanel"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Heading: 0°"
|
||||||
|
label_settings = SubResource("LabelSettings_hud")
|
||||||
|
|
||||||
|
[node name="ThrustLabel" type="Label" parent="Control/InfoPanel"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Thrust: 0%"
|
||||||
|
label_settings = SubResource("LabelSettings_hud")
|
||||||
@@ -51,6 +51,7 @@ shape = SubResource("BoxShape3D_133xi")
|
|||||||
|
|
||||||
[node name="Ball" parent="." instance=ExtResource("2_mv342")]
|
[node name="Ball" parent="." instance=ExtResource("2_mv342")]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 2, 2.08165e-12)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.08165e-12, 2, 2.08165e-12)
|
||||||
|
mass = 3.0
|
||||||
|
|
||||||
[node name="Players" type="Node3D" parent="."]
|
[node name="Players" type="Node3D" parent="."]
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
# HUD Controller - handles all display logic and label updates
|
||||||
|
# Receives ship data via signals and updates UI accordingly
|
||||||
|
# Simplified version focusing on labels only
|
||||||
|
extends CanvasLayer
|
||||||
|
class_name HUDController
|
||||||
|
|
||||||
|
# UI Label References
|
||||||
|
@onready var timer_label = get_node("Control/TimerLabel")
|
||||||
|
@onready var speed_label = get_node("Control/InfoPanel/SpeedLabel")
|
||||||
|
@onready var altitude_label = get_node("Control/InfoPanel/AltitudeLabel")
|
||||||
|
@onready var angular_vel_label = get_node("Control/InfoPanel/AngularVelLabel")
|
||||||
|
@onready var camera_mode_label = get_node("Control/InfoPanel/CameraModeLabel")
|
||||||
|
@onready var attitude_label = get_node("Control/InfoPanel/AttitudeLabel")
|
||||||
|
@onready var heading_label = get_node("Control/InfoPanel/HeadingLabel")
|
||||||
|
@onready var thrust_label = get_node("Control/InfoPanel/ThrustLabel")
|
||||||
|
|
||||||
|
var ship: Node
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
# Wait one frame to ensure ship is ready and added to group
|
||||||
|
await get_tree().process_frame
|
||||||
|
_initialize_hud()
|
||||||
|
|
||||||
|
func _initialize_hud():
|
||||||
|
# Find the ship
|
||||||
|
ship = get_tree().get_first_node_in_group("ship")
|
||||||
|
if not ship:
|
||||||
|
# Try to find it as our parent (ship contains this HUD)
|
||||||
|
var parent_node = get_parent()
|
||||||
|
if parent_node and parent_node.is_in_group("ship"):
|
||||||
|
ship = parent_node
|
||||||
|
else:
|
||||||
|
push_error("HUDController: No ship found in 'ship' group")
|
||||||
|
return
|
||||||
|
|
||||||
|
print("HUDController: Found ship: ", ship.name)
|
||||||
|
_connect_ship_signals()
|
||||||
|
|
||||||
|
# Connect to game manager's timer signal
|
||||||
|
var game_manager = get_tree().get_first_node_in_group("game")
|
||||||
|
if game_manager and game_manager.has_signal("timer_updated"):
|
||||||
|
game_manager.timer_updated.connect(_on_timer_updated)
|
||||||
|
print("HUDController: Connected to game timer")
|
||||||
|
|
||||||
|
func _connect_ship_signals():
|
||||||
|
# Connect ship signals to label update methods
|
||||||
|
if ship.has_signal("speed_changed"):
|
||||||
|
ship.speed_changed.connect(_on_ship_speed_changed)
|
||||||
|
print("HUDController: Connected to speed_changed signal")
|
||||||
|
if ship.has_signal("altitude_changed"):
|
||||||
|
ship.altitude_changed.connect(_on_ship_altitude_changed)
|
||||||
|
if ship.has_signal("angular_velocity_changed"):
|
||||||
|
ship.angular_velocity_changed.connect(_on_ship_angular_velocity_changed)
|
||||||
|
if ship.has_signal("camera_mode_changed"):
|
||||||
|
ship.camera_mode_changed.connect(_on_ship_camera_mode_changed)
|
||||||
|
if ship.has_signal("attitude_changed"):
|
||||||
|
ship.attitude_changed.connect(_on_ship_attitude_changed)
|
||||||
|
if ship.has_signal("heading_changed"):
|
||||||
|
ship.heading_changed.connect(_on_ship_heading_changed)
|
||||||
|
if ship.has_signal("thrust_changed"):
|
||||||
|
ship.thrust_changed.connect(_on_ship_thrust_changed)
|
||||||
|
|
||||||
|
# Signal handlers for ship data - these update the legacy text labels
|
||||||
|
# All handlers include null checks for robustness
|
||||||
|
func _on_ship_speed_changed(speed: float):
|
||||||
|
if speed_label and is_instance_valid(speed_label):
|
||||||
|
speed_label.text = "Speed: %.1f m/s" % speed
|
||||||
|
|
||||||
|
func _on_ship_altitude_changed(altitude: float):
|
||||||
|
if altitude_label and is_instance_valid(altitude_label):
|
||||||
|
altitude_label.text = "Altitude: %.1f m" % altitude
|
||||||
|
|
||||||
|
func _on_ship_angular_velocity_changed(angular_speed: float):
|
||||||
|
if angular_vel_label and is_instance_valid(angular_vel_label):
|
||||||
|
angular_vel_label.text = "Angular Vel: %.2f rad/s" % angular_speed
|
||||||
|
|
||||||
|
func _on_ship_camera_mode_changed(is_ball_cam: bool):
|
||||||
|
if camera_mode_label and is_instance_valid(camera_mode_label):
|
||||||
|
var camera_mode = "Ball Cam" if is_ball_cam else "Ship Cam"
|
||||||
|
camera_mode_label.text = "Camera: %s" % camera_mode
|
||||||
|
|
||||||
|
func _on_ship_attitude_changed(pitch: float, roll: float, yaw: float):
|
||||||
|
if attitude_label and is_instance_valid(attitude_label):
|
||||||
|
attitude_label.text = "Pitch: %.0f° Roll: %.0f°" % [pitch, roll]
|
||||||
|
|
||||||
|
func _on_ship_heading_changed(heading_degrees: float):
|
||||||
|
if heading_label and is_instance_valid(heading_label):
|
||||||
|
heading_label.text = "Heading: %.0f°" % heading_degrees
|
||||||
|
|
||||||
|
func _on_ship_thrust_changed(thrust_percent: float):
|
||||||
|
if thrust_label and is_instance_valid(thrust_label):
|
||||||
|
thrust_label.text = "Thrust: %.0f%%" % thrust_percent
|
||||||
|
|
||||||
|
# Timer signal handler from game manager (restored original functionality)
|
||||||
|
func _on_timer_updated(minutes: int, seconds: int):
|
||||||
|
if timer_label and is_instance_valid(timer_label):
|
||||||
|
timer_label.text = "%02d:%02d" % [minutes, seconds]
|
||||||
|
|
||||||
|
# Simple timer update method (kept for compatibility)
|
||||||
|
func update_timer(time_text: String):
|
||||||
|
if timer_label and is_instance_valid(timer_label):
|
||||||
|
timer_label.text = time_text
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://du7y176h5aaq4
|
||||||
@@ -4,6 +4,9 @@ extends Node3D
|
|||||||
signal timer_updated(minutes: int, seconds: int)
|
signal timer_updated(minutes: int, seconds: int)
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
# Add to group for discovery by HUD
|
||||||
|
add_to_group("game")
|
||||||
|
|
||||||
# Set timer to 2 minutes 30 seconds (150 seconds)
|
# Set timer to 2 minutes 30 seconds (150 seconds)
|
||||||
game_timer.wait_time = 150.0
|
game_timer.wait_time = 150.0
|
||||||
game_timer.one_shot = true # Timer runs once
|
game_timer.one_shot = true # Timer runs once
|
||||||
|
|||||||
+71
-38
@@ -20,22 +20,42 @@ var camera_smoothing = 10.0
|
|||||||
@onready var camera : Camera3D = get_node("Camera3D")
|
@onready var camera : Camera3D = get_node("Camera3D")
|
||||||
@onready var ball = get_parent().get_node("Ball")
|
@onready var ball = get_parent().get_node("Ball")
|
||||||
|
|
||||||
# HUD Nodes
|
|
||||||
@onready var timer_label = get_node("HUD/Control/TimerLabel")
|
|
||||||
@onready var speed_label = get_node("HUD/Control/InfoPanel/SpeedLabel")
|
|
||||||
@onready var altitude_label = get_node("HUD/Control/InfoPanel/AltitudeLabel")
|
|
||||||
@onready var angular_vel_label = get_node("HUD/Control/InfoPanel/AngularVelLabel")
|
|
||||||
@onready var camera_mode_label = get_node("HUD/Control/InfoPanel/CameraModeLabel")
|
|
||||||
@onready var attitude_label = get_node("HUD/Control/InfoPanel/AttitudeLabel")
|
|
||||||
@onready var heading_label = get_node("HUD/Control/InfoPanel/HeadingLabel")
|
|
||||||
@onready var thrust_label = get_node("HUD/Control/InfoPanel/ThrustLabel")
|
|
||||||
|
|
||||||
var ball_cam_enabled = true
|
var ball_cam_enabled = true
|
||||||
|
|
||||||
|
# Instrument signals for efficient data distribution
|
||||||
|
signal speed_changed(speed: float)
|
||||||
|
signal attitude_changed(pitch: float, roll: float, yaw: float)
|
||||||
|
signal altitude_changed(altitude: float)
|
||||||
|
signal thrust_changed(thrust_percent: float)
|
||||||
|
signal angular_velocity_changed(angular_speed: float)
|
||||||
|
signal camera_mode_changed(is_ball_cam: bool)
|
||||||
|
signal heading_changed(heading_degrees: float)
|
||||||
|
|
||||||
|
# Performance optimization - track last emitted values to avoid unnecessary signals
|
||||||
|
var _last_speed: float = -1.0
|
||||||
|
var _last_altitude: float = -999999.0
|
||||||
|
var _last_angular_speed: float = -1.0
|
||||||
|
var _last_pitch: float = -999.0
|
||||||
|
var _last_roll: float = -999.0
|
||||||
|
var _last_yaw: float = -999.0
|
||||||
|
var _last_heading: float = -999.0
|
||||||
|
var _last_thrust: float = -1.0
|
||||||
|
var _last_camera_mode: bool = true
|
||||||
|
|
||||||
|
# Thresholds for signal emission (only emit if change is significant)
|
||||||
|
const SPEED_THRESHOLD = 0.1 # m/s
|
||||||
|
const ALTITUDE_THRESHOLD = 0.5 # meters
|
||||||
|
const ANGULAR_THRESHOLD = 0.01 # rad/s
|
||||||
|
const ATTITUDE_THRESHOLD = 1.0 # degrees
|
||||||
|
const THRUST_THRESHOLD = 1.0 # percent
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
mass = 5
|
mass = 5
|
||||||
gravity_scale = 1.0
|
gravity_scale = 1.0
|
||||||
|
|
||||||
|
# Add ship to group for instrument discovery
|
||||||
|
add_to_group("ship")
|
||||||
|
|
||||||
# Set custom inertia for better rotation
|
# Set custom inertia for better rotation
|
||||||
# Physics: I = m * r² (moment of inertia = mass × radius²)
|
# Physics: I = m * r² (moment of inertia = mass × radius²)
|
||||||
# Lower inertia = easier to rotate, higher inertia = more stable
|
# Lower inertia = easier to rotate, higher inertia = more stable
|
||||||
@@ -58,26 +78,18 @@ func _ready():
|
|||||||
axis_lock_angular_y = false
|
axis_lock_angular_y = false
|
||||||
axis_lock_angular_z = false
|
axis_lock_angular_z = false
|
||||||
|
|
||||||
var game_scene = get_parent()
|
|
||||||
if game_scene and game_scene.has_signal("timer_updated"):
|
|
||||||
game_scene.timer_updated.connect(_on_timer_updated)
|
|
||||||
else:
|
|
||||||
print("Game scene not found or doesn't have timer_updated signal")
|
|
||||||
|
|
||||||
print("Ship physics configured - Mass: ", mass, " Gravity scale: ", gravity_scale, " Inertia: ", inertia)
|
print("Ship physics configured - Mass: ", mass, " Gravity scale: ", gravity_scale, " Inertia: ", inertia)
|
||||||
print("Rotation locks - X:", axis_lock_angular_x, " Y:", axis_lock_angular_y, " Z:", axis_lock_angular_z)
|
print("Rotation locks - X:", axis_lock_angular_x, " Y:", axis_lock_angular_y, " Z:", axis_lock_angular_z)
|
||||||
|
|
||||||
func _input(event):
|
func _input(event):
|
||||||
if event.is_action_pressed("ui_accept"): # Enter key
|
if event.is_action_pressed("ui_accept"): # Enter key
|
||||||
ball_cam_enabled = !ball_cam_enabled
|
ball_cam_enabled = !ball_cam_enabled
|
||||||
|
camera_mode_changed.emit(ball_cam_enabled)
|
||||||
func _on_timer_updated(minutes: int, seconds: int):
|
|
||||||
timer_label.text = "%02d:%02d" % [minutes, seconds]
|
|
||||||
|
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
if camera:
|
if camera:
|
||||||
_update_camera(delta)
|
_update_camera(delta)
|
||||||
_update_hud()
|
_emit_telemetry_data()
|
||||||
|
|
||||||
func _update_camera(delta):
|
func _update_camera(delta):
|
||||||
if ball_cam_enabled and ball:
|
if ball_cam_enabled and ball:
|
||||||
@@ -283,44 +295,65 @@ func apply_drag_and_limits(state: PhysicsDirectBodyState3D, rotation_input: Vect
|
|||||||
# Physics: ω̂ = ω / |ω|, ω_limited = ω̂ * ω_max
|
# Physics: ω̂ = ω / |ω|, ω_limited = ω̂ * ω_max
|
||||||
state.angular_velocity = state.angular_velocity.normalized() * max_angular_speed
|
state.angular_velocity = state.angular_velocity.normalized() * max_angular_speed
|
||||||
|
|
||||||
func _update_hud():
|
func _emit_telemetry_data():
|
||||||
# Update speed display
|
# Ship only calculates and emits data - HUD handles display
|
||||||
|
# Performance optimization: only emit signals when values change significantly
|
||||||
|
|
||||||
|
# Speed telemetry
|
||||||
# Physics: |v| = √(vₓ² + vᵧ² + vᵤ²) (magnitude of velocity vector)
|
# Physics: |v| = √(vₓ² + vᵧ² + vᵤ²) (magnitude of velocity vector)
|
||||||
var current_speed = linear_velocity.length()
|
var current_speed = linear_velocity.length()
|
||||||
speed_label.text = "Speed: %.1f m/s" % current_speed
|
if abs(current_speed - _last_speed) > SPEED_THRESHOLD:
|
||||||
|
speed_changed.emit(current_speed)
|
||||||
|
_last_speed = current_speed
|
||||||
|
|
||||||
# Update altitude (Y position relative to ground level)
|
# Altitude telemetry
|
||||||
# Physics: Height measurement from reference point (y = 0)
|
# Physics: Height measurement from reference point (y = 0)
|
||||||
var current_altitude = global_transform.origin.y
|
var current_altitude = global_transform.origin.y
|
||||||
altitude_label.text = "Altitude: %.1f m" % current_altitude
|
if abs(current_altitude - _last_altitude) > ALTITUDE_THRESHOLD:
|
||||||
|
altitude_changed.emit(current_altitude)
|
||||||
|
_last_altitude = current_altitude
|
||||||
|
|
||||||
# Update angular velocity
|
# Angular velocity telemetry
|
||||||
# Physics: |ω| = √(ωₓ² + ωᵧ² + ωᵤ²) (magnitude of angular velocity vector)
|
# Physics: |ω| = √(ωₓ² + ωᵧ² + ωᵤ²) (magnitude of angular velocity vector)
|
||||||
var angular_speed = angular_velocity.length()
|
var angular_speed = angular_velocity.length()
|
||||||
angular_vel_label.text = "Angular Vel: %.2f rad/s" % angular_speed
|
if abs(angular_speed - _last_angular_speed) > ANGULAR_THRESHOLD:
|
||||||
|
angular_velocity_changed.emit(angular_speed)
|
||||||
|
_last_angular_speed = angular_speed
|
||||||
|
|
||||||
# Update camera mode
|
# Camera mode telemetry (only emit when it actually changes)
|
||||||
var camera_mode = "Ball Cam" if ball_cam_enabled else "Ship Cam"
|
if ball_cam_enabled != _last_camera_mode:
|
||||||
camera_mode_label.text = "Camera: %s" % camera_mode
|
camera_mode_changed.emit(ball_cam_enabled)
|
||||||
|
_last_camera_mode = ball_cam_enabled
|
||||||
|
|
||||||
# Calculate attitude (pitch and roll from ship orientation)
|
# Attitude telemetry (pitch, roll, yaw from ship orientation)
|
||||||
# Physics: Euler angles from rotation matrix
|
# Physics: Euler angles from rotation matrix
|
||||||
# Pitch = rotation around X-axis, Roll = rotation around Z-axis
|
# Pitch = rotation around X-axis, Roll = rotation around Z-axis
|
||||||
var ship_rotation = global_transform.basis.get_euler(EULER_ORDER_XYZ)
|
var ship_rotation = global_transform.basis.get_euler(EULER_ORDER_XYZ)
|
||||||
var pitch_deg = rad_to_deg(ship_rotation.x)
|
var pitch_deg = rad_to_deg(ship_rotation.x)
|
||||||
var roll_deg = rad_to_deg(ship_rotation.z)
|
var roll_deg = rad_to_deg(ship_rotation.z)
|
||||||
attitude_label.text = "Pitch: %.0f° Roll: %.0f°" % [pitch_deg, roll_deg]
|
var yaw_deg = rad_to_deg(ship_rotation.y)
|
||||||
|
|
||||||
# Calculate heading (yaw - direction ship is facing)
|
if abs(pitch_deg - _last_pitch) > ATTITUDE_THRESHOLD or \
|
||||||
|
abs(roll_deg - _last_roll) > ATTITUDE_THRESHOLD or \
|
||||||
|
abs(yaw_deg - _last_yaw) > ATTITUDE_THRESHOLD:
|
||||||
|
attitude_changed.emit(pitch_deg, roll_deg, yaw_deg)
|
||||||
|
_last_pitch = pitch_deg
|
||||||
|
_last_roll = roll_deg
|
||||||
|
_last_yaw = yaw_deg
|
||||||
|
|
||||||
|
# Heading telemetry (yaw - direction ship is facing)
|
||||||
# Physics: Yaw = rotation around Y-axis (compass heading)
|
# Physics: Yaw = rotation around Y-axis (compass heading)
|
||||||
# Convert to 0-360° range for traditional compass display
|
# Convert to 0-360° range for traditional compass display
|
||||||
var yaw_deg = rad_to_deg(ship_rotation.y)
|
|
||||||
var heading = fmod(yaw_deg + 360.0, 360.0) # Normalize to 0-360°
|
var heading = fmod(yaw_deg + 360.0, 360.0) # Normalize to 0-360°
|
||||||
heading_label.text = "Heading: %.0f°" % heading
|
if abs(heading - _last_heading) > ATTITUDE_THRESHOLD:
|
||||||
|
heading_changed.emit(heading)
|
||||||
|
_last_heading = heading
|
||||||
|
|
||||||
# Calculate current thrust percentage
|
# Thrust telemetry
|
||||||
# Physics: Thrust output as percentage of maximum available thrust
|
# Physics: Thrust output as percentage of maximum available thrust
|
||||||
var thrust_input = get_thrust_input()
|
var thrust_input = get_thrust_input()
|
||||||
var thrust_magnitude = thrust_input.length()
|
var thrust_magnitude = thrust_input.length()
|
||||||
var thrust_percent = thrust_magnitude * 100.0
|
var thrust_percent = thrust_magnitude * 100.0
|
||||||
thrust_label.text = "Thrust: %.0f%%" % thrust_percent
|
if abs(thrust_percent - _last_thrust) > THRUST_THRESHOLD:
|
||||||
|
thrust_changed.emit(thrust_percent)
|
||||||
|
_last_thrust = thrust_percent
|
||||||
|
|||||||
Reference in New Issue
Block a user