documentation and optimization

This commit is contained in:
Lucas 2025-07-29 14:08:08 +02:00
parent 5d76a0bbf7
commit 9e2bf5787f
No known key found for this signature in database
2 changed files with 82 additions and 45 deletions

View file

@ -1,4 +1,5 @@
extends Control
class_name SelectionManager
var draw_selection := false
@ -11,11 +12,8 @@ var perform_selection := false # Flag to trigger selection in _physics_process
@onready var optimized_rect: bool = ProjectSettings.get_setting("game/interface/optimized_rectangle", false)
@export var rect_style: StyleBoxFlat
@onready var cam = get_viewport().get_camera_3d()
@onready var hovercontrol:Button = $"../Button"
func _ready() -> void:
if optimized_rect:return
@onready var hovercontrol: Button = $"../Button"
@onready var debug_mode = get_tree().debug_collisions_hint #ProjectSettings.get_setting("debug/collisions/show_mouse_trace", false)
func _unhandled_input(e: InputEvent) -> void:
@ -24,7 +22,6 @@ func _unhandled_input(e: InputEvent) -> void:
draw_selection = true
drag_start = e.position
else:
# When button is released
draw_selection = false
if drag_start.is_equal_approx(e.position):
# Single click: set a zero-sized selection box
@ -38,7 +35,8 @@ func _unhandled_input(e: InputEvent) -> void:
max(drag_start.x, e.position.x) - x_min,
max(drag_start.y, e.position.y) - y_min)
perform_selection = true # Trigger selection in _physics_process
perform_selection = true
queue_redraw()
elif draw_selection and e is InputEventMouseMotion:
# Update selection box for drawing during drag
@ -68,11 +66,11 @@ func check_hover():
hovercontrol.text = ""
hovercontrol.queue_redraw()
pass
## Returns an array of entities selected by the player, using multiplayer-unique group names
func get_selected() -> Array[Entity]:
var selected: Array[Node] = get_tree().get_nodes_in_group('selected-by-'+str(get_tree().get_multiplayer().get_unique_id()))
var selected: Array[Node] = get_tree().get_nodes_in_group('selected-by-' + str(get_tree().get_multiplayer().get_unique_id()))
var selected_entity: Array[Entity]
selected_entity.assign(selected)
return selected_entity
@ -86,29 +84,38 @@ func check_raycast(mouse_pos: Vector2, collision_mask: int = 32768) -> Dictionar
query.collide_with_areas = true
query.collide_with_bodies = false
var space_state = cam.get_world_3d().direct_space_state
#DebugTools.DrawLine(from,to,25.0)
return space_state.intersect_ray(query)
## Deselects all currently selected entities
func deselect_all() -> void:
var selected = get_selected()
for entity:Entity in selected:
for entity: Entity in selected:
entity.deselect()
## Updates selection state of entities based on single-click (raycast) or drag (box) selection [br]
## Iterate on every entities inside the [param selectable-entity] group
func update_selected_units() -> void:
## FIXME: Could be optimized if we store an array of visible entity by adding[br]
## an [Area3D] child of the camera OR changing the group based on if the 3d model is loaded
var units_array = get_tree().get_nodes_in_group("selectable-entity")
var raycast = {}
# Only perform raycast if it's a single click (zero-sized select_box)
if select_box.size == Vector2.ZERO:
raycast = check_raycast(select_box.position,)
if raycast and raycast.collider:
raycast = check_raycast(select_box.position)
if raycast.is_empty():
deselect_all()
return
if raycast.collider:
if debug_mode:
DebugTools.DrawCube(raycast.position,0.02,3.0,Color())
# select entity under mouse
# maybe can be extracted from hover instead?
var entity = raycast.collider.get_parent()
deselect_all()
entity.select()
# BUG: Deselect previous selection
return
for entity: Entity in units_array:
# TODO: Optimize by searching only in spawned chunks
@ -119,6 +126,7 @@ func update_selected_units() -> void:
entity.deselect()
## Draws the selection rectangle during drag or selection, using optimized or styled rendering
func _draw() -> void:
if not (draw_selection or perform_selection):return
if select_box and rect_style:

View file

