41
41
#include " editor/gui/editor_spin_slider.h"
42
42
#include " editor/gui/scene_tree_editor.h"
43
43
#include " editor/inspector_dock.h"
44
+ #include " editor/multi_node_edit.h"
44
45
#include " editor/plugins/animation_player_editor_plugin.h"
45
46
#include " editor/themes/editor_scale.h"
46
47
#include " scene/3d/mesh_instance_3d.h"
@@ -3661,7 +3662,7 @@ void AnimationTrackEditor::update_keying() {
3661
3662
EditorSelectionHistory *editor_history = EditorNode::get_singleton ()->get_editor_selection_history ();
3662
3663
if (is_visible_in_tree () && animation.is_valid () && editor_history->get_path_size () > 0 ) {
3663
3664
Object *obj = ObjectDB::get_instance (editor_history->get_path_object (0 ));
3664
- keying_enabled = Object::cast_to<Node>(obj) != nullptr ;
3665
+ keying_enabled = Object::cast_to<Node>(obj) != nullptr || Object::cast_to<MultiNodeEdit>(obj) != nullptr ;
3665
3666
}
3666
3667
3667
3668
if (keying_enabled == keying) {
@@ -4078,19 +4079,20 @@ void AnimationTrackEditor::_insert_animation_key(NodePath p_path, const Variant
4078
4079
_query_insert (id);
4079
4080
}
4080
4081
4081
- void AnimationTrackEditor::insert_node_value_key (Node *p_node, const String &p_property, const Variant &p_value , bool p_only_if_exists ) {
4082
+ void AnimationTrackEditor::insert_node_value_key (Node *p_node, const String &p_property, bool p_only_if_exists , bool p_advance ) {
4082
4083
ERR_FAIL_NULL (root);
4083
4084
4084
4085
// Let's build a node path.
4085
- Node *node = p_node;
4086
- String path = root->get_path_to (node, true );
4086
+ String path = root->get_path_to (p_node, true );
4087
+
4088
+ Variant value = p_node->get (p_property);
4087
4089
4088
- if (Object::cast_to<AnimationPlayer>(node ) && p_property == " current_animation" ) {
4089
- if (node == AnimationPlayerEditor::get_singleton ()->get_player ()) {
4090
+ if (Object::cast_to<AnimationPlayer>(p_node ) && p_property == " current_animation" ) {
4091
+ if (p_node == AnimationPlayerEditor::get_singleton ()->get_player ()) {
4090
4092
EditorNode::get_singleton ()->show_warning (TTR (" AnimationPlayer can't animate itself, only other players." ));
4091
4093
return ;
4092
4094
}
4093
- _insert_animation_key (path, p_value );
4095
+ _insert_animation_key (path, value );
4094
4096
return ;
4095
4097
}
4096
4098
@@ -4118,26 +4120,26 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
4118
4120
InsertData id;
4119
4121
id.path = np;
4120
4122
id.track_idx = i;
4121
- id.value = p_value ;
4123
+ id.value = value ;
4122
4124
id.type = Animation::TYPE_VALUE;
4123
4125
// TRANSLATORS: This describes the target of new animation track, will be inserted into another string.
4124
4126
id.query = vformat (TTR (" property '%s'" ), p_property);
4125
- id.advance = false ;
4127
+ id.advance = p_advance ;
4126
4128
// Dialog insert.
4127
4129
_query_insert (id);
4128
4130
inserted = true ;
4129
4131
} else if (animation->track_get_type (i) == Animation::TYPE_BEZIER) {
4130
- Variant value ;
4132
+ Variant actual_value ;
4131
4133
String track_path = animation->track_get_path (i);
4132
4134
if (track_path == np) {
4133
- value = p_value ; // All good.
4135
+ actual_value = value ; // All good.
4134
4136
} else {
4135
4137
int sep = track_path.rfind (" :" );
4136
4138
if (sep != -1 ) {
4137
4139
String base_path = track_path.substr (0 , sep);
4138
4140
if (base_path == np) {
4139
4141
String value_name = track_path.substr (sep + 1 );
4140
- value = p_value .get (value_name);
4142
+ actual_value = value .get (value_name);
4141
4143
} else {
4142
4144
continue ;
4143
4145
}
@@ -4149,10 +4151,10 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
4149
4151
InsertData id;
4150
4152
id.path = animation->track_get_path (i);
4151
4153
id.track_idx = i;
4152
- id.value = value ;
4154
+ id.value = actual_value ;
4153
4155
id.type = Animation::TYPE_BEZIER;
4154
4156
id.query = vformat (TTR (" property '%s'" ), p_property);
4155
- id.advance = false ;
4157
+ id.advance = p_advance ;
4156
4158
// Dialog insert.
4157
4159
_query_insert (id);
4158
4160
inserted = true ;
@@ -4165,105 +4167,41 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
4165
4167
InsertData id;
4166
4168
id.path = np;
4167
4169
id.track_idx = -1 ;
4168
- id.value = p_value ;
4170
+ id.value = value ;
4169
4171
id.type = Animation::TYPE_VALUE;
4170
4172
id.query = vformat (TTR (" property '%s'" ), p_property);
4171
- id.advance = false ;
4173
+ id.advance = p_advance ;
4172
4174
// Dialog insert.
4173
4175
_query_insert (id);
4174
4176
}
4175
4177
4176
- void AnimationTrackEditor::insert_value_key (const String &p_property, const Variant &p_value, bool p_advance) {
4178
+ void AnimationTrackEditor::insert_value_key (const String &p_property, bool p_advance) {
4177
4179
EditorSelectionHistory *history = EditorNode::get_singleton ()->get_editor_selection_history ();
4178
4180
4179
4181
ERR_FAIL_NULL (root);
4180
4182
ERR_FAIL_COND (history->get_path_size () == 0 );
4181
4183
Object *obj = ObjectDB::get_instance (history->get_path_object (0 ));
4182
- ERR_FAIL_NULL (Object::cast_to<Node>(obj));
4183
-
4184
- // Let's build a node path.
4185
- Node *node = Object::cast_to<Node>(obj);
4186
- String path = root->get_path_to (node, true );
4187
-
4188
- if (Object::cast_to<AnimationPlayer>(node) && p_property == " current_animation" ) {
4189
- if (node == AnimationPlayerEditor::get_singleton ()->get_player ()) {
4190
- EditorNode::get_singleton ()->show_warning (TTR (" AnimationPlayer can't animate itself, only other players." ));
4191
- return ;
4192
- }
4193
- _insert_animation_key (path, p_value);
4194
- return ;
4195
- }
4196
-
4197
- for (int i = 1 ; i < history->get_path_size (); i++) {
4198
- String prop = history->get_path_property (i);
4199
- ERR_FAIL_COND (prop.is_empty ());
4200
- path += " :" + prop;
4201
- }
4202
-
4203
- path += " :" + p_property;
4204
4184
4205
- NodePath np = path;
4185
+ Ref<MultiNodeEdit> multi_node_edit (obj);
4186
+ if (multi_node_edit.is_valid ()) {
4187
+ Node *edited_scene = EditorNode::get_singleton ()->get_edited_scene ();
4188
+ ERR_FAIL_NULL (edited_scene);
4206
4189
4207
- // Locate track.
4208
-
4209
- bool inserted = false ;
4190
+ make_insert_queue ();
4210
4191
4211
- make_insert_queue ();
4212
- for (int i = 0 ; i < animation->get_track_count (); i++) {
4213
- if (animation->track_get_type (i) == Animation::TYPE_VALUE) {
4214
- if (animation->track_get_path (i) != np) {
4215
- continue ;
4216
- }
4217
-
4218
- InsertData id;
4219
- id.path = np;
4220
- id.track_idx = i;
4221
- id.value = p_value;
4222
- id.type = Animation::TYPE_VALUE;
4223
- id.query = vformat (TTR (" property '%s'" ), p_property);
4224
- id.advance = p_advance;
4225
- // Dialog insert.
4226
- _query_insert (id);
4227
- inserted = true ;
4228
- } else if (animation->track_get_type (i) == Animation::TYPE_BEZIER) {
4229
- Variant value;
4230
- if (animation->track_get_path (i) == np) {
4231
- value = p_value; // All good.
4232
- } else {
4233
- String tpath = animation->track_get_path (i);
4234
- int index = tpath.rfind (" :" );
4235
- if (NodePath (tpath.substr (0 , index + 1 )) == np) {
4236
- String subindex = tpath.substr (index + 1 , tpath.length () - index );
4237
- value = p_value.get (subindex);
4238
- } else {
4239
- continue ;
4240
- }
4241
- }
4242
-
4243
- InsertData id;
4244
- id.path = animation->track_get_path (i);
4245
- id.track_idx = i;
4246
- id.value = value;
4247
- id.type = Animation::TYPE_BEZIER;
4248
- id.query = vformat (TTR (" property '%s'" ), p_property);
4249
- id.advance = p_advance;
4250
- // Dialog insert.
4251
- _query_insert (id);
4252
- inserted = true ;
4192
+ for (int i = 0 ; i < multi_node_edit->get_node_count (); ++i) {
4193
+ Node *node = edited_scene->get_node (multi_node_edit->get_node (i));
4194
+ insert_node_value_key (node, p_property, false , p_advance);
4253
4195
}
4254
- }
4255
- commit_insert_queue ();
4256
4196
4257
- if (!inserted) {
4258
- InsertData id;
4259
- id.path = np;
4260
- id.track_idx = -1 ;
4261
- id.value = p_value;
4262
- id.type = Animation::TYPE_VALUE;
4263
- id.query = vformat (TTR (" property '%s'" ), p_property);
4264
- id.advance = p_advance;
4265
- // Dialog insert.
4266
- _query_insert (id);
4197
+ commit_insert_queue ();
4198
+ } else {
4199
+ Node *node = Object::cast_to<Node>(obj);
4200
+ ERR_FAIL_NULL (node);
4201
+
4202
+ make_insert_queue ();
4203
+ insert_node_value_key (node, p_property, false , p_advance);
4204
+ commit_insert_queue ();
4267
4205
}
4268
4206
}
4269
4207
0 commit comments