From 8c1d2f26a8f8c96bbf56cf8721cdffc0c9cbe8cd Mon Sep 17 00:00:00 2001 From: Naruto TAKAHASHI Date: Wed, 26 Aug 2026 11:32:57 +0900 Subject: [PATCH] feat(player)!: frame -> frame_no Applies the playhead stem from the API conventions (SDK `20_design/40_api_conventions.md`). frame (property) -> frame_no get_frame/set_frame -> get_frame_no/set_frame_no The value is fractional -- sub-frame interpolation puts the playhead between two authored frames -- and this node's own `frame_updated` signal already calls its argument `frame_no`. `AnimatedSprite2D.frame` is the obvious precedent to reach for, and it is the reason to move rather than to keep: that one is an INTEGER index into a SpriteFrames set, so a Godot reader seeing `frame` here is promised the wrong type. The class reference now says so where the member is documented. The C++ names move with the bindings so the two layers keep one word, which also carries the editor playback panel. --- docs/en/api/player.md | 4 ++-- docs/en/troubleshooting.md | 2 +- docs/en/workflow/usage_scripting.md | 4 ++-- docs/ja/api/player.md | 4 ++-- docs/ja/troubleshooting.md | 2 +- docs/ja/workflow/usage_scripting.md | 4 ++-- ss_player/doc_classes/SpriteStudioPlayer2D.xml | 8 ++++---- ss_player/ss_internal_player.cpp | 4 ++-- ss_player/ss_internal_player.h | 8 ++++---- ss_player/ss_playback_panel.cpp | 8 ++++---- ss_player/ss_player_node_2d.cpp | 18 +++++++++--------- ss_player/ss_player_node_2d.h | 4 ++-- 12 files changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/en/api/player.md b/docs/en/api/player.md index 46eb83a..40472b3 100644 --- a/docs/en/api/player.md +++ b/docs/en/api/player.md @@ -31,7 +31,7 @@ func _ready() -> void: * `set_animation_process_mode(mode: AnimationProcessMode)` / `get_animation_process_mode() -> AnimationProcessMode`: Sets whether to sync with `_physics_process` (`ANIMATION_PROCESS_PHYSICS` / `0`) or `_process` (`ANIMATION_PROCESS_IDLE` / `1`), or to stop ticking on its own (`ANIMATION_PROCESS_MANUAL` / `2`). * `advance(delta: float)`: Steps playback by `delta` seconds and emits `frame_updated`, exactly as an automatic tick would. Meant for `ANIMATION_PROCESS_MANUAL` — under the other modes it advances the animation *on top of* the node's own tick. * **In-editor preview**: Select the node and use the **SpriteStudio** bottom panel — play from start / play from current / stop, a frame scrubber, and loop and speed controls — to preview without running the game. Shortcuts mirror the AnimationPlayer editor (**D** play from current, **Shift+D** play from start, **S** stop). *(The former `editor_playing` inspector toggle has been replaced by this panel.)* -* `play(start_frame: float = -1.0)`: Starts playback. `-1.0` (the default) **rewinds to the start of the section** — its end when the direction is backward — rather than continuing from where the playhead is. Pass `get_frame()` to play on from the current position. +* `play(start_frame: float = -1.0)`: Starts playback. `-1.0` (the default) **rewinds to the start of the section** — its end when the direction is backward — rather than continuing from where the playhead is. Pass `get_frame_no()` to play on from the current position. * `pause()`: Holds playback where it stands, keeping the current frame. **Idempotent** — pausing twice leaves it paused. * `resume()`: Lifts the hold and carries on from the same frame. **Idempotent**, and a no-op on an animation that is stopped rather than held — `play()` is what starts a stopped animation, and it rewinds. * `stop()`: Stops playback. The playhead **stays where it was**, so the node keeps drawing the frame it stopped on. @@ -40,7 +40,7 @@ func _ready() -> void: * `just_looped() -> bool`: Whether the last update crossed a loop boundary. A **pulse**, not a state — the runtime clears it at the top of every update, so it only reads `true` inside the tick that crossed (which is why it is not `is_looped`: reading it a tick late reads `false`). The `animation_looped` signal delivers the same edge if you would rather not poll. * `get_animation_names() -> PackedStringArray`: Names of the animations in the assigned [SSABResource] — the same list the `animation` property is chosen from. * `is_playing_forward() -> bool`: Which way the playhead is **actually** travelling. Not `get_playback_direction()`, which reports the configured heading: on a ping-pong return leg this reads `false` while that still reads `PLAYBACK_DIRECTION_FORWARD` (a speed of zero or below is a stop, not a reversal, and does not flip it either). **Gate audio on it** — SpriteStudio has no reverse audio, so a sound key crossed on a backward leg is not meant to sound, and this is the test the node itself applies when `play_audio` is on. `true` before anything has played: forward is the resting state. -* `set_frame(frame: float)` / `get_frame() -> float` / `get_total_frames() -> int` +* `set_frame_no(frame: float)` / `get_frame_no() -> float` / `get_total_frames() -> int` * `get_start_frame() -> int` / `get_end_frame() -> int`: The first and last frame that actually plays — the current playback section. They return the same values as `get_animation_section_start()` / `get_animation_section_end()`, which is the whole animation until `set_animation_section()` narrows it. * `set_speed_scale(speed_scale: float)` / `get_speed_scale() -> float` * `set_frame_rate(fps: int)` / `get_frame_rate() -> int` diff --git a/docs/en/troubleshooting.md b/docs/en/troubleshooting.md index 1ff342c..400b6a0 100644 --- a/docs/en/troubleshooting.md +++ b/docs/en/troubleshooting.md @@ -56,7 +56,7 @@ Keep the output directory (`res://ssab_generated` by default) intact, or move th ### An override does not appear on screen -While playback is stopped or paused — or on any frame that does not advance — the drawing is not rebuilt, so setting or clearing an override changes nothing visible. Force a redraw with `set_frame(get_frame())`. +While playback is stopped or paused — or on any frame that does not advance — the drawing is not rebuilt, so setting or clearing an override changes nothing visible. Force a redraw with `set_frame_no(get_frame_no())`. ### `animation_finished` never fires diff --git a/docs/en/workflow/usage_scripting.md b/docs/en/workflow/usage_scripting.md index 7c2a7f1..6da239c 100644 --- a/docs/en/workflow/usage_scripting.md +++ b/docs/en/workflow/usage_scripting.md @@ -35,7 +35,7 @@ func _process(delta): > [!IMPORTANT] > There are three states, not two. **`is_playing()` stays `true` while paused** — a pause is a hold, not a stop — so `is_pausing()` is what tells a held animation from a running one, and both are `false` before the first `play()` and after `stop()`. > -> **`play()` is not a resume.** It rewinds to the start of the section and re-arms the loop counter. Lift a hold with `resume()`, and carry on from a stop with `play(get_frame())`. +> **`play()` is not a resume.** It rewinds to the start of the section and re-arms the loop counter. Lift a hold with `resume()`, and carry on from a stop with `play(get_frame_no())`. --- @@ -293,4 +293,4 @@ Color and cell overrides conflict with the animation, so they take a `priority` - Assigning a different `.ssab` resource clears every override, because part identity is lost. - Overrides do not reach parts **inside** an instance part (the child animation runs as a separate player). Force-hiding the instance part itself does stop its contents from being drawn. -> **On when an override is not reflected in the drawing**: While playback is stopped or paused — or on any frame that does not advance — the drawing is not rebuilt, so setting or clearing an override will not appear on screen. Call `set_frame(get_frame())` to force a redraw when you need it reflected immediately. +> **On when an override is not reflected in the drawing**: While playback is stopped or paused — or on any frame that does not advance — the drawing is not rebuilt, so setting or clearing an override will not appear on screen. Call `set_frame_no(get_frame_no())` to force a redraw when you need it reflected immediately. diff --git a/docs/ja/api/player.md b/docs/ja/api/player.md index 5f03ad2..ad93d49 100644 --- a/docs/ja/api/player.md +++ b/docs/ja/api/player.md @@ -31,7 +31,7 @@ func _ready() -> void: * `set_animation_process_mode(mode: AnimationProcessMode)` / `get_animation_process_mode() -> AnimationProcessMode`: `ANIMATION_PROCESS_PHYSICS`(`0`)で Physics (`_physics_process`) 同期、`ANIMATION_PROCESS_IDLE`(`1`)で Idle (`_process`) 同期、`ANIMATION_PROCESS_MANUAL`(`2`)でノード自身による更新を停止します。 * `advance(delta: float)`: 再生を `delta` 秒ぶん進め、自動更新と同じように `frame_updated` を発行します。`ANIMATION_PROCESS_MANUAL` 向けの API です。他のモードで呼ぶと、ノード自身の更新に *加えて* アニメーションが進みます。 * **エディタ内プレビュー**: ノードを選択すると表示される **SpriteStudio** ボトムパネル(先頭から再生 / 現在位置から再生 / 停止、フレームスクラバ、ループと速度)で、ゲームを実行せずにプレビューできます。ショートカットは AnimationPlayer エディタと同じです(**D** 現在位置から再生 / **Shift+D** 先頭から再生 / **S** 停止)。*(旧 `editor_playing` インスペクタトグルはこのパネルに置き換えられました。)* -* `play(start_frame: float = -1.0)`: 再生を開始します。既定値の `-1.0` は、現在の再生ヘッド位置から続きを再生するのではなく、**区間の先頭に巻き戻します**(逆再生方向なら区間の末尾)。現在位置から再生したい場合は `get_frame()` を渡してください。 +* `play(start_frame: float = -1.0)`: 再生を開始します。既定値の `-1.0` は、現在の再生ヘッド位置から続きを再生するのではなく、**区間の先頭に巻き戻します**(逆再生方向なら区間の末尾)。現在位置から再生したい場合は `get_frame_no()` を渡してください。 * `pause()`: 現在のフレームを保持したまま、その場で再生を止めます。**冪等**です(2 回呼んでも一時停止のままで、再開はしません)。 * `resume()`: 保持を解除し、同じフレームから再開します。**冪等**で、一時停止ではなく停止している場合は何もしません(停止からの開始は `play()` で、こちらは巻き戻ります)。 * `stop()`: 再生を停止します。再生ヘッドは **その場に留まる** ため、停止したフレームを表示し続けます。 @@ -40,7 +40,7 @@ func _ready() -> void: * `just_looped() -> bool`: 直近の update でループ境界を跨いだかどうか。**パルス**であって状態ではありません — ランタイムが毎 update の冒頭でクリアするので、跨いだ tick の内側でのみ `true` です(だから `is_looped` ではありません。1 tick 遅れて読むと `false` になります)。ポーリングしたくなければ `animation_looped` シグナルが同じエッジを配ります。 * `get_animation_names() -> PackedStringArray`: 割り当てた [SSABResource] のアニメーション名一覧。`animation` プロパティが選ぶのと同じリストです。 * `is_playing_forward() -> bool`: 再生ヘッドが**実際に**進んでいる向きです。設定した向きを返す `get_playback_direction()` とは別物で、ピンポン再生の戻りの脚では `get_playback_direction()` が `PLAYBACK_DIRECTION_FORWARD` のままでもこちらは `false` になります(速度 0 以下は逆再生ではなく停止なので、これも反転しません)。**音声のゲートに使ってください** — SpriteStudio に逆再生音声は無いため、後ろ向きの脚で跨いだサウンドキーは鳴らすべきものではありません。`play_audio` が有効なときにプレイヤー自身が掛けている判定と同じものです。何も再生していないときは `true`(前進が既定の状態)。 -* `set_frame(frame: float)` / `get_frame() -> float` / `get_total_frames() -> int` +* `set_frame_no(frame: float)` / `get_frame_no() -> float` / `get_total_frames() -> int` * `get_start_frame() -> int` / `get_end_frame() -> int`: 実際に再生される先頭 / 末尾フレーム、すなわち現在の再生区間です。`get_animation_section_start()` / `get_animation_section_end()` と同じ値を返します(`set_animation_section()` で狭めるまではアニメーション全体)。 * `set_speed_scale(speed_scale: float)` / `get_speed_scale() -> float` * `set_frame_rate(fps: int)` / `get_frame_rate() -> int` diff --git a/docs/ja/troubleshooting.md b/docs/ja/troubleshooting.md index da9442f..f1df92e 100644 --- a/docs/ja/troubleshooting.md +++ b/docs/ja/troubleshooting.md @@ -56,7 +56,7 @@ ### オーバーライドが画面に反映されない -再生が停止・一時停止している間、あるいはフレームが進まないフレームでは描画が再構築されないため、オーバーライドを設定・解除しても見た目は変わりません。`set_frame(get_frame())` で再描画を強制してください。 +再生が停止・一時停止している間、あるいはフレームが進まないフレームでは描画が再構築されないため、オーバーライドを設定・解除しても見た目は変わりません。`set_frame_no(get_frame_no())` で再描画を強制してください。 ### `animation_finished` が発火しない diff --git a/docs/ja/workflow/usage_scripting.md b/docs/ja/workflow/usage_scripting.md index cf9adb7..c066b15 100644 --- a/docs/ja/workflow/usage_scripting.md +++ b/docs/ja/workflow/usage_scripting.md @@ -35,7 +35,7 @@ func _process(delta): > [!IMPORTANT] > 状態は 2 つではなく 3 つです。**`is_playing()` は一時停止中も `true` のまま**であり(一時停止は「保持」であって「停止」ではありません)、保持中かどうかを区別するのが `is_pausing()` です。初回の `play()` の前と `stop()` の後は、どちらも `false` になります。 > -> **`play()` は「再開」ではありません。** 区間の先頭へ巻き戻し、ループ回数を再設定します。保持の解除は `resume()`、停止位置からの続きは `play(get_frame())` を使ってください。 +> **`play()` は「再開」ではありません。** 区間の先頭へ巻き戻し、ループ回数を再設定します。保持の解除は `resume()`、停止位置からの続きは `play(get_frame_no())` を使ってください。 --- @@ -293,4 +293,4 @@ print(ss_player.get_cell_names("Ringo")) # → ["effect3", ...] - 別の `.ssab` リソースを割り当てると、パーツの同一性が失われるため全オーバーライドが解除されます。 - インスタンスパーツ**配下**のパーツには届きません(子アニメーションは別のプレーヤとして動作するためです)。インスタンスパーツ自体を強制非表示にした場合は、その配下もまとめて描画されなくなります。 -> **オーバーライドの設定が描画に反映されないタイミングについて**: アニメーション停止 / 一時停止中や、フレームが進まない状況では描画が更新されないため、オーバーライドの設定・解除が画面に反映されません。その場で反映させたい場合は `set_frame(get_frame())` を呼んで再描画させてください。 +> **オーバーライドの設定が描画に反映されないタイミングについて**: アニメーション停止 / 一時停止中や、フレームが進まない状況では描画が更新されないため、オーバーライドの設定・解除が画面に反映されません。その場で反映させたい場合は `set_frame_no(get_frame_no())` を呼んで再描画させてください。 diff --git a/ss_player/doc_classes/SpriteStudioPlayer2D.xml b/ss_player/doc_classes/SpriteStudioPlayer2D.xml index 340921d..76f08af 100644 --- a/ss_player/doc_classes/SpriteStudioPlayer2D.xml +++ b/ss_player/doc_classes/SpriteStudioPlayer2D.xml @@ -28,7 +28,7 @@ - Starts playback. [param start_frame] of [code]-1.0[/code] (the default) [b]rewinds to the start of the playback section[/b] - its end when [method set_playback_direction] is set to [constant PLAYBACK_DIRECTION_BACKWARD] - rather than continuing from where the playhead is. Pass [method get_frame] to play on from the current position. + Starts playback. [param start_frame] of [code]-1.0[/code] (the default) [b]rewinds to the start of the playback section[/b] - its end when [method set_playback_direction] is set to [constant PLAYBACK_DIRECTION_BACKWARD] - rather than continuing from where the playhead is. Pass [method get_frame_no] to play on from the current position. This is a fresh start, not a resume: it re-arms the loop counter and clears the paused state. Resuming a pause is [method pause]'s own toggle. @@ -47,7 +47,7 @@ - Stops playback. The playhead [b]stays where it was[/b], so the node keeps drawing the frame it stopped on; seek with [member frame] or start over with [method play] if you want it elsewhere. + Stops playback. The playhead [b]stays where it was[/b], so the node keeps drawing the frame it stopped on; seek with [member frame_no] or start over with [method play] if you want it elsewhere. @@ -351,8 +351,8 @@ Last frame of the played section, inclusive. Setting it keeps [member animation_section_start]; use [method set_animation_section] to move both endpoints at once. - - Current playback frame (editor-only display). Can be keyframed from an [AnimationPlayer] to drive playback from a timeline. + + Where the playhead is, in frames. Fractional: sub-frame interpolation puts it between two authored frames, which is why it is not called [code]frame[/code] - [member AnimatedSprite2D.frame] is an integer index into a [SpriteFrames] set and means something else. Editor-only display. Can be keyframed from an [AnimationPlayer] to drive playback from a timeline. Playback speed multiplier. [code]1.0[/code] is normal speed. diff --git a/ss_player/ss_internal_player.cpp b/ss_player/ss_internal_player.cpp index d3fcad7..60c61f4 100644 --- a/ss_player/ss_internal_player.cpp +++ b/ss_player/ss_internal_player.cpp @@ -556,14 +556,14 @@ float SsInternalPlayer::getSpeed() const { return ss_runtime_get_animation_speed(runtime_ctx); } -void SsInternalPlayer::setFrame(float p_frame) { +void SsInternalPlayer::setFrameNo(float p_frame) { if (runtime_ctx) { ss_runtime_set_frame_no(runtime_ctx, p_frame); _seek_and_redraw(ss_runtime_get_frame_no(runtime_ctx), 0.0f, false); } } -float SsInternalPlayer::getFrame() const { +float SsInternalPlayer::getFrameNo() const { return ss_runtime_get_frame_no(runtime_ctx); } diff --git a/ss_player/ss_internal_player.h b/ss_player/ss_internal_player.h index 43ce222..8a4d3c3 100644 --- a/ss_player/ss_internal_player.h +++ b/ss_player/ss_internal_player.h @@ -141,8 +141,8 @@ class SsInternalPlayer { void setSpeed(float p_speed); float getSpeed() const; - void setFrame(float p_frame); - float getFrame() const; + void setFrameNo(float p_frame); + float getFrameNo() const; int getTotalFrames() const; @@ -770,7 +770,7 @@ class SsInternalPlayer { // forwarded to children whose EventInstance has `independent = true` // (those children run their own controller via `ss_runtime_update` // rather than being seeked deterministically from `parent_frame_no`). - // Pass 0 from non-tick callers (`setFrame`, `setSubFrameEnabled`, + // Pass 0 from non-tick callers (`setFrameNo`, `setSubFrameEnabled`, // `_fetchAnimation`) — synced children still update via parent-frame // seek; independent children stay where they are. // @@ -800,7 +800,7 @@ class SsInternalPlayer { // Apply the current `frame_no` to this player's draw state in one shot: // resolve `draw_frame` per `_sub_frame_enabled`, store it as // `previous_frame_no`, drive Instance children for that frame, and - // redraw. Used by `setFrame`, `setSubFrameEnabled`, `_fetchAnimation` + // redraw. Used by `setFrameNo`, `setSubFrameEnabled`, `_fetchAnimation` // (delta=0, parent_looped=false — non-tick callers don't step // independent children) and the per-tick `update` path. void _seek_and_redraw(float frame_no, float delta_seconds, bool parent_looped); diff --git a/ss_player/ss_playback_panel.cpp b/ss_player/ss_playback_panel.cpp index ef90ffe..22343a3 100644 --- a/ss_player/ss_playback_panel.cpp +++ b/ss_player/ss_playback_panel.cpp @@ -252,7 +252,7 @@ void SSPlaybackPanel::_sync_playhead() { return; } _updating = true; - float frame = _player->getFrame(); + float frame = _player->getFrameNo(); _frame_slider->set_value(frame); _frame_spin->set_value(frame); _updating = false; @@ -320,7 +320,7 @@ void SSPlaybackPanel::_on_play_pressed() { // ss_runtime_play, which does not restart from a stopped state; passing the // current frame routes through play_with_start_frame so it reliably plays // from wherever the playhead is. - _player->play(_player->getFrame()); + _player->play(_player->getFrameNo()); } void SSPlaybackPanel::_on_stop_pressed() { @@ -349,7 +349,7 @@ void SSPlaybackPanel::_on_slider_changed(double p_value) { if (_updating || !_player) { return; } - _player->setFrame((float)p_value); + _player->setFrameNo((float)p_value); _updating = true; _frame_spin->set_value(p_value); _updating = false; @@ -359,7 +359,7 @@ void SSPlaybackPanel::_on_frame_spin_changed(double p_value) { if (_updating || !_player) { return; } - _player->setFrame((float)p_value); + _player->setFrameNo((float)p_value); _updating = true; _frame_slider->set_value(p_value); _updating = false; diff --git a/ss_player/ss_player_node_2d.cpp b/ss_player/ss_player_node_2d.cpp index de940fa..0d9c537 100644 --- a/ss_player/ss_player_node_2d.cpp +++ b/ss_player/ss_player_node_2d.cpp @@ -429,14 +429,14 @@ void SpriteStudioPlayer2D::advance(double p_delta) { _internal->update(p_delta); // Same post-update contract as an automatic tick: world matrices are final, // so part attachments mirror their parts before anything draws. - emit_signal(SNAME("frame_updated"), _internal->getFrame()); + emit_signal(SNAME("frame_updated"), _internal->getFrameNo()); } void SpriteStudioPlayer2D::setSpeedScale(float p_speed) { _internal->setSpeed(p_speed); } float SpriteStudioPlayer2D::getSpeedScale() const { return _internal->getSpeed(); } -void SpriteStudioPlayer2D::setFrame(float p_frame) { _internal->setFrame(p_frame); } -float SpriteStudioPlayer2D::getFrame() const { return _internal->getFrame(); } +void SpriteStudioPlayer2D::setFrameNo(float p_frame) { _internal->setFrameNo(p_frame); } +float SpriteStudioPlayer2D::getFrameNo() const { return _internal->getFrameNo(); } int SpriteStudioPlayer2D::getTotalFrames() const { return _internal->getTotalFrames(); } @@ -497,8 +497,8 @@ void SpriteStudioPlayer2D::_bind_methods() { ClassDB::bind_method( D_METHOD( "set_speed_scale", "speed_scale" ), &SpriteStudioPlayer2D::setSpeedScale ); ClassDB::bind_method( D_METHOD( "get_speed_scale" ), &SpriteStudioPlayer2D::getSpeedScale ); - ClassDB::bind_method( D_METHOD( "set_frame", "frame" ), &SpriteStudioPlayer2D::setFrame ); - ClassDB::bind_method( D_METHOD( "get_frame" ), &SpriteStudioPlayer2D::getFrame ); + ClassDB::bind_method( D_METHOD( "set_frame_no", "frame_no" ), &SpriteStudioPlayer2D::setFrameNo ); + ClassDB::bind_method( D_METHOD( "get_frame_no" ), &SpriteStudioPlayer2D::getFrameNo ); ClassDB::bind_method( D_METHOD( "get_total_frames" ), &SpriteStudioPlayer2D::getTotalFrames ); ClassDB::bind_method( D_METHOD( "get_start_frame" ), &SpriteStudioPlayer2D::getStartFrame ); @@ -631,7 +631,7 @@ void SpriteStudioPlayer2D::_bind_methods() { 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. - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "frame", PROPERTY_HINT_RANGE, "0,0,0.01", PROPERTY_USAGE_EDITOR), "set_frame", "get_frame"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "frame_no", PROPERTY_HINT_RANGE, "0,0,0.01", PROPERTY_USAGE_EDITOR), "set_frame_no", "get_frame_no"); ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_count", PROPERTY_HINT_RANGE, "-1,9999,1,or_greater"), "set_loop_count", "get_loop_count"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale", PROPERTY_HINT_RANGE, "0,4,0.01,or_greater"), "set_speed_scale", "get_speed_scale"); @@ -764,7 +764,7 @@ void SpriteStudioPlayer2D::_validate_property(PropertyInfo& p_property) const { // The playhead and the section endpoints are bounded by the current // animation's length, which only the instance knows. - bool is_frame = p_property.name == StringName("frame"); + bool is_frame = p_property.name == StringName("frame_no"); bool is_section = p_property.name == StringName("animation_section_start") || p_property.name == StringName("animation_section_end"); if (is_frame || is_section) { @@ -824,7 +824,7 @@ void SpriteStudioPlayer2D::_notification(int p_notification) { _internal->update(get_process_delta_time()); // Post-update: world matrices are final this tick, so part // attachments can mirror their parts in the same frame. - emit_signal(SNAME("frame_updated"), _internal->getFrame()); + emit_signal(SNAME("frame_updated"), _internal->getFrameNo()); } // Audio voices advance independently of the animation's play/pause // state (fire-and-forget), so tick every frame the node processes. @@ -834,7 +834,7 @@ void SpriteStudioPlayer2D::_notification(int p_notification) { if (_process_mode == ANIMATION_PROCESS_PHYSICS) { _push_coverage_screen_scale(); _internal->update(get_physics_process_delta_time()); - emit_signal(SNAME("frame_updated"), _internal->getFrame()); + emit_signal(SNAME("frame_updated"), _internal->getFrameNo()); } if (_audio_controller) _audio_controller->tick(); break; diff --git a/ss_player/ss_player_node_2d.h b/ss_player/ss_player_node_2d.h index 0e96446..4405dfe 100644 --- a/ss_player/ss_player_node_2d.h +++ b/ss_player/ss_player_node_2d.h @@ -130,8 +130,8 @@ class SpriteStudioPlayer2D : public Node2D { void setSpeedScale( float p_speed ); float getSpeedScale() const; - void setFrame( float p_frame ); - float getFrame() const; + void setFrameNo( float p_frame ); + float getFrameNo() const; int getTotalFrames() const;