Add spine and dialogic museums

This commit is contained in:
2026-06-15 00:35:27 +02:00
parent 12efcbb4a6
commit a621366717
1088 changed files with 74220 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
@tool
class_name SpineDialogicPortrait
extends DialogicPortrait
#region EXPORTS
@export_group("Main")
## Path to the .tres SpineSkeletonDataResource file.
@export_file var spine_skeleton_data_file := ""
func _ready() -> void:
$SpineSprite.animation_completed.connect(_on_animation_completed)
func _on_animation_completed(spine_sprite: Object, animation_state: SpineAnimationState, track_entry: SpineTrackEntry) -> void:
print(track_entry)
pass
#region DIALOGIC PORTRAIT OVERRIDES
## If the next portrait uses the same scene, reuse this instance rather than
## creating a new one (allows smooth animation transitions).
func _should_do_portrait_update(_character: DialogicCharacter, _portrait: String) -> bool:
return true
## Called by Dialogic when the portrait is first shown or changed.
## [param passed_character] — the DialogicCharacter resource.
## [param passed_portrait] — the portrait name (e.g. "Idle", "Walk").
##
## Export overrides (like spine_skeleton_data_file) are applied by Dialogic
## *before* this method is called.
func _update_portrait(passed_character: DialogicCharacter, passed_portrait: String) -> void:
apply_character_and_portrait(passed_character, passed_portrait)
# Load the skeleton data file (export override from character portrait config).
if not spine_skeleton_data_file.is_empty() and ResourceLoader.exists(spine_skeleton_data_file):
var skel_res := load(spine_skeleton_data_file)
if skel_res:
$SpineSprite.skeleton_data_res = skel_res
# Anchor the SpineSprite at the root origin. Dialogic treats the portrait
# root's (0,0) as the bottom-center pivot. Scale is applied by the portrait
# container, so we reset the SpineSprite's own scale to 1.
$SpineSprite.position = Vector2.ZERO
$SpineSprite.scale = Vector2.ONE
# Play the animation matching the portrait name (loop on track 0).
var anim_name := passed_portrait
var loop := anim_name == "walk"
$SpineSprite.get_animation_state().set_animation(anim_name, loop, 0)
## Returns the bounding rectangle of this portrait relative to the root node.
## The root node's origin (0,0) is the spine skeleton's root bone.
## Dialogic uses this rect to compute the scale/offset for the portrait.
func _get_covered_rect() -> Rect2:
if not is_instance_valid($SpineSprite):
return Rect2()
# Use the skeleton's own bounds — the rect is in the skeleton's local
# space, relative to the root bone at (0,0).
return $SpineSprite.get_skeleton().get_bounds()
## Called by Dialogic when the character should be mirrored (e.g. facing left
## on a right-side position).
func _set_mirror(mirror: bool) -> void:
if not is_instance_valid($SpineSprite):
return
# Mirror by flipping the skeleton horizontally.
$SpineSprite.get_skeleton().set_scale_x(-1.0 if mirror else 1.0)
## Called when this character becomes the active speaker.
func _highlight() -> void:
if not is_instance_valid($SpineSprite):
return
# Visual feedback: brighten slightly when speaking.
$SpineSprite.modulate = Color(1.2, 1.2, 1.2, 1.0)
## Called when this character stops being the active speaker.
func _unhighlight() -> void:
if not is_instance_valid($SpineSprite):
return
$SpineSprite.modulate = Color(1.0, 1.0, 1.0, 1.0)

View File

@@ -0,0 +1 @@
uid://ytkf0l6cg5ny

View File

@@ -0,0 +1,15 @@
[gd_scene format=3 uid="uid://ds0pygab23pfk"]
[ext_resource type="Script" uid="uid://ytkf0l6cg5ny" path="res://core/spine_dialogic_portrait.gd" id="1_qspp1"]
[ext_resource type="SpineSkeletonDataResource" uid="uid://c53t4xfil8g8g" path="res://docs/museums/spine/assets/raptor/raptor-data.tres" id="2_k3iyv"]
[node name="SpineDialogicPortrait" type="Node2D" unique_id=1507714417]
script = ExtResource("1_qspp1")
spine_skeleton_data_file = "uid://c53t4xfil8g8g"
[node name="SpineSprite" type="SpineSprite" parent="." unique_id=1962155358]
skeleton_data_res = ExtResource("2_k3iyv")
preview_skin = "Default"
preview_animation = "-- Empty --"
preview_frame = false
preview_time = 0.0