mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-16 12:01:41 +08:00
[godot] Beginnings of making animation mixes nicely inspector editable
This commit is contained in:
parent
0bd1fe7aac
commit
5b9385e185
@ -1,10 +1,22 @@
|
||||
[gd_resource type="SpineSkeletonDataResource" load_steps=3 format=2]
|
||||
[gd_resource type="SpineSkeletonDataResource" load_steps=5 format=2]
|
||||
|
||||
[ext_resource path="res://assets/spineboy/spineboy.atlas" type="SpineAtlasResource" id=1]
|
||||
[ext_resource path="res://assets/spineboy/spineboy-pro.json" type="SpineSkeletonFileResource" id=2]
|
||||
|
||||
[sub_resource type="SpineAnimationMix" id=1]
|
||||
from = "run"
|
||||
to = "idle"
|
||||
mix = 1.0
|
||||
|
||||
[sub_resource type="SpineAnimationMix" id=2]
|
||||
from = "idle"
|
||||
to = "run"
|
||||
mix = 1.0
|
||||
|
||||
[resource]
|
||||
atlas_res = ExtResource( 1 )
|
||||
skeleton_file_res = ExtResource( 2 )
|
||||
default_mix = 0.2
|
||||
animation_mixes = [ SubResource( 1 ), SubResource( 2 ), null, null ]
|
||||
animations = null
|
||||
skins = null
|
||||
|
||||
@ -1,34 +1,12 @@
|
||||
[gd_scene load_steps=7 format=2]
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://examples/helloworld/spineboy-helloworld.gd" type="Script" id=1]
|
||||
[ext_resource path="res://examples/mix-and-match/mix-and-match.gd" type="Script" id=2]
|
||||
[ext_resource path="res://assets/spineboy/spinebody-data-res.tres" type="SpineSkeletonDataResource" id=3]
|
||||
[ext_resource path="res://assets/mix-and-match/mix-and-match-data.tres" type="SpineSkeletonDataResource" id=4]
|
||||
[ext_resource path="res://assets/raptor/raprot-data.tres" type="SpineSkeletonDataResource" id=5]
|
||||
|
||||
[sub_resource type="GDScript" id=1]
|
||||
script/source = "extends SpineSprite
|
||||
|
||||
func _ready():
|
||||
get_animation_state().set_animation(\"walk\", true)
|
||||
"
|
||||
|
||||
[node name="Node2D" type="Node2D"]
|
||||
|
||||
[node name="Spineboy" type="SpineSprite" parent="."]
|
||||
position = Vector2( 137.107, 540.132 )
|
||||
position = Vector2( 496.207, 477.185 )
|
||||
scale = Vector2( 0.466832, 0.466832 )
|
||||
skeleton_data_res = ExtResource( 3 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="MixAndMatch" type="SpineSprite" parent="."]
|
||||
position = Vector2( 402.469, 534.677 )
|
||||
scale = Vector2( 0.366163, 0.366163 )
|
||||
skeleton_data_res = ExtResource( 4 )
|
||||
script = ExtResource( 2 )
|
||||
|
||||
[node name="Raptor" type="SpineSprite" parent="."]
|
||||
position = Vector2( 793.667, 527.026 )
|
||||
scale = Vector2( 0.343143, 0.343143 )
|
||||
skeleton_data_res = ExtResource( 5 )
|
||||
script = SubResource( 1 )
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
extends SpineSprite
|
||||
|
||||
func _ready():
|
||||
func _ready():
|
||||
get_animation_state().set_animation("walk", true, 0)
|
||||
|
||||
12
spine-godot/example/examples/simple-input/simple-input.tscn
Normal file
12
spine-godot/example/examples/simple-input/simple-input.tscn
Normal file
@ -0,0 +1,12 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://assets/spineboy/spinebody-data-res.tres" type="SpineSkeletonDataResource" id=1]
|
||||
[ext_resource path="res://examples/simple-input/spineboy-simple-input.gd" type="Script" id=2]
|
||||
|
||||
[node name="Node2D" type="Node2D"]
|
||||
|
||||
[node name="Spineboy" type="SpineSprite" parent="."]
|
||||
position = Vector2( 501.503, 472.035 )
|
||||
scale = Vector2( 0.518624, 0.518624 )
|
||||
skeleton_data_res = ExtResource( 1 )
|
||||
script = ExtResource( 2 )
|
||||
@ -0,0 +1,19 @@
|
||||
extends SpineSprite
|
||||
|
||||
func _ready():
|
||||
get_animation_state().set_animation("idle", true, 0)
|
||||
|
||||
func _process(delta):
|
||||
if Input.is_action_just_pressed("ui_left"):
|
||||
get_animation_state().set_animation("run", true, 0)
|
||||
get_skeleton().set_scale_x(-1)
|
||||
|
||||
if Input.is_action_just_released("ui_left"):
|
||||
get_animation_state().set_animation("idle", true, 0)
|
||||
|
||||
if (Input.is_action_just_pressed("ui_right")):
|
||||
get_animation_state().set_animation("run", true, 0)
|
||||
get_skeleton().set_scale_x(1)
|
||||
|
||||
if Input.is_action_just_released("ui_right"):
|
||||
get_animation_state().set_animation("idle", true, 0)
|
||||
@ -11,7 +11,7 @@ config_version=4
|
||||
[application]
|
||||
|
||||
config/name="spine-godot-examples"
|
||||
run/main_scene="res://tests/batch-test.tscn"
|
||||
run/main_scene="res://examples/simple-input/simple-input.tscn"
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.png"
|
||||
|
||||
|
||||
@ -76,13 +76,46 @@ SpineEditorPlugin::SpineEditorPlugin(EditorNode *node) {
|
||||
add_import_plugin(memnew(SpineAtlasResourceImportPlugin));
|
||||
add_import_plugin(memnew(SpineJsonResourceImportPlugin));
|
||||
add_import_plugin(memnew(SpineBinaryResourceImportPlugin));
|
||||
add_inspector_plugin(memnew(SpineAnimationMixesInspectorPlugin));
|
||||
}
|
||||
|
||||
SpineEditorPlugin::~SpineEditorPlugin() {
|
||||
}
|
||||
|
||||
bool SpineEditorPlugin::handles(Object *object) const {
|
||||
return object->is_class("SpineSprite");
|
||||
return object->is_class("SpineSprite") || object->is_class("SpineSkeletonDataResource");
|
||||
}
|
||||
|
||||
SpineAnimationMixesInspectorPlugin::SpineAnimationMixesInspectorPlugin() {
|
||||
|
||||
}
|
||||
|
||||
SpineAnimationMixesInspectorPlugin::~SpineAnimationMixesInspectorPlugin() {
|
||||
|
||||
}
|
||||
|
||||
bool SpineAnimationMixesInspectorPlugin::can_handle(Object *object) {
|
||||
return object->is_class("SpineSkeletonDataResource");
|
||||
}
|
||||
|
||||
void SpineAnimationMixesInspectorPlugin::parse_begin(Object *object) {
|
||||
EditorInspectorPlugin::parse_begin(object);
|
||||
}
|
||||
|
||||
void SpineAnimationMixesInspectorPlugin::parse_category(Object *object, const String &parse_category) {
|
||||
EditorInspectorPlugin::parse_category(object, parse_category);
|
||||
if (parse_category == "Animation mixes") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool SpineAnimationMixesInspectorPlugin::parse_property(Object *object, Variant::Type type, const String &path,
|
||||
PropertyHint hint, const String &hint_text, int usage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void SpineAnimationMixesInspectorPlugin::parse_end() {
|
||||
EditorInspectorPlugin::parse_end();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -38,23 +38,23 @@ class SpineAtlasResourceImportPlugin : public EditorImportPlugin {
|
||||
|
||||
public:
|
||||
String get_importer_name() const override { return "spine.atlas"; }
|
||||
|
||||
|
||||
String get_visible_name() const override { return "Spine Runtime Atlas"; }
|
||||
|
||||
|
||||
void get_recognized_extensions(List<String> *extensions) const override { extensions->push_back("atlas"); }
|
||||
|
||||
|
||||
String get_preset_name(int idx) const override { return idx == 0 ? "Default" : "Unknown"; }
|
||||
|
||||
|
||||
int get_preset_count() const override { return 1; }
|
||||
|
||||
|
||||
String get_save_extension() const override { return "spatlas"; }
|
||||
|
||||
|
||||
String get_resource_type() const override { return "SpineAtlasResource"; }
|
||||
|
||||
|
||||
void get_import_options(List<ImportOption> *options, int preset) const override;
|
||||
|
||||
|
||||
bool get_option_visibility(const String &option, const Map<StringName, Variant> &options) const override { return true; }
|
||||
|
||||
|
||||
Error import(const String &source_file, const String &save_path, const Map<StringName, Variant> &options, List<String> *platform_variants, List<String> *gen_files, Variant *metadata) override;
|
||||
};
|
||||
|
||||
@ -63,23 +63,23 @@ class SpineJsonResourceImportPlugin : public EditorImportPlugin {
|
||||
|
||||
public:
|
||||
String get_importer_name() const override { return "spine.json"; }
|
||||
|
||||
|
||||
String get_visible_name() const override { return "Spine Skeleton Json"; }
|
||||
|
||||
|
||||
void get_recognized_extensions(List<String> *extensions) const override { extensions->push_back("json"); }
|
||||
|
||||
|
||||
String get_preset_name(int idx) const override { return idx == 0 ? "Default" : "Unknown"; }
|
||||
|
||||
|
||||
int get_preset_count() const override { return 1; }
|
||||
|
||||
|
||||
String get_save_extension() const override { return "spjson"; }
|
||||
|
||||
|
||||
String get_resource_type() const override { return "SpineSkeletonFileResource"; }
|
||||
|
||||
|
||||
void get_import_options(List<ImportOption> *options, int preset) const override {}
|
||||
|
||||
|
||||
bool get_option_visibility(const String &option, const Map<StringName, Variant> &options) const override { return true; }
|
||||
|
||||
|
||||
Error import(const String &source_file, const String &save_path, const Map<StringName, Variant> &options, List<String> *platform_variants, List<String> *gen_files, Variant *metadata) override;
|
||||
};
|
||||
|
||||
@ -116,11 +116,33 @@ public:
|
||||
~SpineEditorPlugin();
|
||||
|
||||
String get_name() const override { return "SpineEditorPlugin"; }
|
||||
|
||||
|
||||
bool has_main_screen() const { return false; }
|
||||
|
||||
|
||||
bool handles(Object *object) const override;
|
||||
};
|
||||
|
||||
class SpineAnimationMixesInspectorPlugin: public EditorInspectorPlugin {
|
||||
GDCLASS(SpineAnimationMixesInspectorPlugin, EditorInspectorPlugin)
|
||||
|
||||
public:
|
||||
SpineAnimationMixesInspectorPlugin();
|
||||
~SpineAnimationMixesInspectorPlugin() override;
|
||||
|
||||
bool can_handle(Object *object) override;
|
||||
void parse_begin(Object *object) override;
|
||||
void parse_category(Object *object, const String &parse_category) override;
|
||||
bool parse_property(Object *object, Variant::Type type, const String &path, PropertyHint hint, const String &hint_text, int usage) override;
|
||||
void parse_end() override;
|
||||
};
|
||||
|
||||
class SpineAnimationMixesProperty: public EditorProperty {
|
||||
GDCLASS(SpineAnimationMixesProperty, EditorProperty)
|
||||
|
||||
public:
|
||||
SpineAnimationMixesProperty();
|
||||
~SpineAnimationMixesProperty();
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif//GODOT_SPINEEDITORPLUGIN_H
|
||||
|
||||
@ -29,10 +29,48 @@
|
||||
|
||||
#include "SpineSkeletonDataResource.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_inspector.h"
|
||||
#endif
|
||||
void SpineAnimationMix::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_from", "from"), &SpineAnimationMix::set_from);
|
||||
ClassDB::bind_method(D_METHOD("get_from"), &SpineAnimationMix::get_from);
|
||||
ClassDB::bind_method(D_METHOD("set_to", "to"), &SpineAnimationMix::set_to);
|
||||
ClassDB::bind_method(D_METHOD("get_to"), &SpineAnimationMix::get_to);
|
||||
ClassDB::bind_method(D_METHOD("set_mix", "mix"), &SpineAnimationMix::set_mix);
|
||||
ClassDB::bind_method(D_METHOD("get_mix"), &SpineAnimationMix::get_mix);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "from"), "set_from", "get_from");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "to"), "set_to", "get_to");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "mix"), "set_mix", "get_mix");
|
||||
}
|
||||
|
||||
SpineAnimationMix::SpineAnimationMix() {
|
||||
}
|
||||
|
||||
SpineAnimationMix::~SpineAnimationMix() {
|
||||
}
|
||||
|
||||
void SpineAnimationMix::set_from(const StringName &from) {
|
||||
this->from = from;
|
||||
}
|
||||
|
||||
String SpineAnimationMix::get_from() {
|
||||
return from;
|
||||
}
|
||||
|
||||
void SpineAnimationMix::set_to(const StringName &to) {
|
||||
this->to = to;
|
||||
}
|
||||
|
||||
String SpineAnimationMix::get_to() {
|
||||
return to;
|
||||
}
|
||||
|
||||
void SpineAnimationMix::set_mix(float mix) {
|
||||
this->mix = mix;
|
||||
}
|
||||
|
||||
float SpineAnimationMix::get_mix() {
|
||||
return mix;
|
||||
}
|
||||
|
||||
void SpineSkeletonDataResource::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("is_skeleton_data_loaded"), &SpineSkeletonDataResource::is_skeleton_data_loaded);
|
||||
@ -40,6 +78,10 @@ void SpineSkeletonDataResource::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_atlas_res"), &SpineSkeletonDataResource::get_atlas_res);
|
||||
ClassDB::bind_method(D_METHOD("set_skeleton_file_res", "skeleton_file_res"), &SpineSkeletonDataResource::set_skeleton_file_res);
|
||||
ClassDB::bind_method(D_METHOD("get_skeleton_file_res"), &SpineSkeletonDataResource::get_skeleton_file_res);
|
||||
ClassDB::bind_method(D_METHOD("set_default_mix", "default_mix"), &SpineSkeletonDataResource::set_default_mix);
|
||||
ClassDB::bind_method(D_METHOD("get_default_mix"), &SpineSkeletonDataResource::get_default_mix);
|
||||
ClassDB::bind_method(D_METHOD("set_animation_mixes", "mixes"), &SpineSkeletonDataResource::set_animation_mixes);
|
||||
ClassDB::bind_method(D_METHOD("get_animation_mixes"), &SpineSkeletonDataResource::get_animation_mixes);
|
||||
|
||||
// Spine API
|
||||
ClassDB::bind_method(D_METHOD("find_bone", "bone_name"), &SpineSkeletonDataResource::find_bone);
|
||||
@ -75,9 +117,12 @@ void SpineSkeletonDataResource::_bind_methods() {
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas_res", PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "SpineAtlasResource"), "set_atlas_res", "get_atlas_res");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skeleton_file_res", PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "SpineSkeletonFileResource"), "set_skeleton_file_res", "get_skeleton_file_res");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "default_mix"), "set_default_mix", "get_default_mix");
|
||||
ADD_GROUP("Animation mixes", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animation_mixes"), "set_animation_mixes", "get_animation_mixes");
|
||||
}
|
||||
|
||||
SpineSkeletonDataResource::SpineSkeletonDataResource() : skeleton_data(nullptr), animation_state_data(nullptr) {
|
||||
SpineSkeletonDataResource::SpineSkeletonDataResource() : skeleton_data(nullptr), animation_state_data(nullptr), default_mix(0) {
|
||||
}
|
||||
|
||||
SpineSkeletonDataResource::~SpineSkeletonDataResource() {
|
||||
@ -137,6 +182,7 @@ void SpineSkeletonDataResource::set_atlas_res(const Ref<SpineAtlasResource> &atl
|
||||
atlas_res = atlas;
|
||||
update_skeleton_data();
|
||||
}
|
||||
|
||||
Ref<SpineAtlasResource> SpineSkeletonDataResource::get_atlas_res() {
|
||||
return atlas_res;
|
||||
}
|
||||
@ -145,6 +191,7 @@ void SpineSkeletonDataResource::set_skeleton_file_res(const Ref<SpineSkeletonFil
|
||||
skeleton_file_res = skeleton_file;
|
||||
update_skeleton_data();
|
||||
}
|
||||
|
||||
Ref<SpineSkeletonFileResource> SpineSkeletonDataResource::get_skeleton_file_res() {
|
||||
return skeleton_file_res;
|
||||
}
|
||||
@ -169,23 +216,21 @@ void SpineSkeletonDataResource::get_skin_names(Vector<String> &skin_names) const
|
||||
}
|
||||
}
|
||||
|
||||
void SpineSkeletonDataResource::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
PropertyInfo property;
|
||||
Vector<String> animation_names;
|
||||
void SpineSkeletonDataResource::set_default_mix(float default_mix) {
|
||||
this->default_mix = default_mix;
|
||||
if (animation_state_data) animation_state_data->setDefaultMix(default_mix);
|
||||
}
|
||||
|
||||
property.name = "animations";
|
||||
property.type = Variant::STRING;
|
||||
get_animation_names(animation_names);
|
||||
property.hint_string = String(",").join(animation_names);
|
||||
property.hint = PROPERTY_HINT_ENUM;
|
||||
p_list->push_back(property);
|
||||
float SpineSkeletonDataResource::get_default_mix() {
|
||||
return default_mix;
|
||||
}
|
||||
|
||||
property.name = "skins";
|
||||
property.type = Variant::STRING;
|
||||
get_skin_names(animation_names);
|
||||
property.hint_string = String(",").join(animation_names);
|
||||
property.hint = PROPERTY_HINT_ENUM;
|
||||
p_list->push_back(property);
|
||||
void SpineSkeletonDataResource::set_animation_mixes(Array animation_mixes) {
|
||||
this->animation_mixes = animation_mixes;
|
||||
}
|
||||
|
||||
Array SpineSkeletonDataResource::get_animation_mixes() {
|
||||
return animation_mixes;
|
||||
}
|
||||
|
||||
#define CHECK(x) \
|
||||
|
||||
@ -12,8 +12,34 @@
|
||||
#include "SpinePathConstraintData.h"
|
||||
#include "SpineEventData.h"
|
||||
|
||||
class SpineAnimationMix : public Resource {
|
||||
GDCLASS(SpineAnimationMix, Resource)
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
String from;
|
||||
String to;
|
||||
float mix;
|
||||
public:
|
||||
SpineAnimationMix();
|
||||
~SpineAnimationMix();
|
||||
|
||||
void set_from(const StringName &from);
|
||||
|
||||
String get_from();
|
||||
|
||||
void set_to(const StringName &to);
|
||||
|
||||
String get_to();
|
||||
|
||||
void set_mix(float mix);
|
||||
|
||||
float get_mix();
|
||||
};
|
||||
|
||||
class SpineSkeletonDataResource : public Resource {
|
||||
GDCLASS(SpineSkeletonDataResource, Resource);
|
||||
GDCLASS(SpineSkeletonDataResource, Resource)
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
@ -21,6 +47,8 @@ protected:
|
||||
private:
|
||||
Ref<SpineAtlasResource> atlas_res;
|
||||
Ref<SpineSkeletonFileResource> skeleton_file_res;
|
||||
float default_mix;
|
||||
Array animation_mixes;
|
||||
|
||||
spine::SkeletonData *skeleton_data;
|
||||
spine::AnimationStateData *animation_state_data;
|
||||
@ -49,7 +77,13 @@ public:
|
||||
|
||||
void get_skin_names(Vector<String> &l) const;
|
||||
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
void set_default_mix(float default_mix);
|
||||
|
||||
float get_default_mix();
|
||||
|
||||
void set_animation_mixes(Array animation_mixes);
|
||||
|
||||
Array get_animation_mixes();
|
||||
|
||||
// Spine API
|
||||
Ref<SpineBoneData> find_bone(const String &bone_name) const;
|
||||
|
||||
@ -73,11 +73,10 @@ void register_spine_godot_types() {
|
||||
#ifdef TOOLS_ENABLED
|
||||
EditorNode::add_init_callback(editor_init_callback);
|
||||
#endif
|
||||
|
||||
ClassDB::register_class<SpineAtlasResource>();
|
||||
ClassDB::register_class<SpineSkeletonFileResource>();
|
||||
ClassDB::register_class<SpineSkeletonDataResource>();
|
||||
ClassDB::register_class<SpineSkeletonDataResource>();
|
||||
ClassDB::register_class<SpineAnimationMix>();
|
||||
ClassDB::register_class<SpineSprite>();
|
||||
ClassDB::register_class<SpineSprite>();
|
||||
ClassDB::register_class<SpineSkeleton>();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user