89 lines
2.5 KiB
GDScript
89 lines
2.5 KiB
GDScript
@icon("res://addons/arrow3d/arrow_3d.svg")
|
|
@tool
|
|
class_name Arrow3D
|
|
extends Marker3D
|
|
|
|
@export var arrow_size = 1.0 : set = set_size
|
|
@export var arrow_thickness = 0.05 : set = set_thickness
|
|
@export var arrow_material = StandardMaterial3D.new()
|
|
@export var opposite_direction = false : set = flip_direction
|
|
@export var is_centered = false : set = center_arrow
|
|
|
|
@export var head_segments = 6 : set = set_head_segments
|
|
@export var stick_segments = 6 : set = set_stick_segments
|
|
|
|
var arrow_head = MeshInstance3D.new()
|
|
var arrow_head_mesh = CylinderMesh.new()
|
|
var arrow_stick = MeshInstance3D.new()
|
|
var arrow_stick_mesh = CylinderMesh.new()
|
|
var arrow_rig = Node3D.new()
|
|
|
|
func _ready():
|
|
arrow_head_mesh.radial_segments = head_segments
|
|
arrow_stick_mesh.radial_segments = stick_segments
|
|
|
|
gizmo_extents = 0
|
|
arrow_stick.mesh = arrow_stick_mesh
|
|
arrow_stick.material_override = arrow_material
|
|
|
|
# Init arrow head
|
|
arrow_head.mesh = arrow_head_mesh
|
|
arrow_head.material_override = arrow_material
|
|
|
|
# Add to scene
|
|
arrow_rig.add_child(arrow_stick)
|
|
arrow_rig.add_child(arrow_head)
|
|
add_child(arrow_rig)
|
|
|
|
resize_arrow()
|
|
center_arrow(is_centered)
|
|
|
|
func flip_direction(value):
|
|
opposite_direction = value
|
|
resize_arrow()
|
|
|
|
func set_size(size):
|
|
arrow_size = size
|
|
resize_arrow()
|
|
|
|
func set_thickness(thickness):
|
|
arrow_thickness = thickness
|
|
resize_arrow()
|
|
|
|
func set_head_segments(segments):
|
|
head_segments = segments
|
|
arrow_head_mesh.radial_segments = head_segments
|
|
|
|
func set_stick_segments(segments):
|
|
stick_segments = segments
|
|
arrow_stick_mesh.radial_segments = stick_segments
|
|
|
|
func resize_arrow():
|
|
arrow_stick_mesh.bottom_radius = arrow_thickness
|
|
arrow_stick_mesh.top_radius = arrow_thickness
|
|
arrow_stick_mesh.height = (arrow_size / 3) * 2
|
|
arrow_head_mesh.top_radius = 0.0
|
|
arrow_head_mesh.bottom_radius = arrow_thickness * 2
|
|
arrow_head_mesh.height = arrow_size / 3
|
|
arrow_head.rotation_degrees.x = 90 if not opposite_direction else -90
|
|
arrow_stick.rotation_degrees.x = 90 if not opposite_direction else -90
|
|
|
|
if is_centered:
|
|
if opposite_direction:
|
|
arrow_head.position.z = -arrow_size / 2
|
|
arrow_stick.position.z = 0
|
|
else:
|
|
arrow_head.position.z = arrow_size / 2
|
|
arrow_stick.position.z = 0
|
|
else:
|
|
if opposite_direction:
|
|
arrow_head.position.z = -(arrow_stick_mesh.height + arrow_head_mesh.height / 2)
|
|
arrow_stick.position.z = -arrow_stick_mesh.height / 2
|
|
else:
|
|
arrow_head.position.z = arrow_stick_mesh.height + arrow_head_mesh.height / 2
|
|
arrow_stick.position.z = arrow_stick_mesh.height / 2
|
|
|
|
func center_arrow(centered):
|
|
is_centered = centered
|
|
resize_arrow()
|