Skip to content

Instantly share code, notes, and snippets.

@Shilo
Last active November 26, 2024 17:08
Show Gist options
  • Save Shilo/137a2bd13b14f69df1f5a8011f48a710 to your computer and use it in GitHub Desktop.
Save Shilo/137a2bd13b14f69df1f5a8011f48a710 to your computer and use it in GitHub Desktop.
Godot 4 VisibleOnScreenEnabler2D subclass that will also hide enable_node to stop rendering also.
class_name VisibleOnScreenActivator2D extends VisibleOnScreenEnabler2D
@export var activate_visibility: bool = true
@export var auto_rect: bool = false
@export_group("Debug", "debug_")
@export var debug_enabled: bool = false
@export var debug_color: Color = Color(Color.YELLOW, 0.1)
var _activate_node_path: NodePath
func _init(init_enable_node_path: NodePath = NodePath()) -> void:
_activate_node_path = init_enable_node_path if init_enable_node_path else enable_node_path
enable_node_path = ""
func _ready() -> void:
if !visible:
queue_free()
return
if activate_visibility:
_activate_visibility()
else:
enable_node_path = _activate_node_path
_activate_node_path = ""
if auto_rect:
_auto_rect()
func _activate_visibility() -> void:
var activate_node := _prepare_activate_node()
if not activate_node:
return
enable_node_path = activate_node.get_path()
activate_node.hide()
screen_exited.connect(activate_node.hide)
screen_entered.connect(activate_node.show)
func _prepare_activate_node() -> CanvasItem:
if _activate_node_path.is_empty():
return null
var activate_node := get_node(_activate_node_path)
if activate_node is not CanvasItem:
return null
if activate_node == get_parent():
reparent.call_deferred(activate_node.get_parent())
return activate_node
func _draw() -> void:
if !debug_enabled:
return
draw_rect(rect, debug_color)
func _auto_rect() -> void:
var enable_node: Node = get_node(enable_node_path)
if !enable_node:
return
if enable_node.has_method(&"get_rect") and enable_node.has_method(&"to_global"):
rect = enable_node.get_rect()
rect.position = enable_node.to_global(rect.position)
else:
rect = Rect2()
var children := enable_node.get_children()
while children:
var child = children.pop_back();
children.append_array(child.get_children());
if child is not VisibleOnScreenNotifier2D and child.has_method(&"get_rect") and child.has_method(&"to_global"):
var child_rect: Rect2 = child.get_rect()
if not child_rect:
continue
child_rect.position = child.to_global(child_rect.position)
rect = rect.merge(child_rect) if rect else child_rect
if enable_node.has_method(&"to_local"):
rect.position = enable_node.to_local(rect.position)
elif enable_node.has_method(&"get_global_position"):
rect.position -= enable_node.get_global_position()
func grow_rect(amount: float) -> void:
rect = rect.grow(amount)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment