Assuming every single selectable contain an Area3D at the root with selection collision to handle selection
75 lines
2.4 KiB
GDScript
75 lines
2.4 KiB
GDScript
@icon('uid://br8ndde8qty32')
|
|
extends Node3D
|
|
class_name Entity
|
|
|
|
|
|
## Base entity class for everything not static.
|
|
##
|
|
## Should be the parent of every units, buildings,
|
|
## npc, loot, and everything that the player can interact with
|
|
##
|
|
## 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('selectable-entity')
|
|
|
|
|
|
## Check if the entity is contained in the [Rect2] [param selection_box] of the player.
|
|
## Need the [Camera3D] of the player to work
|
|
func is_in_selection(selection_box:Rect2,player_cam:Camera3D) -> bool:
|
|
if selection_box.size: # Checking if size is 0,0
|
|
var p = player_cam.unproject_position(global_position)
|
|
return selection_box.has_point(p)
|
|
|
|
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
|
|
var node_transform: Transform3D
|
|
|
|
# we are going down the child chain, we want the aabb of each subsequent node to be on the same axis as the parent
|
|
if bounds_transform.is_equal_approx(Transform3D()):
|
|
node_transform = node.global_transform
|
|
else:
|
|
node_transform = bounds_transform
|
|
|
|
# no more nodes. return default aabb
|
|
if node == null:
|
|
return AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4))
|
|
|
|
# makes sure the transform we get isn't distorted
|
|
var top_xform : Transform3D = node_transform.affine_inverse() * node.global_transform
|
|
|
|
# convert the node into visualinstance3D to access get_aabb() function.
|
|
var visual_result : VisualInstance3D = node as VisualInstance3D
|
|
if visual_result != null:
|
|
box = visual_result.get_aabb()
|
|
else:
|
|
box = AABB()
|
|
|
|
# xforms the transform with the box aabb for proper alignment I believe?
|
|
box = top_xform * box
|
|
# recursion
|
|
for i : int in node.get_child_count():
|
|
var child : Node3D = node.get_child(i) as Node3D
|
|
if child && !(ignore_top_level && child.top_level):
|
|
var child_box : AABB = get_entity_aabb(child, ignore_top_level, transform)
|
|
box = box.merge(child_box)
|
|
|
|
return box
|
|
|
|
|
|
func select():
|
|
add_to_group('selected-by-'+str(get_tree().get_multiplayer().get_unique_id()))
|
|
print(self.name," selected"," by "+str(get_tree().get_multiplayer().get_unique_id()))
|
|
|
|
|
|
func deselect():
|
|
remove_from_group('selected-by-'+str(get_tree().get_multiplayer().get_unique_id()))
|
|
print(self.name," unselected")
|