79 lines
2.4 KiB
GDScript
79 lines
2.4 KiB
GDScript
class_name Tile
|
|
extends Node3D
|
|
|
|
@export var display_texture: Texture2D
|
|
@export var inward_face_flip := true
|
|
@export var continuous_billboard := true
|
|
@export_range(0.0, 1.0, 0.01) var pulse_strength := 0.08
|
|
@export_range(0.05, 4.0, 0.05) var pulse_frequency_hz := 0.45
|
|
var tile_material: StandardMaterial3D
|
|
var base_scale := Vector3.ONE
|
|
var base_emission_energy := 1.0
|
|
var scale_multiplier := 1.0
|
|
var phase_offset := 0.0
|
|
var viewer_camera: Node3D
|
|
|
|
@onready var mesh_instance := $MeshInstance3D as MeshInstance3D
|
|
@onready var animation_player := $AnimationPlayer2 as AnimationPlayer
|
|
|
|
func _ready() -> void:
|
|
var source_material := ((mesh_instance.mesh as PlaneMesh).material as StandardMaterial3D)
|
|
if source_material != null:
|
|
tile_material = source_material.duplicate() as StandardMaterial3D
|
|
mesh_instance.material_override = tile_material
|
|
|
|
if tile_material != null and display_texture != null:
|
|
tile_material.albedo_texture = display_texture
|
|
tile_material.emission_texture = display_texture
|
|
base_emission_energy = tile_material.emission_energy_multiplier
|
|
|
|
base_scale = mesh_instance.scale
|
|
visible = true
|
|
if animation_player != null:
|
|
animation_player.play("flying")
|
|
|
|
func _process(_delta: float) -> void:
|
|
if viewer_camera != null and continuous_billboard:
|
|
look_at(viewer_camera.global_position, Vector3.UP)
|
|
if inward_face_flip:
|
|
rotate_object_local(Vector3.UP, PI)
|
|
|
|
var osc := Time.get_ticks_msec() * 0.001
|
|
var pulse := 1.0 + sin((osc * TAU * pulse_frequency_hz) + phase_offset) * pulse_strength
|
|
mesh_instance.scale = base_scale * scale_multiplier * pulse
|
|
|
|
if tile_material != null:
|
|
tile_material.emission_energy_multiplier = base_emission_energy * (0.9 + pulse_strength)
|
|
|
|
func place_on_shell(
|
|
center: Vector3,
|
|
direction: Vector3,
|
|
radius: float,
|
|
camera: Node3D
|
|
) -> void:
|
|
viewer_camera = camera
|
|
global_position = center + (direction.normalized() * radius)
|
|
|
|
if viewer_camera != null:
|
|
look_at(viewer_camera.global_position, Vector3.UP)
|
|
if inward_face_flip:
|
|
rotate_object_local(Vector3.UP, PI)
|
|
|
|
func set_scale_multiplier(multiplier: float) -> void:
|
|
scale_multiplier = max(multiplier, 0.05)
|
|
|
|
func set_phase_offset(phase: float) -> void:
|
|
phase_offset = phase
|
|
|
|
func set_display_texture(texture: Texture2D) -> void:
|
|
if texture == null:
|
|
return
|
|
|
|
display_texture = texture
|
|
if tile_material != null:
|
|
tile_material.albedo_texture = texture
|
|
tile_material.emission_texture = texture
|
|
|
|
func set_global_position_unclamped(pos: Vector3) -> void:
|
|
global_position = pos
|