49 lines
1.5 KiB
GDScript3
49 lines
1.5 KiB
GDScript3
|
|
class_name Interactable extends Node3D
|
||
|
|
|
||
|
|
@export var interaction_ui: PackedScene = null
|
||
|
|
|
||
|
|
@onready var view: Node3D = $View
|
||
|
|
@onready var frame: Sprite3D = $Frame
|
||
|
|
|
||
|
|
var shown : bool = false
|
||
|
|
var hover : bool = false
|
||
|
|
var collected : bool = false
|
||
|
|
|
||
|
|
var tween: Tween = null
|
||
|
|
|
||
|
|
func _ready() -> void:
|
||
|
|
view.scale = Vector3.ZERO
|
||
|
|
frame.modulate.a = 0
|
||
|
|
|
||
|
|
func _process(_delta: float) -> void:
|
||
|
|
_process_hover()
|
||
|
|
_process_billboard()
|
||
|
|
|
||
|
|
func _process_billboard() -> void:
|
||
|
|
if shown:
|
||
|
|
var player_view := State.player_view
|
||
|
|
look_at(player_view.global_position, Vector3.UP, true)
|
||
|
|
|
||
|
|
func _process_hover() -> void:
|
||
|
|
if hover and not shown:
|
||
|
|
shown = true
|
||
|
|
view.scale = Vector3.ZERO
|
||
|
|
frame.modulate = Color.TRANSPARENT
|
||
|
|
view.rotation.z = -PI*0.5 # Godot angle wrapping is ... something
|
||
|
|
if tween: tween.kill()
|
||
|
|
tween = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
|
||
|
|
tween.parallel().tween_property(view, "scale", Vector3.ONE, 1.0).set_delay(0.5)
|
||
|
|
tween.parallel().tween_property(view, "rotation:z", 0, 0.8).set_delay(0.5)
|
||
|
|
tween.parallel().tween_property(frame, "modulate:a", 1.0, 2.0)
|
||
|
|
|
||
|
|
elif not hover and shown:
|
||
|
|
shown = false
|
||
|
|
if tween: tween.kill()
|
||
|
|
tween = create_tween().set_ease(Tween.EASE_IN).set_trans(Tween.TRANS_BACK)
|
||
|
|
tween.parallel().tween_property(view, "scale", Vector3.ZERO, 0.3)
|
||
|
|
tween.parallel().tween_property(frame, "modulate:a", 0, 0.6)
|
||
|
|
|
||
|
|
func _input(event: InputEvent) -> void:
|
||
|
|
if hover and shown and event is InputEventMouseButton and event.is_action_pressed("ui_select"):
|
||
|
|
collected = true
|
||
|
|
|