summaryrefslogtreecommitdiff
path: root/scene/animation/animation_player.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation/animation_player.cpp')
-rw-r--r--scene/animation/animation_player.cpp161
1 files changed, 88 insertions, 73 deletions
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 6463180d9e..9db4a5fb04 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "animation_player.h"
#include "engine.h"
@@ -48,24 +49,15 @@ bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name;
- if (p_name == SceneStringNames::get_singleton()->playback_speed || p_name == SceneStringNames::get_singleton()->speed) { //bw compatibility
- set_speed_scale(p_value);
-
- } else if (p_name == SceneStringNames::get_singleton()->playback_active) {
- set_active(p_value);
- } else if (name.begins_with("playback/play")) {
+ if (name.begins_with("playback/play")) { // bw compatibility
- String which = p_value;
+ set_current_animation(p_value);
- if (which == "[stop]")
- stop();
- else
- play(which);
} else if (name.begins_with("anims/")) {
String which = name.get_slicec('/', 1);
-
add_animation(which, p_value);
+
} else if (name.begins_with("next/")) {
String which = name.get_slicec('/', 1);
@@ -86,9 +78,6 @@ bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
set_blend_time(from, to, time);
}
- } else if (p_name == SceneStringNames::get_singleton()->autoplay) {
- autoplay = p_value;
-
} else
return false;
@@ -99,24 +88,15 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const {
String name = p_name;
- if (name == "playback/speed") { //bw compatibility
-
- r_ret = speed_scale;
- } else if (name == "playback/active") {
-
- r_ret = is_active();
- } else if (name == "playback/play") {
+ if (name == "playback/play") { // bw compatibility
- if (is_active() && is_playing())
- r_ret = playback.assigned;
- else
- r_ret = "[stop]";
+ r_ret = get_current_animation();
} else if (name.begins_with("anims/")) {
String which = name.get_slicec('/', 1);
-
r_ret = get_animation(which).get_ref_ptr();
+
} else if (name.begins_with("next/")) {
String which = name.get_slicec('/', 1);
@@ -140,27 +120,43 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const {
}
r_ret = array;
- } else if (name == "autoplay") {
- r_ret = autoplay;
-
} else
return false;
return true;
}
-void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const {
+void AnimationPlayer::_validate_property(PropertyInfo &property) const {
+
+ if (property.name == "current_animation") {
+ List<String> names;
+
+ for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
+ names.push_back(E->key());
+ }
+ names.sort();
+ names.push_front("[stop]");
+ String hint;
+ for (List<String>::Element *E = names.front(); E; E = E->next()) {
+
+ if (E != names.front())
+ hint += ",";
+ hint += E->get();
+ }
- List<String> names;
+ property.hint_string = hint;
+ }
+}
+
+void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const {
List<PropertyInfo> anim_names;
for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
- anim_names.push_back(PropertyInfo(Variant::OBJECT, "anims/" + String(E->key()), PROPERTY_HINT_RESOURCE_TYPE, "Animation", PROPERTY_USAGE_NOEDITOR));
+ anim_names.push_back(PropertyInfo(Variant::OBJECT, "anims/" + String(E->key()), PROPERTY_HINT_RESOURCE_TYPE, "Animation", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
if (E->get().next != StringName())
- anim_names.push_back(PropertyInfo(Variant::STRING, "next/" + String(E->key()), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- names.push_back(E->key());
+ anim_names.push_back(PropertyInfo(Variant::STRING, "next/" + String(E->key()), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
anim_names.sort();
@@ -169,24 +165,7 @@ void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(E->get());
}
- {
- names.sort();
- names.push_front("[stop]");
- String hint;
- for (List<String>::Element *E = names.front(); E; E = E->next()) {
-
- if (E != names.front())
- hint += ",";
- hint += E->get();
- }
-
- p_list->push_back(PropertyInfo(Variant::STRING, "playback/play", PROPERTY_HINT_ENUM, hint, PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ANIMATE_AS_TRIGGER));
- p_list->push_back(PropertyInfo(Variant::BOOL, "playback/active", PROPERTY_HINT_NONE, ""));
- p_list->push_back(PropertyInfo(Variant::REAL, "playback/speed", PROPERTY_HINT_RANGE, "-64,64,0.01"));
- }
-
- p_list->push_back(PropertyInfo(Variant::ARRAY, "blend_times", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::STRING, "autoplay", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, "blend_times", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
void AnimationPlayer::advance(float p_time) {
@@ -275,8 +254,8 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
}
{
- if (!child->is_connected("tree_exited", this, "_node_removed"))
- child->connect("tree_exited", this, "_node_removed", make_binds(child), CONNECT_ONESHOT);
+ if (!child->is_connected("tree_exiting", this, "_node_removed"))
+ child->connect("tree_exiting", this, "_node_removed", make_binds(child), CONNECT_ONESHOT);
}
TrackNodeCacheKey key;
@@ -547,12 +526,14 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f
if (!backwards && cd.pos <= len && next_pos == len /*&& playback.blend.empty()*/) {
//playback finished
- end_notify = true;
+ end_reached = true;
+ end_notify = cd.pos < len; // Notify only if not already at the end
}
if (backwards && cd.pos >= 0 && next_pos == 0 /*&& playback.blend.empty()*/) {
//playback finished
- end_notify = true;
+ end_reached = true;
+ end_notify = cd.pos > 0; // Notify only if not already at the beginning
}
}
@@ -679,24 +660,26 @@ void AnimationPlayer::_animation_process(float p_delta) {
if (playback.current.from) {
+ end_reached = false;
end_notify = false;
_animation_process2(p_delta);
_animation_update_transforms();
- if (end_notify) {
+ if (end_reached) {
if (queued.size()) {
String old = playback.assigned;
play(queued.front()->get());
String new_name = playback.assigned;
queued.pop_front();
- end_notify = false;
- emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name);
+ if (end_notify)
+ emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name);
} else {
//stop();
playing = false;
_set_process(false);
- end_notify = false;
- emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned);
+ if (end_notify)
+ emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned);
}
+ end_reached = false;
}
} else {
@@ -954,7 +937,7 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
c.current.speed_scale = p_custom_scale;
c.assigned = p_name;
- if (!end_notify)
+ if (!end_reached)
queued.clear();
_set_process(true); // always process when starting an animation
playing = true;
@@ -985,10 +968,27 @@ bool AnimationPlayer::is_playing() const {
};
return true;
- */
+ */
}
+
void AnimationPlayer::set_current_animation(const String &p_anim) {
+ if (p_anim == "[stop]" || p_anim == "") {
+ stop();
+ } else if (!is_playing() || playback.assigned != p_anim) {
+ play(p_anim);
+ } else {
+ // Same animation, do not replay from start
+ }
+}
+
+String AnimationPlayer::get_current_animation() const {
+
+ return (is_playing() ? playback.assigned : "");
+}
+
+void AnimationPlayer::set_assigned_animation(const String &p_anim) {
+
if (is_playing()) {
play(p_anim);
} else {
@@ -999,9 +999,9 @@ void AnimationPlayer::set_current_animation(const String &p_anim) {
}
}
-String AnimationPlayer::get_current_animation() const {
+String AnimationPlayer::get_assigned_animation() const {
- return (playback.assigned);
+ return playback.assigned;
}
void AnimationPlayer::stop(bool p_reset) {
@@ -1028,8 +1028,10 @@ float AnimationPlayer::get_speed_scale() const {
void AnimationPlayer::seek(float p_time, bool p_update) {
if (!playback.current.from) {
- if (playback.assigned)
- set_current_animation(playback.assigned);
+ if (playback.assigned) {
+ ERR_FAIL_COND(!animation_set.has(playback.assigned));
+ playback.current.from = &animation_set[playback.assigned];
+ }
ERR_FAIL_COND(!playback.current.from);
}
@@ -1042,8 +1044,10 @@ void AnimationPlayer::seek(float p_time, bool p_update) {
void AnimationPlayer::seek_delta(float p_time, float p_delta) {
if (!playback.current.from) {
- if (playback.assigned)
- set_current_animation(playback.assigned);
+ if (playback.assigned) {
+ ERR_FAIL_COND(!animation_set.has(playback.assigned));
+ playback.current.from = &animation_set[playback.assigned];
+ }
ERR_FAIL_COND(!playback.current.from);
}
@@ -1301,6 +1305,8 @@ void AnimationPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_current_animation", "anim"), &AnimationPlayer::set_current_animation);
ClassDB::bind_method(D_METHOD("get_current_animation"), &AnimationPlayer::get_current_animation);
+ ClassDB::bind_method(D_METHOD("set_assigned_animation", "anim"), &AnimationPlayer::set_assigned_animation);
+ ClassDB::bind_method(D_METHOD("get_assigned_animation"), &AnimationPlayer::get_assigned_animation);
ClassDB::bind_method(D_METHOD("queue", "name"), &AnimationPlayer::queue);
ClassDB::bind_method(D_METHOD("clear_queue"), &AnimationPlayer::clear_queue);
@@ -1329,14 +1335,22 @@ void AnimationPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("seek", "seconds", "update"), &AnimationPlayer::seek, DEFVAL(false));
ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationPlayer::advance);
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_node"), "set_root", "get_root");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_animation", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ANIMATE_AS_TRIGGER), "set_current_animation", "get_current_animation");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "assigned_animation", PROPERTY_HINT_NONE, "", 0), "set_assigned_animation", "get_assigned_animation");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "autoplay", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_autoplay", "get_autoplay");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "current_animation_length", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_length");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "current_animation_position", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_position");
+
ADD_GROUP("Playback Options", "playback_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "playback_default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_default_blend_time", "get_default_blend_time");
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_node"), "set_root", "get_root");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playback_active", PROPERTY_HINT_NONE, "", 0), "set_active", "is_active");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale");
- ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING, "name")));
+ ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING, "anim_name")));
ADD_SIGNAL(MethodInfo("animation_changed", PropertyInfo(Variant::STRING, "old_name"), PropertyInfo(Variant::STRING, "new_name")));
- ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::STRING, "name")));
+ ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::STRING, "anim_name")));
BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS);
BIND_ENUM_CONSTANT(ANIMATION_PROCESS_IDLE);
@@ -1348,6 +1362,7 @@ AnimationPlayer::AnimationPlayer() {
cache_update_size = 0;
cache_update_prop_size = 0;
speed_scale = 1;
+ end_reached = false;
end_notify = false;
animation_process_mode = ANIMATION_PROCESS_IDLE;
processing = false;