@ -1,4 +1,5 @@
extends Control
## A utility node for drawing 3D debug visuals (lines, rays, cubes) in screen space.
@export var MouseOverlay: Node
@onready var Cam = get_viewport().get_camera_3d()
@ -7,36 +8,52 @@ extends Control
func _ready() -> void:
if !OS.is_debug_build():
self.queue_free()
return
# Ensure the node processes and draws even when the game is paused.
process_mode = Node.PROCESS_MODE_ALWAYS
# Ensure the node is visible and set to draw in screen space.
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
## A class representing a single debug line with start/end points, color, and duration.
class Line:
var Start:Vector3
var End:Vector3
var LineColor:Color
var time
var time:float
func _init(Start:Vector3, End:Vector3, LineColor, time):
self.Start = Start
self.End = End
self.LineColor = LineColor
self.time = time
## Constructor for DebugLine. [br]
## [param _start] Starting point in 3D space.[br]
## [param _end] Ending point in 3D space.[br]
## [param _color] Color of the line.[br]
## [param _time] Duration the line persists (seconds).
func _init(_Start:Vector3, _End:Vector3, _LineColor:Color, _time:float):
self.Start = _Start
self.End = _End
self.LineColor = _LineColor
self.time = _time
## Array storing all active debug lines.
var Lines = []
## Flag to track if a line was removed, triggering a redraw.
var RemovedLine = false
func _process(delta):
for i in range(len(Lines)):
Lines[i].time -= delta
# Trigger a redraw if lines exist or a line was removed.
if (len(Lines) > 0 || RemovedLine):
queue_redraw() #Calls _draw
RemovedLine = false
func _draw():
# Exit early if no lines to draw or camera is not available.
if Lines.is_empty() or not Cam:
return
for i in range(len(Lines)):
if Lines[i].Start.length() == 0:return
var ScreenPointStart = Cam.unproject_position(Lines[i].Start)
@ -61,57 +78,69 @@ func _draw():
i -= 1
## start point, end point, color, time (optional)
func DrawLine(Start, End, time = 0.0, LineColor = Color(1.0, 0.0, 0.0, 1.0)):
## Draws a line between two 3D points. [br]
## [param start] Starting point in 3D space.[br]
## [param end] Ending point in 3D space.[br]
## [param time] Duration the line persists (seconds, default: 0.0 for one frame).[br]
## [param color] Color of the line (default: red, fully opaque).
func DrawLine(Start, End, time := 0.0, LineColor := Color(1.0, 0.0, 0.0, 1.0)):
Lines.append(Line.new(Start, End, LineColor, time))
## start point, velocity (direction and magnitude), color, time (optional)
func DrawRay(Start, Ray, time = 0.0, LineColor = Color(1.0, 0.0, 0.0, 1.0)):
## Draws a ray from a starting point in a given direction.[br]
## [param start] Starting point in 3D space.[br]
## [param ray] Direction and magnitude of the ray (Vector3).[br]
## [param time] Duration the ray persists (seconds, default: 0.0 for one frame).[br]
## [param color] Color of the ray (default: red, fully opaque).
func DrawRay(Start, Ray, time := 0.0, LineColor := Color(1.0, 0.0, 0.0, 1.0)):
Lines.append(Line.new(Start, Start + Ray, LineColor, time))
## start point, half extents (float), color, time (optional)
func DrawCube(Center, HalfExtents, time = 0.0, LineColor = Color(1.0, 0.0, 0.0, 1.0)):
## Draws a wireframe cube in 3D space.[br]
## [param center] Center point of the cube in 3D space.[br]
## [param half_extents] Half the width of the cube (default: 0.1).[br]
## [param time] Duration the cube persists (seconds, default: 0.0 for one frame).[br]
## [param color] Color of the cube's edges (default: red, fully opaque).
func DrawCube(Center, HalfExtents := 0.1, time := 0.0, LineColor := Color(1.0, 0.0, 0.0, 1.0)):
#Start at the 'top left'
var LinePointStart = Center
LinePointStart.x -= HalfExtents
LinePointStart.y += HalfExtents
LinePointStart.z -= HalfExtents
#Draw top square
# Draw top square (four edges).
var LinePointEnd = LinePointStart + Vector3(0, 0, HalfExtents * 2.0)
DrawLine(LinePointStart, LinePointEnd, LineColor, time);
DrawLine(LinePointStart, LinePointEnd, time, LineColor);
LinePointStart = LinePointEnd
LinePointEnd = LinePointStart + Vector3(HalfExtents * 2.0, 0, 0)
DrawLine(LinePointStart, LinePointEnd, LineColor, time);
DrawLine(LinePointStart, LinePointEnd, time, LineColor);
LinePointStart = LinePointEnd
LinePointEnd = LinePointStart + Vector3(0, 0, -HalfExtents * 2.0)
DrawLine(LinePointStart, LinePointEnd, LineColor, time);
DrawLine(LinePointStart, LinePointEnd, time, LineColor);
LinePointStart = LinePointEnd
LinePointEnd = LinePointStart + Vector3(-HalfExtents * 2.0, 0, 0)
DrawLine(LinePointStart, LinePointEnd, LineColor, time);
DrawLine(LinePointStart, LinePointEnd, time, LineColor);
#Draw bottom square
# Draw bottom square (four edges).
LinePointStart = LinePointEnd + Vector3(0, -HalfExtents * 2.0, 0)
LinePointEnd = LinePointStart + Vector3(0, 0, HalfExtents * 2.0)
DrawLine(LinePointStart, LinePointEnd, LineColor, time);
DrawLine(LinePointStart, LinePointEnd, time, LineColor);
LinePointStart = LinePointEnd
LinePointEnd = LinePointStart + Vector3(HalfExtents * 2.0, 0, 0)
DrawLine(LinePointStart, LinePointEnd, LineColor, time);
DrawLine(LinePointStart, LinePointEnd, time, LineColor);
LinePointStart = LinePointEnd
LinePointEnd = LinePointStart + Vector3(0, 0, -HalfExtents * 2.0)
DrawLine(LinePointStart, LinePointEnd, LineColor, time);
DrawLine(LinePointStart, LinePointEnd, time, LineColor);
LinePointStart = LinePointEnd
LinePointEnd = LinePointStart + Vector3(-HalfExtents * 2.0, 0, 0)
DrawLine(LinePointStart, LinePointEnd, LineColor, time);
DrawLine(LinePointStart, LinePointEnd, time, LineColor);
#Draw vertical lines
# Draw vertical lines (four edges connecting top and bottom squares).
LinePointStart = LinePointEnd
DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0), LineColor, time)
DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0),time, LineColor)
LinePointStart += Vector3(0, 0, HalfExtents * 2.0)
DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0), LineColor, time)
DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0), time, LineColor)
LinePointStart += Vector3(HalfExtents * 2.0, 0, 0)
DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0), LineColor, time)
DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0), time, LineColor)
LinePointStart += Vector3(0, 0, -HalfExtents * 2.0)
DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0), LineColor, time)
DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0), time, LineColor)