diff --git a/docs/en/api/player.md b/docs/en/api/player.md
index 40472b3..18a9e40 100644
--- a/docs/en/api/player.md
+++ b/docs/en/api/player.md
@@ -23,7 +23,7 @@ func _ready() -> void:
## Main methods
* `set_ssab_resource(res: SSABResource)` / `get_ssab_resource() -> SSABResource`
-* `set_animation(name: String)` / `get_animation() -> String`
+* `set_animation(name: String)` / `get_current_animation() -> String`
* `set_autoplay(autoplay: bool)` / `is_autoplay() -> bool`: Whether to start playing automatically when the scene starts. **Default `true`** — a node placed in a scene has no code to call `play()` for it, so it plays. Set it off for a node you drive yourself, or one that should hold its first frame as a pose.
* `set_offset(offset: Vector2)` / `get_offset() -> Vector2`: Shifts the drawing position without moving the Node2D's origin.
* `set_flip_h(flip: bool)` / `is_flipped_h() -> bool`: Flips the animation horizontally.
diff --git a/docs/en/workflow/animation_player.md b/docs/en/workflow/animation_player.md
index c2ff96d..b8bd76c 100644
--- a/docs/en/workflow/animation_player.md
+++ b/docs/en/workflow/animation_player.md
@@ -15,7 +15,7 @@ To control SSPlayer with an `AnimationPlayer`, you must first convert all animat
3. Upon success, a file named `[original_filename]_anims.res` will be generated in the same directory.
> [!NOTE]
-> The generated `_anims.res` automatically contains "Value Tracks" with the exact same names as the original SpriteStudio animations. These tracks control the `animation` (animation name) and `frame` (current frame) properties of the target node.
+> The generated `_anims.res` automatically contains "Value Tracks" with the exact same names as the original SpriteStudio animations. These tracks control the `current_animation` (animation name) and `frame_no` (playhead) properties of the target node.
---
@@ -29,7 +29,7 @@ Here is how to apply the generated library to your scene.
Add an `AnimationPlayer` node to the scene.
3. **Specify the Target (Important!)**
Select the added `AnimationPlayer` node and set its **`Root Node`** property in the Inspector to the **`SpriteStudioPlayer2D` node** from step 1.
- *Note: Since the generated animations are configured to control the `animation` and `frame` properties of the target node itself, the Root Node must point directly to the SSPlayer node.*
+ *Note: Since the generated animations are configured to control the `current_animation` and `frame_no` properties of the target node itself, the Root Node must point directly to the SSPlayer node.*
4. **Load the Library**
Open the "Animation" panel at the bottom of the editor, click the "Animation" menu > **"Manage Animations..."**.
Click the folder icon (Load Library) in the dialog that appears, and load the generated `_anims.res` file.
diff --git a/docs/ja/api/player.md b/docs/ja/api/player.md
index ad93d49..2b76b95 100644
--- a/docs/ja/api/player.md
+++ b/docs/ja/api/player.md
@@ -23,7 +23,7 @@ func _ready() -> void:
## 主なメソッド
* `set_ssab_resource(res: SSABResource)` / `get_ssab_resource() -> SSABResource`
-* `set_animation(name: String)` / `get_animation() -> String`
+* `set_animation(name: String)` / `get_current_animation() -> String`
* `set_autoplay(autoplay: bool)` / `is_autoplay() -> bool`: シーン開始時に自動再生するかどうか。**既定は `true`** です。シーンに配置したノードのために `play()` を呼ぶコードは存在しないため、そのまま再生されます。自分で再生を制御したい場合や、先頭フレームをポーズとして保持したい場合はオフにしてください。
* `set_offset(offset: Vector2)` / `get_offset() -> Vector2`: Node2D の原点を動かさずに描画位置だけをずらします。
* `set_flip_h(flip: bool)` / `is_flipped_h() -> bool`: 水平反転。
diff --git a/docs/ja/workflow/animation_player.md b/docs/ja/workflow/animation_player.md
index 47b21cf..acf888f 100644
--- a/docs/ja/workflow/animation_player.md
+++ b/docs/ja/workflow/animation_player.md
@@ -15,7 +15,7 @@ SSPlayer を `AnimationPlayer` で制御するためには、まず対象の `.s
3. 成功すると、同じフォルダに `[元のファイル名]_anims.res` というファイルが生成されます。
> [!NOTE]
-> 生成された `_anims.res` の中には、元の SpriteStudio アニメーションと同じ名前の「Value Track(値トラック)」が自動生成されています。このトラックは対象ノードの `animation`(アニメーション名)と `frame`(現在のフレーム)を制御します。
+> 生成された `_anims.res` の中には、元の SpriteStudio アニメーションと同じ名前の「Value Track(値トラック)」が自動生成されています。このトラックは対象ノードの `current_animation`(アニメーション名)と `frame_no`(再生ヘッド)を制御します。
---
@@ -29,7 +29,7 @@ SSPlayer を `AnimationPlayer` で制御するためには、まず対象の `.s
シーン内に `AnimationPlayer` ノードを追加します。
3. **ターゲットの指定(重要!)**
追加した `AnimationPlayer` ノードを選択し、インスペクタ内の **`Root Node`** を、手順1の **`SpriteStudioPlayer2D` ノード** に設定します。
- *※自動生成されたアニメーションは「対象ノード自身の `animation` と `frame` を制御する」ようになっているため、Root Node を対象ノードに向ける必要があります。*
+ *※自動生成されたアニメーションは「対象ノード自身の `current_animation` と `frame_no` を制御する」ようになっているため、Root Node を対象ノードに向ける必要があります。*
4. **ライブラリの読み込み**
エディタ下部の「アニメーション (Animation)」パネルを開き、「アニメーション」メニュー > **「アニメーションを管理... (Manage Animations)」** をクリックします。
出てきたウィンドウのフォルダアイコン(ライブラリをロード)を押し、生成された `_anims.res` を読み込みます。
diff --git a/ss_player/doc_classes/SpriteStudioPlayer2D.xml b/ss_player/doc_classes/SpriteStudioPlayer2D.xml
index 76f08af..d7ca50f 100644
--- a/ss_player/doc_classes/SpriteStudioPlayer2D.xml
+++ b/ss_player/doc_classes/SpriteStudioPlayer2D.xml
@@ -5,7 +5,7 @@
Node that plays a SpriteStudio 7 animation imported as an [code].ssab[/code] resource ([SSABResource]).
- Assign a resource to [member ssab], pick an animation with [member animation], then drive playback from code with [method play], [method pause], [method resume] and [method stop], or preview it in the editor from the [b]SpriteStudio[/b] bottom panel (shown while the node is selected).
+ Assign a resource to [member ssab], pick an animation with [member current_animation], then drive playback from code with [method play], [method pause], [method resume] and [method stop], or preview it in the editor from the [b]SpriteStudio[/b] bottom panel (shown while the node is selected).
[b]Editor preview:[/b] with the node selected, the bottom panel provides transport controls (play from start / play from current / stop), a frame scrubber, loop and speed. Its keyboard shortcuts mirror the AnimationPlayer editor ([kbd]D[/kbd] play from current, [kbd]Shift+D[/kbd] play from start, [kbd]S[/kbd] stop).
@@ -53,7 +53,7 @@
- Returns [code]true[/code] once every configured loop has played. A [b]state[/b], not a pulse: it latches on completion and holds until the next [method play] or [member animation] change, so a caller that was not listening when [signal animation_finished] fired can still ask whether the run is over.
+ Returns [code]true[/code] once every configured loop has played. A [b]state[/b], not a pulse: it latches on completion and holds until the next [method play] or [member current_animation] change, so a caller that was not listening when [signal animation_finished] fired can still ask whether the run is over.
Never [code]true[/code] under an infinite [member loop_count], and [b]not raised by [method stop][/b] - a commanded stop is not a completion. That is what separates it from [code]not is_playing()[/code], which cannot tell the two apart. Connect to [signal animation_finished] if you want the one-shot edge instead.
@@ -85,7 +85,7 @@
- Names of the animations in the assigned [SSABResource], empty when none is assigned. The same list [member animation] is chosen from.
+ Names of the animations in the assigned [SSABResource], empty when none is assigned. The same list [member current_animation] is chosen from.
@@ -120,7 +120,7 @@
Sets the playback direction and style.
- Both are kept across [member animation] changes - "play this backwards" describes the playback rather than the clip that happens to be loaded. What does not carry is the heading within a [constant PLAYBACK_STYLE_PING_PONG] cycle: a new animation always starts on the outward leg.
+ Both are kept across [member current_animation] changes - "play this backwards" describes the playback rather than the clip that happens to be loaded. What does not carry is the heading within a [constant PLAYBACK_STYLE_PING_PONG] cycle: a new animation always starts on the outward leg.
@@ -326,7 +326,7 @@
The SpriteStudio animation resource ([code].ssab[/code]) to play.
-
+
Name of the animation to play, chosen from the animations contained in [member ssab].
@@ -359,10 +359,10 @@
How many times to play the animation. [code]n[/code] plays [code]n[/code] cycles and stops, so [code]1[/code] plays it once; [code]-1[/code] loops forever, and [code]0[/code] is an alias for that rather than "no cycles" - the runtime normalizes everything at or below zero to [code]-1[/code].
- Kept across [member animation] changes, because it is the node's own configuration - as are [member speed_scale], [member frame_skip_enabled], [member frame_rate] and the playback direction and style. Only the playback section is per-transition: frame indices mean nothing against a different clip.
+ Kept across [member current_animation] changes, because it is the node's own configuration - as are [member speed_scale], [member frame_skip_enabled], [member frame_rate] and the playback direction and style. Only the playback section is per-transition: frame indices mean nothing against a different clip.
- Playback frame rate (FPS). Setting one overrides whatever the animation was authored at, and the override is kept across [member animation] changes; set it to [code]0[/code] to clear it and hand playback back to each clip's authored rate.
+ Playback frame rate (FPS). Setting one overrides whatever the animation was authored at, and the override is kept across [member current_animation] changes; set it to [code]0[/code] to clear it and hand playback back to each clip's authored rate.
This is an [i]absolute[/i] rate where [member speed_scale] is a multiplier, so its effect depends on the clip: 60 against a 30fps animation is double speed, and against a 60fps one is none.
@@ -392,7 +392,7 @@
Emitted when the current animation changes, with the name of the new one.
- A host that called [method set_animation] already knows what it selected, so this exists for the routes that do not go through it: [member animation] is an exported property, so the inspector, an [AnimationPlayer] track or a tool script can mount a different clip without any of the node's own callers touching it.
+ A host that called [method set_animation] already knows what it selected, so this exists for the routes that do not go through it: [member current_animation] is an exported property, so the inspector, an [AnimationPlayer] track or a tool script can mount a different clip without any of the node's own callers touching it.
diff --git a/ss_player/ss_internal_player.h b/ss_player/ss_internal_player.h
index 8a4d3c3..2f35e5b 100644
--- a/ss_player/ss_internal_player.h
+++ b/ss_player/ss_internal_player.h
@@ -112,7 +112,7 @@ class SsInternalPlayer {
Ref getSSABResource() const { return _ssabRes; }
void setAnimation(const String& p_name);
void setAnimationByHash(uint32_t p_hash);
- String getAnimation() const { return _strAnimationSelected; }
+ String getCurrentAnimation() const { return _strAnimationSelected; }
// Cached AnimationData* for the currently selected animation. Null until
// setAnimation+_fetchAnimation succeed; lets callers skip a redundant
// name->AnimationData lookup in their own binary.
diff --git a/ss_player/ss_player_node_2d.cpp b/ss_player/ss_player_node_2d.cpp
index 0d9c537..fbc3c8c 100644
--- a/ss_player/ss_player_node_2d.cpp
+++ b/ss_player/ss_player_node_2d.cpp
@@ -286,8 +286,8 @@ void SpriteStudioPlayer2D::setAnimation(const String& strName) {
update_configuration_warnings();
}
-String SpriteStudioPlayer2D::getAnimation() const {
- return _internal->getAnimation();
+String SpriteStudioPlayer2D::getCurrentAnimation() const {
+ return _internal->getCurrentAnimation();
}
void SpriteStudioPlayer2D::setAutoplay(bool p_autoplay) {
@@ -479,7 +479,7 @@ void SpriteStudioPlayer2D::_bind_methods() {
ClassDB::bind_method( D_METHOD( "set_ssab_resource", "res_ssab" ), &SpriteStudioPlayer2D::setSSABResource );
ClassDB::bind_method( D_METHOD( "get_ssab_resource" ), &SpriteStudioPlayer2D::getSSABResource );
ClassDB::bind_method( D_METHOD( "set_animation", "name" ), &SpriteStudioPlayer2D::setAnimation );
- ClassDB::bind_method( D_METHOD( "get_animation" ), &SpriteStudioPlayer2D::getAnimation );
+ ClassDB::bind_method( D_METHOD( "get_current_animation" ), &SpriteStudioPlayer2D::getCurrentAnimation );
ClassDB::bind_method( D_METHOD( "set_autoplay", "autoplay" ), &SpriteStudioPlayer2D::setAutoplay );
ClassDB::bind_method( D_METHOD( "is_autoplay" ), &SpriteStudioPlayer2D::isAutoplay );
@@ -627,7 +627,13 @@ void SpriteStudioPlayer2D::_bind_methods() {
"set_ssab_resource",
"get_ssab_resource"
);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation", PROPERTY_HINT_ENUM, ""), "set_animation", "get_animation");
+ // The accessors are deliberately asymmetric. `set_animation` is the verb the
+ // whole family publishes and `get_current_animation` is its read
+ // (SDK: 20_design/40_api_conventions), and ADD_PROPERTY names the two
+ // independently -- so the property reads as Godot expects
+ // (`AnimationPlayer.current_animation` is this same thing) without inventing a
+ // `set_current_animation` that would be a second name for one operation.
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_animation", PROPERTY_HINT_ENUM, ""), "set_animation", "get_current_animation");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay");
// Editor-only (never stored): the playhead is runtime state, but it stays in
// the property list so an AnimationPlayer can keyframe it.
@@ -747,7 +753,7 @@ void SpriteStudioPlayer2D::_get_property_list(List* p_list) const
}
void SpriteStudioPlayer2D::_validate_property(PropertyInfo& p_property) const {
- if (p_property.name == StringName("animation")) {
+ if (p_property.name == StringName("current_animation")) {
// Turn the statically registered enum hint into the animation names of
// the bound resource. Left empty when no resource is assigned.
Ref res = _internal->getSSABResource();
@@ -783,7 +789,7 @@ PackedStringArray SpriteStudioPlayer2D::get_configuration_warnings() const {
#endif
if (getSSABResource().is_null()) {
warnings.push_back(tr("Assign an SSABResource to the \"ssab\" property to play an animation."));
- } else if (getAnimation().is_empty()) {
+ } else if (getCurrentAnimation().is_empty()) {
warnings.push_back(tr("Select an animation in the \"animation\" property."));
}
return warnings;
diff --git a/ss_player/ss_player_node_2d.h b/ss_player/ss_player_node_2d.h
index 4405dfe..aed0cd4 100644
--- a/ss_player/ss_player_node_2d.h
+++ b/ss_player/ss_player_node_2d.h
@@ -81,7 +81,7 @@ class SpriteStudioPlayer2D : public Node2D {
void setSSABResource( const Ref& ssabRes );
Ref getSSABResource() const;
void setAnimation( const String& strName );
- String getAnimation() const;
+ String getCurrentAnimation() const;
void setAutoplay( bool p_autoplay );
bool isAutoplay() const;
diff --git a/ss_player/ss_resource_inspector.cpp b/ss_player/ss_resource_inspector.cpp
index a5a6f33..aee3f31 100644
--- a/ss_player/ss_resource_inspector.cpp
+++ b/ss_player/ss_resource_inspector.cpp
@@ -177,15 +177,17 @@ void SSResourceInspectorPlugin::_on_generate_animation_library_pressed(const Str
anim->set_length(length);
anim->set_step(1.0f / fps);
- // Track 0: animation
+ // Track 0: the selected animation. The path is a PROPERTY path, so it has
+ // to be the exported name -- a track pointing at a property that no longer
+ // exists is not an error, it just silently drives nothing.
int track_anim = anim->add_track(Animation::TYPE_VALUE);
- anim->track_set_path(track_anim, NodePath(".:animation"));
+ anim->track_set_path(track_anim, NodePath(".:current_animation"));
anim->track_insert_key(track_anim, 0.0, anim_name);
anim->value_track_set_update_mode(track_anim, Animation::UPDATE_DISCRETE);
- // Track 1: frame
+ // Track 1: the playhead. Same story as above.
int track_frame = anim->add_track(Animation::TYPE_VALUE);
- anim->track_set_path(track_frame, NodePath(".:frame"));
+ anim->track_set_path(track_frame, NodePath(".:frame_no"));
anim->track_insert_key(track_frame, 0.0, 0.0f);
// The player exposes frames 0..total_frame-1, and the last frame occupies
// the final 1/fps slice of `length`. Keying the last VALID frame at its own