Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/en/api/player.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions docs/en/workflow/animation_player.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

---

Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion docs/ja/api/player.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`: 水平反転。
Expand Down
4 changes: 2 additions & 2 deletions docs/ja/workflow/animation_player.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`(再生ヘッド)を制御します。

---

Expand All @@ -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` を読み込みます。
Expand Down
16 changes: 8 additions & 8 deletions ss_player/doc_classes/SpriteStudioPlayer2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</brief_description>
<description>
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).
</description>
<tutorials>
Expand Down Expand Up @@ -53,7 +53,7 @@
<method name="is_finished" qualifiers="const">
<return type="bool" />
<description>
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.
</description>
</method>
Expand Down Expand Up @@ -85,7 +85,7 @@
<method name="get_animation_names" qualifiers="const">
<return type="PackedStringArray" />
<description>
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.
</description>
</method>
<method name="get_total_frames" qualifiers="const">
Expand Down Expand Up @@ -120,7 +120,7 @@
<param index="1" name="style" type="int" enum="SpriteStudioPlayer2D.PlaybackStyle" />
<description>
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.
</description>
</method>
<method name="get_playback_direction" qualifiers="const">
Expand Down Expand Up @@ -326,7 +326,7 @@
<member name="ssab" type="SSABResource">
The SpriteStudio animation resource ([code].ssab[/code]) to play.
</member>
<member name="animation" type="String">
<member name="current_animation" type="String">
Name of the animation to play, chosen from the animations contained in [member ssab].
</member>
<member name="autoplay" type="bool" default="true">
Expand Down Expand Up @@ -359,10 +359,10 @@
</member>
<member name="loop_count" type="int" default="-1">
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.
</member>
<member name="frame_rate" type="int">
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.
</member>
<member name="frame_skip_enabled" type="bool" default="true">
Expand Down Expand Up @@ -392,7 +392,7 @@
<param index="0" name="anim_name" type="String" />
<description>
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.
</description>
</signal>
<signal name="animation_finished">
Expand Down
2 changes: 1 addition & 1 deletion ss_player/ss_internal_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class SsInternalPlayer {
Ref<SSABResource> 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.
Expand Down
18 changes: 12 additions & 6 deletions ss_player/ss_player_node_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -747,7 +753,7 @@ void SpriteStudioPlayer2D::_get_property_list(List<PropertyInfo>* 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<SSABResource> res = _internal->getSSABResource();
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion ss_player/ss_player_node_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class SpriteStudioPlayer2D : public Node2D {
void setSSABResource( const Ref<SSABResource>& ssabRes );
Ref<SSABResource> getSSABResource() const;
void setAnimation( const String& strName );
String getAnimation() const;
String getCurrentAnimation() const;

void setAutoplay( bool p_autoplay );
bool isAutoplay() const;
Expand Down
10 changes: 6 additions & 4 deletions ss_player/ss_resource_inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading