diff --git a/spine-flutter/lib/spine_flutter.dart b/spine-flutter/lib/spine_flutter.dart index 15456e786..faec23182 100644 --- a/spine-flutter/lib/spine_flutter.dart +++ b/spine-flutter/lib/spine_flutter.dart @@ -3311,19 +3311,19 @@ class TrackEntry { _bindings.spine_track_entry_set_mix_time(_entry, mixTime); } - /// Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData - /// {@link AnimationStateData#getMix(Animation, Animation)} based on the animation before this animation (if any). - ///
+ /// Seconds for mixing from the previous animation to this animation. Defaults to the value provided by + /// [AnimationStateData.getMix] based on the animation before this animation (if any). + /// /// A mix duration of 0 still mixes out over one frame to provide the track entry being mixed out a chance to revert the /// properties it was animating. A mix duration of 0 can be set at any time to end the mix on the next - /// {@link AnimationState#update(float) update}. - ///
+ /// [AnimationState.update].
+ ///
/// The mixDuration can be set manually rather than use the value from
- /// {@link AnimationStateData#getMix(Animation, Animation)}. In that case, the mixDuration can be set for a new
- /// track entry only before {@link AnimationState#update(float)} is first called.
+ /// [AnimationStateData.getMix]. In that case, the mixDuration can be set for a new
+ /// track entry only before [AnimationState.update] is first called.
///
- /// When using {@link AnimationState#addAnimation(int, Animation, boolean, float)} with a delay <= 0, the
- /// {@link #getDelay()} is set using the mix duration from the {@link AnimationStateData}. If mixDuration is set
+ /// When using [AnimationState.addAnimation] with a delay <= 0, the
+ /// [getDelay] is set using the mix duration from the [AnimationStateData]. If mixDuration is set
/// afterward, the delay may need to be adjusted. For example:
/// entry.delay = entry.previous.getTrackComplete() - entry.mixDuration;
double getMixDuration() {
@@ -3334,6 +3334,12 @@ class TrackEntry {
_bindings.spine_track_entry_set_mix_duration(_entry, mixDuration);
}
+ /// Controls how properties keyed in the animation are mixed with lower tracks. Defaults to [MixBlend.replace].
+ ///
+ /// Track entries on track 0 ignore this setting and always use {@link MixBlend#first}.
+ ///
+ /// The mixBlend can be set for a new track entry only before [AnimationState.apply] is first
+ /// called.
MixBlend getMixBlend() {
return MixBlend.values[_bindings.spine_track_entry_get_mix_blend(_entry)];
}
@@ -3342,16 +3348,16 @@ class TrackEntry {
_bindings.spine_track_entry_set_mix_blend(_entry, mixBlend.value);
}
- /// The track entry for the previous animation when mixing from the previous animation to this animation, or NULL if no
- /// mixing is currently occuring. When mixing from multiple animations, MixingFrom makes up a double linked list with MixingTo.
+ /// The track entry for the previous animation when mixing from the previous animation to this animation, or null if no
+ /// mixing is currently occurring. When mixing from multiple animations, mixingFrom makes up a linked list.
TrackEntry? getMixingFrom() {
final from = _bindings.spine_track_entry_get_mixing_from(_entry);
if (from.address == nullptr.address) return null;
return TrackEntry._(from, _state);
}
- /// The track entry for the next animation when mixing from this animation, or NULL if no mixing is currently occuring.
- /// When mixing from multiple animations, MixingTo makes up a double linked list with MixingFrom.
+ /// The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is
+ /// currently occurring. When mixing to multiple animations, mixingTo makes up a linked list.
TrackEntry? getMixingTo() {
final to = _bindings.spine_track_entry_get_mixing_to(_entry);
if (to.address == nullptr.address) return null;
@@ -3369,22 +3375,62 @@ class TrackEntry {
_bindings.spine_track_entry_reset_rotation_directions(_entry);
}
+ /// If this track entry is non-looping, the track time in seconds when [getAnimationEnd] is reached, or the current
+ /// [getTrackTime] if it has already been reached. If this track entry is looping, the track time when this
+ /// animation will reach its next [getAnimationEnd] (the next loop completion).
double getTrackComplete() {
return _bindings.spine_track_entry_get_track_complete(_entry);
}
+ /// The listener for events generated by this track entry, or null.
+ ///
+ /// A track entry returned from [AnimationState.setAnimation] is already the current animation
+ /// for the track, so the track entry listener will not be called for [EventType.start].
void setListener(AnimationStateListener? listener) {
_state._setTrackEntryListener(_entry, listener);
}
}
-enum EventType { start, interrupt, end, complete, dispose, event }
+/// The event type passed to [AnimationStateListener]
+enum EventType {
+ /// Emitted when [TrackEntry] has been set as the current entry. [EventType.end] will occur when this entry will no
+ /// longer be applied.
+ start,
+ /// Emitted when another entry has replaced the current entry. This entry may continue being applied for
+ /// mixing.
+ interrupt,
+ /// Emitted when this entry will never be applied again. This only occurs if this entry has previously been set as the
+ /// current entry ([EventType.start] was emitted).
+ end,
+ /// Emitted every time the current entry's animation completes a loop. This may occur during mixing (after
+ /// [EventType.interrupted] is emitted).
+ ///
+ /// If [TrackEntry.getMixingTo] of the entry reported by the event is not null, the entry is mixing out (it is not the current entry).
+ ///
+ /// Because this event is triggered at the end of [AnimationState.apply], any animations set in response to
+ /// the event won't be applied until the next time the [AnimationState] is applied.
+ complete,
+ /// Emitted when this entry will be disposed. This may occur without the entry ever being set as the current entry.
+ ///
+ /// References to the entry should not be kept after dispose is called, as it may be destroyed or reused.
+ dispose,
+ /// Invoked when the current entry's animation triggers an event. This may occur during mixing (after
+ /// [EventType.interrupt] is emitted), see [TrackEntry.getEventThreshold].
+ ///
+ /// Because this event is triggered at the end of [AnimationState.apply], any animations set in response to
+ /// the event won't be applied until the next time the [AnimationState] is applied.
+ event
+}
+/// Stores the setup pose values for an [Event].
+///
+/// See Events in the Spine User Guide.
class EventData {
final spine_event_data _data;
EventData._(this._data);
+ /// The name of the event, which is unique across all events in the skeleton.
String getName() {
final Pointerdelay (ie the mix
+ /// ends at (delay = 0) or before (delay < 0) the previous track entry duration). If the
+ /// previous entry is looping, its next loop completion is used instead of its duration.
+ ///
+ /// Returns a track entry to allow further customization of animation playback. References to the track entry must not be kept
+ /// after the [EventType.dispose] event occurs.
TrackEntry addAnimation(int trackIndex, Animation animation, bool loop, double delay) {
final entry = _bindings.spine_animation_state_add_animation(_state, trackIndex, animation._animation, loop ? -1 : 0, delay);
if (entry.address == nullptr.address) throw Exception("Couldn't add animation ${animation.getName()}");
return TrackEntry._(entry, this);
}
- /// Sets an empty animation for a track, discarding any queued animations, and mixes to it over the specified mix duration.
+ /// Sets an empty animation for a track at [trackIndex], discarding any queued animations, and sets the track entry's
+ /// [TrackEntry.getMixDuration] to [mixDuration]. An empty animation has no timelines and serves as a placeholder for mixing in or out.
+ ///
+ /// Mixing out is done by setting an empty animation with a mix duration using either [setEmptyAnimation],
+ /// [setEmptyAnimations], or [addEmptyAnimation]. Mixing to an empty animation causes
+ /// the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation
+ /// transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of
+ /// 0 still mixes out over one frame.
+ ///
+ /// Mixing in is done by first setting an empty animation, then adding an animation using
+ /// [addAnimation] with the desired delay (an empty animation has a duration of 0) and on
+ /// the returned track entry, set the [TrackEntry.setMixDuration]. Mixing from an empty animation causes the new
+ /// animation to be applied more and more over the mix duration. Properties keyed in the new animation transition from the value
+ /// from lower tracks or from the setup pose value if no lower tracks key the property to the value keyed in the new
+ /// animation.
TrackEntry setEmptyAnimation(int trackIndex, double mixDuration) {
final entry = _bindings.spine_animation_state_set_empty_animation(_state, trackIndex, mixDuration);
return TrackEntry._(entry, this);
}
- /// Adds an empty animation to be played after the current or last queued animation for a track, and mixes to it over the
- /// specified mix duration.
- /// @return
- /// A track entry to allow further customization of animation playback. References to the track entry must not be kept after AnimationState.Dispose.
+ /// Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's
+ /// [TrackEntry.getMixDuration]. If the track is empty, it is equivalent to calling
+ /// [setEmptyAnimation].
///
- /// @param trackIndex Track number.
- /// @param mixDuration Mix duration.
- /// @param delay Seconds to begin this animation after the start of the previous animation. May be <= 0 to use the animation
- /// duration of the previous track minus any mix duration plus the negative delay.
+ /// See [setEmptyAnimation].
+ ///
+ /// If [delay] > 0, sets [TrackEntry.getDelay]. If <= 0, the delay set is the duration of the previous track entry
+ /// minus any mix duration plus the specified delay (ie the mix ends at (delay = 0) or
+ /// before (delay < 0) the previous track entry duration). If the previous entry is looping, its next
+ /// loop completion is used instead of its duration.
+ ///
+ /// Returns a track entry to allow further customization of animation playback. References to the track entry must not be kept
+ /// after the [EventType.dispose] event occurs.
TrackEntry addEmptyAnimation(int trackIndex, double mixDuration, double delay) {
final entry = _bindings.spine_animation_state_add_empty_animation(_state, trackIndex, mixDuration, delay);
return TrackEntry._(entry, this);
}
+ /// Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing.
TrackEntry? getCurrent(int trackIndex) {
final entry = _bindings.spine_animation_state_get_current(_state, trackIndex);
if (entry.address == nullptr.address) return null;
return TrackEntry._(entry, this);
}
+ /// Returns the number of tracks that have animations queued.
int getNumTracks() {
return _bindings.spine_animation_state_get_num_tracks(_state);
}
- /// Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix duration.
+ /// Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix
+ /// duration.
void setEmptyAnimations(double mixDuration) {
_bindings.spine_animation_state_set_empty_animations(_state, mixDuration);
}
+ /// Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower
+ /// or faster. Defaults to 1.
+ ///
+ /// See [TrackEntry.getTimeScale] for affecting a single animation.
double getTimeScale() {
return _bindings.spine_animation_state_get_time_scale(_state);
}
@@ -3714,10 +3827,15 @@ class AnimationState {
_bindings.spine_animation_state_set_time_scale(_state, timeScale);
}
+ /// The [AnimationStateData] to look up mix durations.
AnimationStateData getData() {
return AnimationStateData._(_bindings.spine_animation_state_get_data(_state));
}
+ /// The listener for events generated for all tracks managed by the AnimationState, or null.
+ ///
+ /// A track entry returned from [setAnimation] is already the current animation
+ /// for the track, so the track entry listener will not be called for [EventType.start].
void setListener(AnimationStateListener? listener) {
_stateListener = listener;
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java
index 958aaab77..a7d12e3b8 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java
@@ -847,7 +847,7 @@ public class AnimationState {
this.timeScale = timeScale;
}
- /** The AnimationStateData to look up mix durations. */
+ /** The {@link AnimationStateData} to look up mix durations. */
public AnimationStateData getData () {
return data;
}
@@ -1199,13 +1199,13 @@ public class AnimationState {
}
/** The track entry for the previous animation when mixing from the previous animation to this animation, or null if no
- * mixing is currently occuring. When mixing from multiple animations, mixingFrom makes up a linked list. */
+ * mixing is currently occurring. When mixing from multiple animations, mixingFrom makes up a linked list. */
public @Null TrackEntry getMixingFrom () {
return mixingFrom;
}
/** The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is
- * currently occuring. When mixing to multiple animations, mixingTo makes up a linked list. */
+ * currently occurring. When mixing to multiple animations, mixingTo makes up a linked list. */
public @Null TrackEntry getMixingTo () {
return mixingTo;
}