Selection working.
Assuming every single selectable contain an Area3D at the root with selection collision to handle selection
This commit is contained in:
parent
258ffc4523
commit
58df83ec50
5 changed files with 57 additions and 40 deletions
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=12 format=3 uid="uid://qbceryqqfoum"]
|
||||
[gd_scene load_steps=11 format=3 uid="uid://qbceryqqfoum"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bsnc11pwypbny" path="res://packs/Kaykit-Proto/obj/prototypebits_texture.png" id="1_6oykk"]
|
||||
[ext_resource type="Script" uid="uid://b8p60y4eo8w2n" path="res://core/scripts/entity.gd" id="1_w0ui8"]
|
||||
|
@ -8,7 +8,6 @@
|
|||
[ext_resource type="ArrayMesh" uid="uid://cvlxxld3w6siv" path="res://packs/Kaykit-Proto/obj/Dummy_Base_Dummy_Body_Dummy_ArmRight.obj" id="5_w4l2r"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://6h2lg4h0y0ea" path="res://packs/Kaykit-Proto/obj/Dummy_Base_Dummy_Body_Dummy_Head.obj" id="6_5dfyn"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://b7cky6rmvhxl8" path="res://packs/Kaykit-Proto/obj/Dummy_Base_Dummy_Body_Dummy_Target.obj" id="7_d3okb"]
|
||||
[ext_resource type="Texture2D" uid="uid://cg3hn4l231fws" path="res://packs/Kenney-BoardGamesIcon/chess_rook_red.svg" id="8_15r82"]
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_w0ui8"]
|
||||
size = Vector3(1, 2, 1)
|
||||
|
@ -21,10 +20,12 @@ transform = Transform3D(0.9, 0, 0, 0, 0.9, 0, 0, 0, 0.9, 0, 0, 0)
|
|||
script = ExtResource("1_w0ui8")
|
||||
metadata/_custom_type_script = "uid://b8p60y4eo8w2n"
|
||||
|
||||
[node name="StaticBody3D" type="StaticBody3D" parent="."]
|
||||
[node name="SelectionArea" type="Area3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0267677, 0)
|
||||
collision_layer = 32768
|
||||
collision_mask = 0
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D"]
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="SelectionArea"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.11408532, 0)
|
||||
shape = SubResource("BoxShape3D_w0ui8")
|
||||
|
||||
|
@ -51,8 +52,3 @@ mesh = ExtResource("6_5dfyn")
|
|||
[node name="DummyBaseDummyBodyDummyTarget" type="MeshInstance3D" parent="."]
|
||||
material_override = SubResource("StandardMaterial3D_th4ew")
|
||||
mesh = ExtResource("7_d3okb")
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="."]
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
texture = ExtResource("8_15r82")
|
||||
|
|
|
@ -7,7 +7,7 @@ ignore_paths=Array[String]([])
|
|||
|
||||
[patterns]
|
||||
|
||||
patterns=[["\\bTODO\\b", Color(0.588235, 0.945098, 0.678431, 1), 0], ["\\bHACK\\b", Color(0.835294, 0.737255, 0.439216, 1), 0], ["\\bFIXME\\b", Color(0.835294, 0.439216, 0.439216, 1), 0]]
|
||||
patterns=[["\\bTODO\\b", Color(0.588235, 0.945098, 0.678431, 1), 0], ["\\bHACK\\b", Color(0.835294, 0.737255, 0.439216, 1), 0], ["\\bFIXME\\b", Color(0.835294, 0.439216, 0.439216, 1), 0], ["\\bBUG\\b", Color(0.9607843, 0.48682597, 0.4509804, 1), 0]]
|
||||
|
||||
[config]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@icon('uid://br8ndde8qty32')
|
||||
extends Node
|
||||
extends Node3D
|
||||
class_name Entity
|
||||
|
||||
|
||||
|
@ -11,8 +11,8 @@ class_name Entity
|
|||
## Is a node, because we want to deactivate rendering when out of camera and only simulating the world.
|
||||
## Plus, only the entity is replicated in multiplayer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
add_to_group('entity')
|
||||
add_to_group('selectable-entity')
|
||||
|
||||
|
||||
|
@ -26,17 +26,8 @@ func is_in_selection(selection_box:Rect2,player_cam:Camera3D) -> bool:
|
|||
return false
|
||||
|
||||
|
||||
## Check if the entity is under the raycast (usually made by [method SelectionManager.check_raycast])
|
||||
## and colliding with entity bouding box
|
||||
func is_under_mouse(raycast:Dictionary) -> bool:
|
||||
if raycast:
|
||||
var aabb:AABB = get_entity_aabb()
|
||||
return aabb.has_point(raycast.position)
|
||||
|
||||
return false
|
||||
|
||||
|
||||
## Calculate the node bouding box
|
||||
## @deprecated
|
||||
func get_entity_aabb(node: Node3D = self, ignore_top_level: bool = true, bounds_transform: Transform3D = Transform3D()) -> AABB:
|
||||
if node == null: return AABB()
|
||||
var box: AABB
|
||||
|
|
|
@ -11,6 +11,7 @@ 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:
|
||||
|
@ -48,6 +49,8 @@ func _unhandled_input(e: InputEvent) -> void:
|
|||
max(drag_start.y, e.position.y) - y_min)
|
||||
|
||||
queue_redraw()
|
||||
if !draw_selection and e is InputEventMouseMotion:
|
||||
check_hover()
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
|
@ -56,38 +59,60 @@ func _physics_process(_delta: float) -> void:
|
|||
perform_selection = false
|
||||
|
||||
|
||||
func check_raycast(mouse_pos: Vector2, collision_mask: int = 4294967295) -> Dictionary:
|
||||
func check_hover():
|
||||
# TODO: Hovering and display names
|
||||
var selected = get_selected()
|
||||
if selected.size() > 0:
|
||||
hovercontrol.text = selected[0].name
|
||||
else:
|
||||
hovercontrol.text = ""
|
||||
|
||||
hovercontrol.queue_redraw()
|
||||
pass
|
||||
|
||||
|
||||
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_entity: Array[Entity]
|
||||
selected_entity.assign(selected)
|
||||
return selected_entity
|
||||
|
||||
|
||||
## [param collision_mask] is 32768 by default, so the collision channel 16
|
||||
func check_raycast(mouse_pos: Vector2, collision_mask: int = 32768) -> 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 query = PhysicsRayQueryParameters3D.create(from,to,collision_mask)
|
||||
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)
|
||||
|
||||
|
||||
func deselect_all() -> void:
|
||||
var selected = get_selected()
|
||||
for entity:Entity in selected:
|
||||
entity.deselect()
|
||||
|
||||
|
||||
func update_selected_units() -> void:
|
||||
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:
|
||||
print("found ",raycast.collider.name)
|
||||
#breakpoint
|
||||
|
||||
raycast = check_raycast(select_box.position,)
|
||||
if raycast and raycast.collider:
|
||||
# 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
|
||||
if select_box.size == Vector2.ZERO:
|
||||
# Single click: select entity under mouse via raycast
|
||||
if raycast and entity.is_under_mouse(raycast):
|
||||
entity.select()
|
||||
else:
|
||||
entity.deselect()
|
||||
else:
|
||||
# Drag: select entities within the selection box
|
||||
# select entities within the selection/draggin box
|
||||
if entity.is_in_selection(select_box, cam):
|
||||
entity.select()
|
||||
else:
|
||||
|
|
|
@ -109,6 +109,11 @@ locale/locale_filter_mode=1
|
|||
locale/language_filter=["en", "fr"]
|
||||
locale/country_filter=["FR"]
|
||||
|
||||
[layer_names]
|
||||
|
||||
3d_physics/layer_1="Static"
|
||||
3d_physics/layer_16="Selection"
|
||||
|
||||
[physics]
|
||||
|
||||
3d/run_on_separate_thread=true
|
||||
|
|
Loading…
Reference in a new issue