You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-02 16:48:55 +00:00
Add animation reset track feature
As a bonus, to have consistency between use Beziers and create insert tracks, use Beziers also gets a default via editor settings that is used when the confirmation dialog is disabled, instead of just falling back to creating non-Bezier tracks.
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#include "editor/plugins/animation_player_editor_plugin.h"
|
||||
#include "editor_node.h"
|
||||
#include "editor_scale.h"
|
||||
#include "scene/animation/animation_player.h"
|
||||
#include "scene/main/window.h"
|
||||
#include "servers/audio/audio_stream.h"
|
||||
|
||||
@@ -3299,6 +3300,19 @@ void AnimationTrackEditor::set_anim_pos(float p_pos) {
|
||||
bezier_edit->set_play_position(p_pos);
|
||||
}
|
||||
|
||||
static bool track_type_is_resettable(Animation::TrackType p_type) {
|
||||
switch (p_type) {
|
||||
case Animation::TYPE_VALUE:
|
||||
[[fallthrough]];
|
||||
case Animation::TYPE_BEZIER:
|
||||
[[fallthrough]];
|
||||
case Animation::TYPE_TRANSFORM:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
|
||||
if (insert_frame != Engine::get_singleton()->get_frames_drawn()) {
|
||||
//clear insert list for the frame if frame changed
|
||||
@@ -3319,40 +3333,58 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
|
||||
|
||||
insert_data.push_back(p_id);
|
||||
|
||||
bool reset_allowed = true;
|
||||
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
|
||||
if (player->has_animation("RESET") && player->get_animation("RESET") == animation) {
|
||||
// Avoid messing with the reset animation itself
|
||||
reset_allowed = false;
|
||||
} else {
|
||||
bool some_resettable = false;
|
||||
for (int i = 0; i < insert_data.size(); i++) {
|
||||
if (track_type_is_resettable(insert_data[i].type)) {
|
||||
some_resettable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!some_resettable) {
|
||||
reset_allowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_id.track_idx == -1) {
|
||||
if (bool(EDITOR_DEF("editors/animation/confirm_insert_track", true))) {
|
||||
//potential new key, does not exist
|
||||
int num_tracks = 0;
|
||||
bool all_bezier = true;
|
||||
for (int i = 0; i < insert_data.size(); i++) {
|
||||
if (insert_data[i].type != Animation::TYPE_VALUE && insert_data[i].type != Animation::TYPE_BEZIER) {
|
||||
all_bezier = false;
|
||||
}
|
||||
|
||||
if (insert_data[i].track_idx == -1) {
|
||||
++num_tracks;
|
||||
}
|
||||
|
||||
if (insert_data[i].type != Animation::TYPE_VALUE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (insert_data[i].value.get_type()) {
|
||||
case Variant::INT:
|
||||
case Variant::FLOAT:
|
||||
case Variant::VECTOR2:
|
||||
case Variant::VECTOR3:
|
||||
case Variant::QUAT:
|
||||
case Variant::PLANE:
|
||||
case Variant::COLOR: {
|
||||
// Valid.
|
||||
} break;
|
||||
default: {
|
||||
all_bezier = false;
|
||||
}
|
||||
}
|
||||
int num_tracks = 0;
|
||||
bool all_bezier = true;
|
||||
for (int i = 0; i < insert_data.size(); i++) {
|
||||
if (insert_data[i].type != Animation::TYPE_VALUE && insert_data[i].type != Animation::TYPE_BEZIER) {
|
||||
all_bezier = false;
|
||||
}
|
||||
|
||||
if (insert_data[i].track_idx == -1) {
|
||||
++num_tracks;
|
||||
}
|
||||
|
||||
if (insert_data[i].type != Animation::TYPE_VALUE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (insert_data[i].value.get_type()) {
|
||||
case Variant::INT:
|
||||
case Variant::FLOAT:
|
||||
case Variant::VECTOR2:
|
||||
case Variant::VECTOR3:
|
||||
case Variant::QUAT:
|
||||
case Variant::PLANE:
|
||||
case Variant::COLOR: {
|
||||
// Valid.
|
||||
} break;
|
||||
default: {
|
||||
all_bezier = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bool(EDITOR_DEF("editors/animation/confirm_insert_track", true))) {
|
||||
//potential new key, does not exist
|
||||
if (num_tracks == 1) {
|
||||
insert_confirm_text->set_text(vformat(TTR("Create new track for %s and insert key?"), p_id.query));
|
||||
} else {
|
||||
@@ -3360,23 +3392,26 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
|
||||
}
|
||||
|
||||
insert_confirm_bezier->set_visible(all_bezier);
|
||||
insert_confirm_reset->set_visible(reset_allowed);
|
||||
|
||||
insert_confirm->get_ok_button()->set_text(TTR("Create"));
|
||||
insert_confirm->popup_centered();
|
||||
insert_query = true;
|
||||
} else {
|
||||
call_deferred("_insert_delay");
|
||||
call_deferred("_insert_delay", reset_allowed && EDITOR_GET("editors/animation/default_create_reset_tracks"), all_bezier && EDITOR_GET("editors/animation/default_create_bezier_tracks"));
|
||||
insert_queue = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!insert_query && !insert_queue) {
|
||||
call_deferred("_insert_delay");
|
||||
// Create Beziers wouldn't make sense in this case, where no tracks are being created
|
||||
call_deferred("_insert_delay", reset_allowed && EDITOR_GET("editors/animation/default_create_reset_tracks"), false);
|
||||
insert_queue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationTrackEditor::_insert_delay() {
|
||||
void AnimationTrackEditor::_insert_delay(bool p_create_reset, bool p_create_beziers) {
|
||||
if (insert_query) {
|
||||
//discard since it's entered into query mode
|
||||
insert_queue = false;
|
||||
@@ -3385,13 +3420,18 @@ void AnimationTrackEditor::_insert_delay() {
|
||||
|
||||
undo_redo->create_action(TTR("Anim Insert"));
|
||||
|
||||
int last_track = animation->get_track_count();
|
||||
Ref<Animation> reset_anim;
|
||||
if (p_create_reset) {
|
||||
reset_anim = _create_and_get_reset_animation();
|
||||
}
|
||||
|
||||
TrackIndices next_tracks(animation.ptr(), reset_anim.ptr());
|
||||
bool advance = false;
|
||||
while (insert_data.size()) {
|
||||
if (insert_data.front()->get().advance) {
|
||||
advance = true;
|
||||
}
|
||||
last_track = _confirm_insert(insert_data.front()->get(), last_track);
|
||||
next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, p_create_reset, p_create_beziers);
|
||||
insert_data.pop_front();
|
||||
}
|
||||
|
||||
@@ -3682,12 +3722,34 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() {
|
||||
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
|
||||
if (player->has_animation("RESET")) {
|
||||
return player->get_animation("RESET");
|
||||
} else {
|
||||
Ref<Animation> reset_anim;
|
||||
reset_anim.instance();
|
||||
reset_anim->set_length(ANIM_MIN_LENGTH);
|
||||
undo_redo->add_do_method(player, "add_animation", "RESET", reset_anim);
|
||||
undo_redo->add_do_method(AnimationPlayerEditor::singleton, "_animation_player_changed", player);
|
||||
undo_redo->add_undo_method(player, "remove_animation", "RESET");
|
||||
undo_redo->add_undo_method(AnimationPlayerEditor::singleton, "_animation_player_changed", player);
|
||||
return reset_anim;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationTrackEditor::_confirm_insert_list() {
|
||||
undo_redo->create_action(TTR("Anim Create & Insert"));
|
||||
|
||||
int last_track = animation->get_track_count();
|
||||
bool create_reset = insert_confirm_reset->is_visible() && insert_confirm_reset->is_pressed();
|
||||
Ref<Animation> reset_anim;
|
||||
if (create_reset) {
|
||||
reset_anim = _create_and_get_reset_animation();
|
||||
}
|
||||
|
||||
TrackIndices next_tracks(animation.ptr(), reset_anim.ptr());
|
||||
while (insert_data.size()) {
|
||||
last_track = _confirm_insert(insert_data.front()->get(), last_track, insert_confirm_bezier->is_pressed());
|
||||
next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, create_reset, insert_confirm_bezier->is_pressed());
|
||||
insert_data.pop_front();
|
||||
}
|
||||
|
||||
@@ -3807,11 +3869,7 @@ static Vector<String> _get_bezier_subindices_for_type(Variant::Type p_type, bool
|
||||
return subindices;
|
||||
}
|
||||
|
||||
int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, bool p_create_beziers) {
|
||||
if (p_last_track == -1) {
|
||||
p_last_track = animation->get_track_count();
|
||||
}
|
||||
|
||||
AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_create_reset, bool p_create_beziers) {
|
||||
bool created = false;
|
||||
if (p_id.track_idx < 0) {
|
||||
if (p_create_beziers) {
|
||||
@@ -3823,10 +3881,10 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
|
||||
id.type = Animation::TYPE_BEZIER;
|
||||
id.value = p_id.value.get(subindices[i].substr(1, subindices[i].length()));
|
||||
id.path = String(p_id.path) + subindices[i];
|
||||
_confirm_insert(id, p_last_track + i);
|
||||
p_next_tracks = _confirm_insert(id, p_next_tracks, p_create_reset, false);
|
||||
}
|
||||
|
||||
return p_last_track + subindices.size();
|
||||
return p_next_tracks;
|
||||
}
|
||||
}
|
||||
created = true;
|
||||
@@ -3863,7 +3921,7 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
|
||||
}
|
||||
}
|
||||
|
||||
p_id.track_idx = p_last_track;
|
||||
p_id.track_idx = p_next_tracks.normal;
|
||||
|
||||
undo_redo->add_do_method(animation.ptr(), "add_track", p_id.type);
|
||||
undo_redo->add_do_method(animation.ptr(), "track_set_path", p_id.track_idx, p_id.path);
|
||||
@@ -3915,7 +3973,7 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
|
||||
// Just remove the track.
|
||||
undo_redo->add_undo_method(this, "_clear_selection", false);
|
||||
undo_redo->add_undo_method(animation.ptr(), "remove_track", animation->get_track_count());
|
||||
p_last_track++;
|
||||
p_next_tracks.normal++;
|
||||
} else {
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_position", p_id.track_idx, time);
|
||||
int existing = animation->track_find_key(p_id.track_idx, time, true);
|
||||
@@ -3926,9 +3984,27 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
|
||||
}
|
||||
}
|
||||
|
||||
if (p_create_reset && track_type_is_resettable(p_id.type)) {
|
||||
bool create_reset_track = true;
|
||||
Animation *reset_anim = AnimationPlayerEditor::singleton->get_player()->get_animation("RESET").ptr();
|
||||
for (int i = 0; i < reset_anim->get_track_count(); i++) {
|
||||
if (reset_anim->track_get_path(i) == p_id.path) {
|
||||
create_reset_track = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (create_reset_track) {
|
||||
undo_redo->add_do_method(reset_anim, "add_track", p_id.type);
|
||||
undo_redo->add_do_method(reset_anim, "track_set_path", p_next_tracks.reset, p_id.path);
|
||||
undo_redo->add_do_method(reset_anim, "track_insert_key", p_next_tracks.reset, 0.0f, value);
|
||||
undo_redo->add_undo_method(reset_anim, "remove_track", reset_anim->get_track_count());
|
||||
p_next_tracks.reset++;
|
||||
}
|
||||
}
|
||||
|
||||
undo_redo->commit_action();
|
||||
|
||||
return p_last_track;
|
||||
return p_next_tracks;
|
||||
}
|
||||
|
||||
void AnimationTrackEditor::show_select_node_warning(bool p_show) {
|
||||
@@ -4224,6 +4300,7 @@ void AnimationTrackEditor::_notification(int p_what) {
|
||||
selected_filter->set_icon(get_theme_icon("AnimationFilter", "EditorIcons"));
|
||||
imported_anim_warning->set_icon(get_theme_icon("NodeWarning", "EditorIcons"));
|
||||
main_panel->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree"));
|
||||
edit->get_popup()->set_item_icon(edit->get_popup()->get_item_index(EDIT_APPLY_RESET), get_theme_icon("Reload", "EditorIcons"));
|
||||
}
|
||||
|
||||
if (p_what == NOTIFICATION_READY) {
|
||||
@@ -5056,6 +5133,11 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationTrackEditor::_edit_menu_about_to_popup() {
|
||||
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
|
||||
edit->get_popup()->set_item_disabled(edit->get_popup()->get_item_index(EDIT_APPLY_RESET), !player->can_apply_reset());
|
||||
}
|
||||
|
||||
void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
|
||||
last_menu_track_opt = p_option;
|
||||
switch (p_option) {
|
||||
@@ -5377,6 +5459,10 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
|
||||
set_anim_pos(pos);
|
||||
emit_signal("timeline_changed", pos, true);
|
||||
|
||||
} break;
|
||||
case EDIT_APPLY_RESET: {
|
||||
AnimationPlayerEditor::singleton->get_player()->apply_reset(true);
|
||||
|
||||
} break;
|
||||
case EDIT_OPTIMIZE_ANIMATION: {
|
||||
optimize_dialog->popup_centered(Size2(250, 180) * EDSCALE);
|
||||
@@ -5710,10 +5796,13 @@ AnimationTrackEditor::AnimationTrackEditor() {
|
||||
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/goto_next_step", TTR("Go to Next Step"), KEY_MASK_CMD | KEY_RIGHT), EDIT_GOTO_NEXT_STEP);
|
||||
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/goto_prev_step", TTR("Go to Previous Step"), KEY_MASK_CMD | KEY_LEFT), EDIT_GOTO_PREV_STEP);
|
||||
edit->get_popup()->add_separator();
|
||||
edit->get_popup()->add_shortcut(ED_SHORTCUT("animation_editor/apply_reset", TTR("Apply Reset")), EDIT_APPLY_RESET);
|
||||
edit->get_popup()->add_separator();
|
||||
edit->get_popup()->add_item(TTR("Optimize Animation"), EDIT_OPTIMIZE_ANIMATION);
|
||||
edit->get_popup()->add_item(TTR("Clean-Up Animation"), EDIT_CLEAN_UP_ANIMATION);
|
||||
|
||||
edit->get_popup()->connect("id_pressed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed));
|
||||
edit->get_popup()->connect("about_to_popup", callable_mp(this, &AnimationTrackEditor::_edit_menu_about_to_popup));
|
||||
|
||||
pick_track = memnew(SceneTreeDialog);
|
||||
add_child(pick_track);
|
||||
@@ -5739,9 +5828,16 @@ AnimationTrackEditor::AnimationTrackEditor() {
|
||||
insert_confirm->add_child(icvb);
|
||||
insert_confirm_text = memnew(Label);
|
||||
icvb->add_child(insert_confirm_text);
|
||||
HBoxContainer *ichb = memnew(HBoxContainer);
|
||||
icvb->add_child(ichb);
|
||||
insert_confirm_bezier = memnew(CheckBox);
|
||||
insert_confirm_bezier->set_text(TTR("Use Bezier Curves"));
|
||||
icvb->add_child(insert_confirm_bezier);
|
||||
insert_confirm_bezier->set_pressed(EDITOR_GET("editors/animation/default_create_bezier_tracks"));
|
||||
ichb->add_child(insert_confirm_bezier);
|
||||
insert_confirm_reset = memnew(CheckBox);
|
||||
insert_confirm_reset->set_text(TTR("Create RESET Track(s)", ""));
|
||||
insert_confirm_reset->set_pressed(EDITOR_GET("editors/animation/default_create_reset_tracks"));
|
||||
ichb->add_child(insert_confirm_reset);
|
||||
keying = false;
|
||||
moving_selection = false;
|
||||
key_edit = nullptr;
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
#include "scene/resources/animation.h"
|
||||
#include "scene_tree_editor.h"
|
||||
|
||||
class AnimationPlayer;
|
||||
|
||||
class AnimationTimelineEdit : public Range {
|
||||
GDCLASS(AnimationTimelineEdit, Range);
|
||||
|
||||
@@ -285,6 +287,7 @@ class AnimationTrackEditor : public VBoxContainer {
|
||||
EDIT_DELETE_SELECTION,
|
||||
EDIT_GOTO_NEXT_STEP,
|
||||
EDIT_GOTO_PREV_STEP,
|
||||
EDIT_APPLY_RESET,
|
||||
EDIT_OPTIMIZE_ANIMATION,
|
||||
EDIT_OPTIMIZE_ANIMATION_CONFIRM,
|
||||
EDIT_CLEAN_UP_ANIMATION,
|
||||
@@ -361,6 +364,7 @@ class AnimationTrackEditor : public VBoxContainer {
|
||||
|
||||
Label *insert_confirm_text;
|
||||
CheckBox *insert_confirm_bezier;
|
||||
CheckBox *insert_confirm_reset;
|
||||
ConfirmationDialog *insert_confirm;
|
||||
bool insert_queue;
|
||||
bool inserting;
|
||||
@@ -369,9 +373,19 @@ class AnimationTrackEditor : public VBoxContainer {
|
||||
uint64_t insert_frame;
|
||||
|
||||
void _query_insert(const InsertData &p_id);
|
||||
Ref<Animation> _create_and_get_reset_animation();
|
||||
void _confirm_insert_list();
|
||||
int _confirm_insert(InsertData p_id, int p_last_track, bool p_create_beziers = false);
|
||||
void _insert_delay();
|
||||
struct TrackIndices {
|
||||
int normal;
|
||||
int reset;
|
||||
|
||||
TrackIndices(const Animation *p_anim = nullptr, const Animation *p_reset_anim = nullptr) {
|
||||
normal = p_anim ? p_anim->get_track_count() : 0;
|
||||
reset = p_reset_anim ? p_reset_anim->get_track_count() : 0;
|
||||
}
|
||||
};
|
||||
TrackIndices _confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_create_reset, bool p_create_beziers);
|
||||
void _insert_delay(bool p_create_reset, bool p_create_beziers);
|
||||
|
||||
void _root_removed(Node *p_root);
|
||||
|
||||
@@ -447,6 +461,7 @@ class AnimationTrackEditor : public VBoxContainer {
|
||||
|
||||
void _select_all_tracks_for_copy();
|
||||
|
||||
void _edit_menu_about_to_popup();
|
||||
void _edit_menu_pressed(int p_option);
|
||||
int last_menu_track_opt;
|
||||
|
||||
|
||||
@@ -1419,6 +1419,17 @@ int EditorNode::_save_external_resources() {
|
||||
return saved;
|
||||
}
|
||||
|
||||
static void _reset_animation_players(Node *p_node, List<Ref<AnimatedValuesBackup>> *r_anim_backups) {
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(p_node->get_child(i));
|
||||
if (player && player->is_reset_on_save_enabled() && player->can_apply_reset()) {
|
||||
Ref<AnimatedValuesBackup> old_values = player->apply_reset();
|
||||
r_anim_backups->push_back(old_values);
|
||||
}
|
||||
_reset_animation_players(p_node->get_child(i), r_anim_backups);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorNode::_save_scene(String p_file, int idx) {
|
||||
Node *scene = editor_data.get_edited_scene_root(idx);
|
||||
|
||||
@@ -1433,6 +1444,8 @@ void EditorNode::_save_scene(String p_file, int idx) {
|
||||
}
|
||||
|
||||
editor_data.apply_changes_in_editors();
|
||||
List<Ref<AnimatedValuesBackup>> anim_backups;
|
||||
_reset_animation_players(scene, &anim_backups);
|
||||
_save_default_environment();
|
||||
|
||||
_set_scene_metadata(p_file, idx);
|
||||
@@ -1480,6 +1493,11 @@ void EditorNode::_save_scene(String p_file, int idx) {
|
||||
_save_external_resources();
|
||||
|
||||
editor_data.save_editor_external_data();
|
||||
|
||||
for (List<Ref<AnimatedValuesBackup>>::Element *E = anim_backups.front(); E; E = E->next()) {
|
||||
E->get()->restore();
|
||||
}
|
||||
|
||||
if (err == OK) {
|
||||
scene->set_filename(ProjectSettings::get_singleton()->localize_path(p_file));
|
||||
if (idx < 0 || idx == editor_data.get_edited_scene()) {
|
||||
|
||||
@@ -628,6 +628,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
||||
// Animation
|
||||
_initial_set("editors/animation/autorename_animation_tracks", true);
|
||||
_initial_set("editors/animation/confirm_insert_track", true);
|
||||
_initial_set("editors/animation/default_create_bezier_tracks", false);
|
||||
_initial_set("editors/animation/default_create_reset_tracks", true);
|
||||
_initial_set("editors/animation/onion_layers_past_color", Color(1, 0, 0));
|
||||
_initial_set("editors/animation/onion_layers_future_color", Color(0, 1, 0));
|
||||
|
||||
|
||||
@@ -116,6 +116,19 @@ void AnimationPlayerEditor::_notification(int p_what) {
|
||||
play_bw_from->set_icon(get_theme_icon("PlayBackwards", "EditorIcons"));
|
||||
|
||||
autoplay_icon = get_theme_icon("AutoPlay", "EditorIcons");
|
||||
reset_icon = get_theme_icon("Reload", "EditorIcons");
|
||||
{
|
||||
Ref<Image> autoplay_img = autoplay_icon->get_data();
|
||||
Ref<Image> reset_img = reset_icon->get_data();
|
||||
Ref<Image> autoplay_reset_img;
|
||||
Size2 icon_size = Size2(autoplay_img->get_width(), autoplay_img->get_height());
|
||||
autoplay_reset_img.instance();
|
||||
autoplay_reset_img->create(icon_size.x * 2, icon_size.y, false, autoplay_img->get_format());
|
||||
autoplay_reset_img->blit_rect(autoplay_img, Rect2(Point2(), icon_size), Point2());
|
||||
autoplay_reset_img->blit_rect(reset_img, Rect2(Point2(), icon_size), Point2(icon_size.x, 0));
|
||||
autoplay_reset_icon.instance();
|
||||
autoplay_reset_icon->create_from_image(autoplay_reset_img);
|
||||
}
|
||||
stop->set_icon(get_theme_icon("Stop", "EditorIcons"));
|
||||
|
||||
onion_toggle->set_icon(get_theme_icon("Onion", "EditorIcons"));
|
||||
@@ -817,11 +830,17 @@ void AnimationPlayerEditor::_update_player() {
|
||||
|
||||
int active_idx = -1;
|
||||
for (List<StringName>::Element *E = animlist.front(); E; E = E->next()) {
|
||||
if (player->get_autoplay() == E->get()) {
|
||||
animation->add_icon_item(autoplay_icon, E->get());
|
||||
} else {
|
||||
animation->add_item(E->get());
|
||||
Ref<Texture2D> icon;
|
||||
if (E->get() == player->get_autoplay()) {
|
||||
if (E->get() == "RESET") {
|
||||
icon = autoplay_reset_icon;
|
||||
} else {
|
||||
icon = autoplay_icon;
|
||||
}
|
||||
} else if (E->get() == "RESET") {
|
||||
icon = reset_icon;
|
||||
}
|
||||
animation->add_icon_item(icon, E->get());
|
||||
|
||||
if (player->get_assigned_animation() == E->get()) {
|
||||
active_idx = animation->get_item_count() - 1;
|
||||
@@ -1375,7 +1394,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
|
||||
}
|
||||
|
||||
// Backup current animation state.
|
||||
AnimatedValuesBackup values_backup = player->backup_animated_values();
|
||||
Ref<AnimatedValuesBackup> values_backup = player->backup_animated_values();
|
||||
float cpos = player->get_current_animation_position();
|
||||
|
||||
// Render every past/future step with the capture shader.
|
||||
@@ -1405,7 +1424,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
|
||||
if (valid) {
|
||||
player->seek(pos, true);
|
||||
get_tree()->flush_transform_notifications(); // Needed for transforms of Node3Ds.
|
||||
values_backup.update_skeletons(); // Needed for Skeletons (2D & 3D).
|
||||
values_backup->update_skeletons(); // Needed for Skeletons (2D & 3D).
|
||||
|
||||
RS::get_singleton()->viewport_set_active(onion.captures[cidx], true);
|
||||
RS::get_singleton()->viewport_set_parent_viewport(root_vp, onion.captures[cidx]);
|
||||
@@ -1425,7 +1444,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
|
||||
// (Seeking with update=true wouldn't do the trick because the current value of the properties
|
||||
// may not match their value for the current point in the animation).
|
||||
player->seek(cpos, false);
|
||||
player->restore_animated_values(values_backup);
|
||||
values_backup->restore();
|
||||
|
||||
// Restore state of main editors.
|
||||
if (Node3DEditor::get_singleton()->is_visible()) {
|
||||
|
||||
@@ -105,6 +105,8 @@ class AnimationPlayerEditor : public VBoxContainer {
|
||||
Label *name_title;
|
||||
UndoRedo *undo_redo;
|
||||
Ref<Texture2D> autoplay_icon;
|
||||
Ref<Texture2D> reset_icon;
|
||||
Ref<ImageTexture> autoplay_reset_icon;
|
||||
bool last_active;
|
||||
float timeline_position;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user