@tool extends AnimatableBody3D @export_category('Door') @export var interactable: bool = true @export var autoclose_time: float = 0.0 @export var open_sound: AudioStream @export var close_sound: AudioStream @onready var _timer = $Timer @onready var _player = $AudioStreamPlayer3D var _anim: AnimationPlayer var _open = false func _get_configuration_warnings() -> PackedStringArray: var warns = [] var animation_found = false var animation_player: AnimationPlayer for c in get_children(): if c is AnimationPlayer: if animation_found: warns.append('Multiple AnimationPlayers') animation_found = true animation_player = c if not animation_found: warns.append('Add an AnimationPlayer') if animation_found and not animation_player.has_animation('open'): warns.append('AnimationPlayer missing "open" animation') return warns func _ready(): for c in get_children(): if c is AnimationPlayer: _anim = c break _anim.animation_finished.connect(_on_anim_finished) _timer.timeout.connect(_on_close_timer) func _toggle_open(): # Dont allow closing if the timer is running if not _timer.is_stopped(): return if not _open: open() else: close() func _on_anim_finished(_anim_name): _open = !_open func _on_close_timer(): if _open: _toggle_open() func open(): if open_sound: _player.stream = open_sound _player.play() _anim.play('open') if autoclose_time != 0.0: _timer.start(autoclose_time) func close(): if close_sound: _player.stream = close_sound _player.play() _anim.play_backwards('open') func activate(should_open: bool): if should_open: open() else: close() func interact(_other): if not interactable: return _toggle_open()