mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 07:14:55 +08:00
[godot] Added SpineAnimationTrack to sequence Spine animations with AnimationPlayer, see examples/08-annimation-player
This commit is contained in:
parent
9f5eaf89a8
commit
a09e765c33
@ -6,5 +6,4 @@
|
||||
[resource]
|
||||
atlas_res = ExtResource( 1 )
|
||||
skeleton_file_res = ExtResource( 2 )
|
||||
animations = null
|
||||
skins = null
|
||||
default_mix = 0.2
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
extends Node2D
|
||||
|
||||
onready var player = $AnimationPlayer
|
||||
|
||||
func _ready():
|
||||
player.play("walk-run-die")
|
||||
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,7 @@ config_version=4
|
||||
[application]
|
||||
|
||||
config/name="spine-godot-examples"
|
||||
run/main_scene="res://examples/07-slot-node/slot-node.tscn"
|
||||
run/main_scene="res://examples/08-animation-player/animation-player.tscn"
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.png"
|
||||
|
||||
|
||||
229
spine-godot/spine_godot/SpineAnimationTrack.cpp
Normal file
229
spine-godot/spine_godot/SpineAnimationTrack.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
#include "SpineAnimationTrack.h"
|
||||
#include "core/engine.h"
|
||||
#include "scene/animation/animation_player.h"
|
||||
#include "scene/resources/animation.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
#include "editor/plugins/animation_player_editor_plugin.h"
|
||||
#endif
|
||||
|
||||
void SpineAnimationTrack::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_track_index", "track_index"), &SpineAnimationTrack::set_track_index);
|
||||
ClassDB::bind_method(D_METHOD("get_track_index"), &SpineAnimationTrack::get_track_index);
|
||||
ClassDB::bind_method(D_METHOD("set_animation_name", "animation_name"), &SpineAnimationTrack::set_animation_name);
|
||||
ClassDB::bind_method(D_METHOD("get_animation_name"), &SpineAnimationTrack::get_animation_name);
|
||||
ClassDB::bind_method(D_METHOD("set_loop", "loop"), &SpineAnimationTrack::set_loop);
|
||||
ClassDB::bind_method(D_METHOD("get_loop"), &SpineAnimationTrack::get_loop);
|
||||
ClassDB::bind_method(D_METHOD("set_animation_time", "time"), &SpineAnimationTrack::set_animation_time);
|
||||
ClassDB::bind_method(D_METHOD("get_animation_time"), &SpineAnimationTrack::get_animation_time);
|
||||
ClassDB::bind_method(D_METHOD("update_animation_state", "spine_sprite"), &SpineAnimationTrack::update_animation_state);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "track_index", PROPERTY_HINT_RANGE, "0,256,0"), "set_track_index", "get_track_index");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation_name"), "set_animation_name", "get_animation_name");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "get_loop");
|
||||
#if VERSION_MAJOR > 3
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "animation_time"), "set_animation_time", "get_animation_time");
|
||||
#else
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "animation_time"), "set_animation_time", "get_animation_time");
|
||||
#endif
|
||||
}
|
||||
|
||||
SpineAnimationTrack::SpineAnimationTrack(): track_index(-1), loop(false), animation_time(0), sprite(nullptr) {
|
||||
}
|
||||
|
||||
void SpineAnimationTrack::set_track_index(int _track_index) {
|
||||
track_index = _track_index;
|
||||
}
|
||||
|
||||
int SpineAnimationTrack::get_track_index() {
|
||||
return track_index;
|
||||
}
|
||||
|
||||
void SpineAnimationTrack::_notification(int what) {
|
||||
switch(what) {
|
||||
case NOTIFICATION_PARENTED: {
|
||||
sprite = Object::cast_to<SpineSprite>(get_parent());
|
||||
if (sprite) {
|
||||
sprite->connect("before_animation_state_update", this, "update_animation_state");
|
||||
} else {
|
||||
WARN_PRINT("SpineAnimationTrack parent is not a SpineSprite.");
|
||||
}
|
||||
NOTIFY_PROPERTY_LIST_CHANGED();
|
||||
break;
|
||||
}
|
||||
case NOTIFICATION_READY: {
|
||||
setup_animation_player();
|
||||
break;
|
||||
}
|
||||
case NOTIFICATION_UNPARENTED: {
|
||||
if (sprite) {
|
||||
sprite->disconnect("before_animation_state_update", this, "update_animation_state");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpineAnimationTrack::setup_animation_player() {
|
||||
if (!sprite) return;
|
||||
if (!sprite->get_skeleton_data_res().is_valid() || !sprite->get_skeleton_data_res()->is_skeleton_data_loaded()) return;
|
||||
|
||||
// If we don't have a track index yet, find the highest track number used
|
||||
// by existing tracks.
|
||||
if (track_index < 0) {
|
||||
int highest_track_number = -1;
|
||||
for (int i = 0; i < sprite->get_child_count(); i++) {
|
||||
auto other_track = Object::cast_to<SpineAnimationTrack>(sprite->get_child(i));
|
||||
if (other_track) {
|
||||
if (other_track->track_index > highest_track_number)
|
||||
highest_track_number = other_track->track_index;
|
||||
}
|
||||
}
|
||||
track_index = highest_track_number + 1;
|
||||
}
|
||||
|
||||
// Find the animation player under the track and reset its animation. Create a new one
|
||||
// if there isn't one already.
|
||||
AnimationPlayer *animation_player = nullptr;
|
||||
for (int i = 0; i < get_child_count(); i++) {
|
||||
animation_player = Object::cast_to<AnimationPlayer>(get_child(i));
|
||||
if (animation_player) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!animation_player) {
|
||||
animation_player = memnew(AnimationPlayer);
|
||||
animation_player->set_name(String("Track ") + String::num_int64(track_index));
|
||||
add_child(animation_player);
|
||||
animation_player->set_owner(sprite->get_owner());
|
||||
} else {
|
||||
List<StringName> animation_names;
|
||||
animation_player->get_animation_list(&animation_names);
|
||||
for (int i = 0; i < animation_name.size(); i++) {
|
||||
animation_player->remove_animation(animation_names[i]);
|
||||
}
|
||||
}
|
||||
|
||||
auto skeleton_data = sprite->get_skeleton_data_res()->get_skeleton_data();
|
||||
auto &animations = skeleton_data->getAnimations();
|
||||
for (int i = 0; i < animations.size(); i++) {
|
||||
auto &animation = animations[i];
|
||||
Ref<Animation> animation_ref = create_animation(animation, false);
|
||||
animation_player->add_animation(animation_ref->get_name(), animation_ref);
|
||||
Ref<Animation> animation_looped_ref = create_animation(animation, true);
|
||||
animation_player->add_animation(animation_looped_ref->get_name(), animation_looped_ref);
|
||||
}
|
||||
Ref<Animation> reset_animation_ref;
|
||||
INSTANTIATE(reset_animation_ref);
|
||||
reset_animation_ref->set_name("RESET");
|
||||
reset_animation_ref->set_loop(true);
|
||||
reset_animation_ref->set_length(0.5f);
|
||||
reset_animation_ref->add_track(Animation::TYPE_VALUE);
|
||||
reset_animation_ref->track_set_path(0, NodePath(".:animation_name"));
|
||||
reset_animation_ref->track_insert_key(0, 0, "");
|
||||
animation_player->add_animation(reset_animation_ref->get_name(), reset_animation_ref);
|
||||
animation_player->add_animation("-- Empty --", reset_animation_ref);
|
||||
|
||||
this->animation_player = animation_player;
|
||||
}
|
||||
|
||||
Ref<Animation> SpineAnimationTrack::create_animation(spine::Animation *animation, bool loop) {
|
||||
float duration = animation->getDuration();
|
||||
if (duration == 0) duration = 0.5;
|
||||
|
||||
Ref<Animation> animation_ref;
|
||||
INSTANTIATE(animation_ref);
|
||||
animation_ref->set_name(String(animation->getName().buffer()) + (loop ? "" : "_looped"));
|
||||
animation_ref->set_loop(!loop);
|
||||
animation_ref->set_length(duration);
|
||||
|
||||
animation_ref->add_track(Animation::TYPE_VALUE);
|
||||
animation_ref->track_set_path(0, NodePath(".:animation_name"));
|
||||
animation_ref->track_insert_key(0, 0, animation->getName().buffer());
|
||||
|
||||
animation_ref->add_track(Animation::TYPE_VALUE);
|
||||
animation_ref->track_set_path(1, NodePath(".:animation_time"));
|
||||
animation_ref->track_insert_key(1, 0, 0);
|
||||
animation_ref->track_insert_key(1, duration, duration);
|
||||
|
||||
animation_ref->add_track(Animation::TYPE_VALUE);
|
||||
animation_ref->track_set_path(2, NodePath(".:loop"));
|
||||
animation_ref->track_insert_key(2, 0, !loop);
|
||||
|
||||
return animation_ref;
|
||||
}
|
||||
|
||||
void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite) {
|
||||
sprite = Object::cast_to<SpineSprite>(variant_sprite);
|
||||
if (!sprite) return;
|
||||
if (!sprite->get_skeleton_data_res().is_valid() || !sprite->get_skeleton_data_res()->is_skeleton_data_loaded()) return;
|
||||
if (track_index < 0) return;
|
||||
|
||||
spine::AnimationState *animation_state = sprite->get_animation_state()->get_spine_object();
|
||||
if (!animation_state) return;
|
||||
spine::Skeleton *skeleton = sprite->get_skeleton()->get_spine_object();
|
||||
if (!skeleton) return;
|
||||
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
// When the animation dock is no longer visible, reset the skeleton.
|
||||
if (!AnimationPlayerEditor::singleton->is_visible_in_tree()) {
|
||||
skeleton->setToSetupPose();
|
||||
animation_state->clearTracks();
|
||||
animation_state->setTimeScale(1);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (track_index == 0) skeleton->setToSetupPose();
|
||||
animation_state->setTimeScale(0);
|
||||
animation_state->clearTrack(track_index);
|
||||
if (!EMPTY(animation_name)) {
|
||||
auto entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
|
||||
entry->setMixDuration(0);
|
||||
entry->setTrackTime(animation_time);
|
||||
}
|
||||
} else {
|
||||
auto current_entry = animation_state->getCurrent(track_index);
|
||||
if (current_entry) {
|
||||
if (animation_name != current_entry->getAnimation()->getName().buffer() || current_entry->getLoop() != loop) {
|
||||
if (!EMPTY(animation_name))
|
||||
animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
|
||||
else
|
||||
animation_state->setEmptyAnimation(track_index, 0);
|
||||
}
|
||||
} else {
|
||||
if (!EMPTY(animation_name))
|
||||
animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
|
||||
else
|
||||
animation_state->setEmptyAnimation(track_index, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpineAnimationTrack::set_animation_name(const String& _animation_name) {
|
||||
animation_name = _animation_name;
|
||||
}
|
||||
|
||||
String SpineAnimationTrack::get_animation_name() {
|
||||
return animation_name;
|
||||
}
|
||||
|
||||
void SpineAnimationTrack::set_loop(bool _loop) {
|
||||
loop = _loop;
|
||||
}
|
||||
|
||||
bool SpineAnimationTrack::get_loop() {
|
||||
return loop;
|
||||
}
|
||||
|
||||
void SpineAnimationTrack::set_animation_time(float _animation_time) {
|
||||
animation_time = _animation_time;
|
||||
}
|
||||
|
||||
float SpineAnimationTrack::get_animation_time() {
|
||||
return animation_time;
|
||||
}
|
||||
71
spine-godot/spine_godot/SpineAnimationTrack.h
Normal file
71
spine-godot/spine_godot/SpineAnimationTrack.h
Normal file
@ -0,0 +1,71 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef GODOT_SPINEANIMATIONTRACK_H
|
||||
#define GODOT_SPINEANIMATIONTRACK_H
|
||||
|
||||
#include "SpineCommon.h"
|
||||
#include "SpineSprite.h"
|
||||
#include "scene/animation/animation_player.h"
|
||||
#include "scene/resources/animation.h"
|
||||
|
||||
class SpineAnimationTrack : public Node {
|
||||
GDCLASS(SpineAnimationTrack, Node)
|
||||
protected:
|
||||
int track_index;
|
||||
String animation_name;
|
||||
String last_animation_name;
|
||||
bool loop;
|
||||
float animation_time;
|
||||
SpineSprite *sprite;
|
||||
AnimationPlayer *animation_player;
|
||||
|
||||
static void _bind_methods();
|
||||
void _notification(int what);
|
||||
void setup_animation_player();
|
||||
Ref<Animation> create_animation(spine::Animation *animation, bool loop);
|
||||
void _on_before_world_transforms_change(const Variant& _sprite);
|
||||
void update_animation_state(const Variant &variant_sprite);
|
||||
public:
|
||||
SpineAnimationTrack();
|
||||
|
||||
void set_track_index(int _track_index);
|
||||
int get_track_index();
|
||||
|
||||
void set_animation_name(const String& _animation_name);
|
||||
String get_animation_name();
|
||||
|
||||
void set_loop(bool _loop);
|
||||
bool get_loop();
|
||||
|
||||
void set_animation_time (float _animation_time);
|
||||
float get_animation_time();
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -80,6 +80,7 @@ SpineEditorPlugin::SpineEditorPlugin(EditorNode *node) {
|
||||
add_import_plugin(memnew(SpineJsonResourceImportPlugin));
|
||||
add_import_plugin(memnew(SpineBinaryResourceImportPlugin));
|
||||
add_inspector_plugin(memnew(SpineSkeletonDataResourceInspectorPlugin));
|
||||
add_inspector_plugin(memnew(SpineSpriteInspectorPlugin));
|
||||
}
|
||||
|
||||
bool SpineSkeletonDataResourceInspectorPlugin::can_handle(Object *object) {
|
||||
@ -314,4 +315,21 @@ void SpineEditorPropertyAnimationMix::update_property() {
|
||||
updating = false;
|
||||
}
|
||||
|
||||
void SpineSpriteInspectorPlugin::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("button_clicked"), &SpineSpriteInspectorPlugin::button_clicked);
|
||||
}
|
||||
|
||||
void SpineSpriteInspectorPlugin::button_clicked(const String& button_name) {
|
||||
}
|
||||
|
||||
bool SpineSpriteInspectorPlugin::can_handle(Object* object) {
|
||||
return Object::cast_to<SpineSprite>(object) != nullptr;
|
||||
}
|
||||
|
||||
void SpineSpriteInspectorPlugin::parse_begin(Object* object) {
|
||||
sprite = Object::cast_to<SpineSprite>(object);
|
||||
if (!sprite) return;
|
||||
if (!sprite->get_skeleton_data_res().is_valid() || !sprite->get_skeleton_data_res()->is_skeleton_data_loaded()) return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -147,8 +147,6 @@ class SpineSkeletonDataResourceInspectorPlugin: public EditorInspectorPlugin {
|
||||
GDCLASS(SpineSkeletonDataResourceInspectorPlugin, EditorInspectorPlugin)
|
||||
|
||||
public:
|
||||
SpineSkeletonDataResourceInspectorPlugin() = default;
|
||||
|
||||
bool can_handle(Object *object) override;
|
||||
#if VERSION_MAJOR > 3
|
||||
bool parse_property(Object *object, Variant::Type type, const String &path, PropertyHint hint, const String &hint_text, uint32_t usage, bool wide) override;
|
||||
@ -195,6 +193,18 @@ public:
|
||||
void update_property() override;
|
||||
};
|
||||
|
||||
class SpineSpriteInspectorPlugin: public EditorInspectorPlugin {
|
||||
GDCLASS(SpineSpriteInspectorPlugin, EditorInspectorPlugin)
|
||||
|
||||
SpineSprite *sprite;
|
||||
|
||||
static void _bind_methods();
|
||||
void button_clicked(const String &button_name);
|
||||
public:
|
||||
bool can_handle(Object *object) override;
|
||||
void parse_begin(Object *object) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif//GODOT_SPINEEDITORPLUGIN_H
|
||||
|
||||
@ -50,6 +50,7 @@ class SpineSkeleton : public REFCOUNTED {
|
||||
friend class SpineAnimation;
|
||||
friend class SpineAnimationState;
|
||||
friend class SpineCollisionShapeProxy;
|
||||
friend class SpineAnimationTrack;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
@ -27,7 +27,7 @@ void SpineSlotNode::_notification(int what) {
|
||||
_change_notify("rotation_deg");
|
||||
_change_notify("scale");
|
||||
} else {
|
||||
WARN_PRINT("SpineSlotProxy parent is not a SpineSprite.");
|
||||
WARN_PRINT("SpineSlotNode parent is not a SpineSprite.");
|
||||
}
|
||||
NOTIFY_PROPERTY_LIST_CHANGED();
|
||||
break;
|
||||
|
||||
@ -58,6 +58,8 @@ void SpineSprite::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("animation_completed", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite"), PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "track_entry", PROPERTY_HINT_TYPE_STRING, "SpineTrackEntry")));
|
||||
ADD_SIGNAL(MethodInfo("animation_disposed", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite"), PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "track_entry", PROPERTY_HINT_TYPE_STRING, "SpineTrackEntry")));
|
||||
ADD_SIGNAL(MethodInfo("animation_event", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite"), PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "track_entry", PROPERTY_HINT_TYPE_STRING, "SpineTrackEntry"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_TYPE_STRING, "SpineEvent")));
|
||||
ADD_SIGNAL(MethodInfo("before_animation_state_update", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite")));
|
||||
ADD_SIGNAL(MethodInfo("before_animation_state_apply", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite")));
|
||||
ADD_SIGNAL(MethodInfo("before_world_transforms_change", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite")));
|
||||
ADD_SIGNAL(MethodInfo("world_transforms_changed", PropertyInfo(Variant::OBJECT, "spine_sprite", PROPERTY_HINT_TYPE_STRING, "SpineSprite")));
|
||||
|
||||
@ -158,7 +160,6 @@ void SpineSprite::generate_meshes_for_slots(Ref<SpineSkeleton> skeleton_ref) {
|
||||
mesh_instance->set_material(default_materials[spine::BlendMode_Normal]);
|
||||
|
||||
add_child(mesh_instance);
|
||||
mesh_instance->set_owner(this);
|
||||
mesh_instances.push_back(mesh_instance);
|
||||
slot_nodes.add(spine::Vector<SpineSlotNode*>());
|
||||
}
|
||||
@ -233,10 +234,12 @@ void SpineSprite::update_skeleton(float delta) {
|
||||
if (!(skeleton.is_valid() && animation_state.is_valid()) || EMPTY(mesh_instances))
|
||||
return;
|
||||
|
||||
emit_signal("before_animation_state_update", this);
|
||||
animation_state->update(delta);
|
||||
if (!is_visible_in_tree())
|
||||
return;
|
||||
|
||||
emit_signal("before_animation_state_apply", this);
|
||||
animation_state->apply(skeleton);
|
||||
emit_signal("before_world_transforms_change", this);
|
||||
skeleton->update_world_transform();
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include "SpineSprite.h"
|
||||
#include "SpineSkeleton.h"
|
||||
#include "SpineAnimationState.h"
|
||||
#include "SpineAnimationTrack.h"
|
||||
#include "SpineEventData.h"
|
||||
#include "SpineEvent.h"
|
||||
#include "SpineTrackEntry.h"
|
||||
@ -98,8 +99,10 @@ void register_spine_godot_types() {
|
||||
ClassDB::register_class<SpineTransformConstraint>();
|
||||
ClassDB::register_class<SpineTimeline>();
|
||||
ClassDB::register_class<SpineConstant>();
|
||||
|
||||
ClassDB::register_class<SpineCollisionShapeProxy>();
|
||||
ClassDB::register_class<SpineSlotNode>();
|
||||
ClassDB::register_class<SpineAnimationTrack>();
|
||||
|
||||
#if VERSION_MAJOR > 3
|
||||
atlas_loader.instantiate();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user