74 lines
2.5 KiB
GDScript
74 lines
2.5 KiB
GDScript
extends Control
|
|
class_name SelectionManager
|
|
|
|
var selecting:=false
|
|
var drag_start: Vector2
|
|
var select_box: Rect2
|
|
@onready var box_color: Color = ProjectSettings.get_setting("game/interface/selection_rectangle_color",Color("#00ff0066"))
|
|
@onready var box_color_outline: Color = ProjectSettings.get_setting("game/interface/selection_rectangle_color_outline",Color("#00ff00"))
|
|
|
|
@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()
|
|
|
|
|
|
func _ready() -> void:
|
|
if optimized_rect:return
|
|
|
|
|
|
func _unhandled_input(e: InputEvent) -> void:
|
|
if e is InputEventMouseButton and e.button_index == MOUSE_BUTTON_LEFT:
|
|
if e.pressed:
|
|
selecting = true
|
|
drag_start = e.position
|
|
else: # when button is released
|
|
selecting = false
|
|
if drag_start.is_equal_approx(e.position):
|
|
select_box = Rect2(e.position, Vector2.ZERO) # when just clicked
|
|
print("one click")
|
|
|
|
queue_redraw()
|
|
|
|
update_selected_units()
|
|
elif selecting and e is InputEventMouseMotion:
|
|
var x_min = min(drag_start.x, e.position.x)
|
|
var y_min = min(drag_start.y, e.position.y)
|
|
select_box = Rect2(x_min,y_min,
|
|
max(drag_start.x,e.position.x) - x_min,
|
|
max(drag_start.y,e.position.y) - y_min)
|
|
|
|
update_selected_units()
|
|
queue_redraw()
|
|
|
|
|
|
func check_raycast(mouse_pos:Vector2,collision_mask:int=4294967295) -> Dictionary:
|
|
var from = cam.project_ray_origin(mouse_pos)
|
|
var to = from + cam.project_ray_normal(mouse_pos) * 1000 #Magic number
|
|
var query = PhysicsRayQueryParameters3D.new()
|
|
query.from = from ; query.to = to
|
|
query.collision_mask = collision_mask
|
|
var space_state = cam.get_world_3d().direct_space_state
|
|
return space_state.intersect_ray(query)
|
|
|
|
|
|
#HACK :https://www.youtube.com/watch?v=NxW9t-YgJkM
|
|
func update_selected_units() -> void:
|
|
var units_array = get_tree().get_nodes_in_group('selectable-entity')
|
|
var raycast = check_raycast(get_local_mouse_position(),2)
|
|
for entity: Entity in units_array: #TODO: currently searching in all unit in the world. Should search in spawned in the chunk
|
|
if entity.is_in_selection(select_box, cam):
|
|
entity.select()
|
|
elif entity.is_under_mouse(raycast):
|
|
entity.select()
|
|
else:
|
|
entity.deselect()
|
|
|
|
|
|
func _draw() -> void:
|
|
if not selecting:return
|
|
if select_box and rect_style:
|
|
if optimized_rect:
|
|
draw_rect(select_box,box_color)
|
|
draw_rect(select_box,box_color_outline,false,2.0,true)
|
|
elif rect_style:
|
|
draw_style_box(rect_style,select_box)
|