Wire all twelve levels with billboard prefabs, autoload systems (inventory, achievements, mock shop, DE/EN/BY), and satire audio locks so the Title→End flow is playable with placeholder assets.
37 lines
1.1 KiB
GDScript
37 lines
1.1 KiB
GDScript
extends Node3D
|
|
class_name BillboardSprite
|
|
## 2D sprite on a 3D plane that always faces the camera (Mario-tree style).
|
|
## TODO: Swap placeholder textures for real pixel art.
|
|
|
|
@export var texture: Texture2D
|
|
@export var pixel_size: float = 0.05
|
|
@export var modulate_color: Color = Color.WHITE
|
|
|
|
@onready var _mesh_instance: MeshInstance3D = $MeshInstance3D
|
|
|
|
func _ready() -> void:
|
|
_apply()
|
|
|
|
func set_texture(tex: Texture2D) -> void:
|
|
texture = tex
|
|
_apply()
|
|
|
|
func _apply() -> void:
|
|
if _mesh_instance == null:
|
|
return
|
|
var plane := PlaneMesh.new()
|
|
plane.size = Vector2(1.0, 1.0)
|
|
_mesh_instance.mesh = plane
|
|
var mat := StandardMaterial3D.new()
|
|
mat.billboard_mode = BaseMaterial3D.BILLBOARD_ENABLED
|
|
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
|
mat.texture_filter = BaseMaterial3D.TEXTURE_FILTER_NEAREST
|
|
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR
|
|
mat.alpha_scissor_threshold = 0.1
|
|
mat.albedo_color = modulate_color
|
|
if texture != null:
|
|
mat.albedo_texture = texture
|
|
var w := float(texture.get_width()) * pixel_size
|
|
var h := float(texture.get_height()) * pixel_size
|
|
plane.size = Vector2(w, h)
|
|
_mesh_instance.material_override = mat
|