125 lines
2.7 KiB
GDScript
125 lines
2.7 KiB
GDScript
@tool
|
|
extends Node3D
|
|
|
|
|
|
@export_range(1.0, 100000.0, 1.0, "or_greater")
|
|
var medium_distance: float = 25.0
|
|
|
|
@export_range(2.0, 100000.0, 1.0, "or_greater")
|
|
var distant_distance: float = 60.0
|
|
|
|
@export_range(0.0, 100000.0, 1.0, "or_greater")
|
|
var cull_distance: float = 0.0
|
|
|
|
var _elapsed: float = 0.0
|
|
var _active_level: int = -2
|
|
|
|
|
|
func _ready() -> void:
|
|
if Engine.is_editor_hint():
|
|
show_editor_preview()
|
|
set_process(false)
|
|
return
|
|
|
|
set_process(true)
|
|
_update_from_camera()
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
_elapsed += delta
|
|
if _elapsed < 0.15:
|
|
return
|
|
|
|
_elapsed = 0.0
|
|
_update_from_camera()
|
|
|
|
|
|
func configure(
|
|
new_medium_distance: float,
|
|
new_distant_distance: float,
|
|
new_cull_distance: float
|
|
) -> void:
|
|
medium_distance = maxf(new_medium_distance, 1.0)
|
|
distant_distance = maxf(
|
|
new_distant_distance,
|
|
medium_distance + 1.0
|
|
)
|
|
cull_distance = maxf(new_cull_distance, 0.0)
|
|
show_editor_preview()
|
|
|
|
|
|
func show_editor_preview() -> void:
|
|
_active_level = -2
|
|
_set_active_level(0)
|
|
|
|
|
|
func update_for_distance(distance: float) -> void:
|
|
var near_level := get_node_or_null(^"Near") as Node3D
|
|
var medium_level := get_node_or_null(^"Medium") as Node3D
|
|
var distant_level := get_node_or_null(^"Distant") as Node3D
|
|
var target_level := 0
|
|
|
|
if cull_distance > 0.0 and distance >= cull_distance:
|
|
target_level = -1
|
|
elif distant_level != null and distance >= distant_distance:
|
|
target_level = 2
|
|
elif medium_level != null and distance >= medium_distance:
|
|
target_level = 1
|
|
elif near_level == null:
|
|
if medium_level != null:
|
|
target_level = 1
|
|
elif distant_level != null:
|
|
target_level = 2
|
|
else:
|
|
target_level = -1
|
|
|
|
_set_active_level(target_level)
|
|
|
|
|
|
func _update_from_camera() -> void:
|
|
var viewport := get_viewport()
|
|
if viewport == null:
|
|
return
|
|
|
|
var camera := viewport.get_camera_3d()
|
|
if camera == null:
|
|
return
|
|
|
|
update_for_distance(
|
|
camera.global_position.distance_to(global_position)
|
|
)
|
|
|
|
|
|
func _set_active_level(level: int) -> void:
|
|
if bool(get_meta("harvest_hidden", false)):
|
|
_active_level = -2
|
|
_set_level_visible(^"Near", false)
|
|
_set_level_visible(^"Medium", false)
|
|
_set_level_visible(^"Distant", false)
|
|
return
|
|
|
|
if level == _active_level:
|
|
return
|
|
|
|
_active_level = level
|
|
_set_level_visible(^"Near", level == 0)
|
|
_set_level_visible(^"Medium", level == 1)
|
|
_set_level_visible(^"Distant", level == 2)
|
|
|
|
|
|
func set_harvest_hidden(hidden: bool) -> void:
|
|
set_meta("harvest_hidden", hidden)
|
|
_active_level = -2
|
|
if hidden:
|
|
_set_level_visible(^"Near", false)
|
|
_set_level_visible(^"Medium", false)
|
|
_set_level_visible(^"Distant", false)
|
|
else:
|
|
_update_from_camera()
|
|
|
|
|
|
func _set_level_visible(path: NodePath, level_visible: bool) -> void:
|
|
var level := get_node_or_null(path) as Node3D
|
|
if level != null:
|
|
level.visible = level_visible
|