浏览代码

-Added trigger mode to tracks, useful for properties that work as triggers, such as playing a sample, an animation, etc.
-Better interpolation of discrete tracks, fixes #4417

Juan Linietsky 9 年之前
父节点
当前提交
7c20c386c5

+ 1 - 0
core/object.h

@@ -88,6 +88,7 @@ enum PropertyUsageFlags {
 	PROPERTY_USAGE_RESTART_IF_CHANGED=4096,
 	PROPERTY_USAGE_SCRIPT_VARIABLE=8192,
 	PROPERTY_USAGE_STORE_IF_NULL=16384,
+	PROPERTY_USAGE_ANIMATE_AS_TRIGGER=32768,
 
 	PROPERTY_USAGE_DEFAULT=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK,
 	PROPERTY_USAGE_DEFAULT_INTL=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK|PROPERTY_USAGE_INTERNATIONALIZED,

+ 1 - 1
scene/2d/sample_player_2d.cpp

@@ -81,7 +81,7 @@ void SamplePlayer2D::_get_property_list(List<PropertyInfo> *p_list) const {
 		}
 	}
 
-	p_list->push_back( PropertyInfo( Variant::STRING, "play/play", PROPERTY_HINT_ENUM, en,PROPERTY_USAGE_EDITOR));
+	p_list->push_back( PropertyInfo( Variant::STRING, "play/play", PROPERTY_HINT_ENUM, en,PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_ANIMATE_AS_TRIGGER));
 }
 
 void SamplePlayer2D::_notification(int p_what) {

+ 1 - 1
scene/3d/spatial_sample_player.cpp

@@ -82,7 +82,7 @@ void SpatialSamplePlayer::_get_property_list(List<PropertyInfo> *p_list) const {
 		}
 	}
 
-	p_list->push_back( PropertyInfo( Variant::STRING, "play/play", PROPERTY_HINT_ENUM, en,PROPERTY_USAGE_EDITOR));
+	p_list->push_back( PropertyInfo( Variant::STRING, "play/play", PROPERTY_HINT_ENUM, en,PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_ANIMATE_AS_TRIGGER));
 
 }
 void SpatialSamplePlayer::_notification(int p_what) {

+ 1 - 1
scene/animation/animation_cache.cpp

@@ -301,7 +301,7 @@ void AnimationCache::set_all(float p_time, float p_delta) {
 			} break;
 			case Animation::TYPE_VALUE: {
 
-				if (animation->value_track_is_continuous(i)) {
+				if (animation->value_track_get_update_mode(i)==Animation::UPDATE_CONTINUOUS || (animation->value_track_get_update_mode(i)==Animation::UPDATE_DISCRETE && p_delta==0)) {
 					Variant v = animation->value_track_interpolate(i,p_time);
 					set_track_value(i,v);
 				} else {

+ 7 - 5
scene/animation/animation_player.cpp

@@ -174,7 +174,7 @@ void AnimationPlayer::_get_property_list( List<PropertyInfo> *p_list) const {
 			hint+=E->get();
 		}
 
-		p_list->push_back( PropertyInfo( Variant::STRING, "playback/play", PROPERTY_HINT_ENUM, hint,PROPERTY_USAGE_EDITOR) );
+		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") );
 
@@ -421,12 +421,13 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
 				TrackNodeCache::PropertyAnim *pa = &E->get();
 
 
-				if (a->value_track_is_continuous(i) || p_delta==0) { //delta == 0 means seek
+				if (a->value_track_get_update_mode(i)==Animation::UPDATE_CONTINUOUS || (p_delta==0 && a->value_track_get_update_mode(i)==Animation::UPDATE_DISCRETE)) { //delta == 0 means seek
 
 
 					Variant value=a->value_track_interpolate(i,p_time);
-					if (p_delta==0 && value.get_type()==Variant::STRING)
-						continue; // doing this with strings is messy, should find another way
+					//thanks to trigger mode, this should be solved now..
+					//if (p_delta==0 && value.get_type()==Variant::STRING)
+					//	continue; // doing this with strings is messy, should find another way
 					if (pa->accum_pass!=accum_pass) {
 						ERR_CONTINUE( cache_update_prop_size >= NODE_CACHE_UPDATE_MAX );
 						cache_update_prop[cache_update_prop_size++]=pa;
@@ -437,11 +438,12 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
 					}
 
 
-				} else if (p_allow_discrete) {
+				} else if (p_allow_discrete && p_delta!=0) {
 
 					List<int> indices;
 					a->value_track_get_key_indices(i,p_time,p_delta,&indices);
 
+
 					for(List<int>::Element *F=indices.front();F;F=F->next()) {
 
 						Variant value=a->track_get_key_value(i,F->get());

+ 1 - 1
scene/animation/animation_tree_player.cpp

@@ -825,7 +825,7 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
 					} break;
 					case Animation::TYPE_VALUE: { ///< Set a value in a property, can be interpolated.
 
-						if (a->value_track_is_continuous(tr.local_track)) {
+						if (a->value_track_get_update_mode(tr.local_track)==Animation::UPDATE_CONTINUOUS) {
 							Variant value = a->value_track_interpolate(tr.local_track,anim_list->time);
 							Variant::blend(tr.track->value,value,blend,tr.track->value);
 						} else {

+ 1 - 1
scene/audio/sample_player.cpp

@@ -152,7 +152,7 @@ void SamplePlayer::_get_property_list(List<PropertyInfo> *p_list) const {
 		}
 	}
 
-	p_list->push_back( PropertyInfo( Variant::STRING, "play/play", PROPERTY_HINT_ENUM, en,PROPERTY_USAGE_EDITOR));
+	p_list->push_back( PropertyInfo( Variant::STRING, "play/play", PROPERTY_HINT_ENUM, en,PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_ANIMATE_AS_TRIGGER));
 	p_list->push_back( PropertyInfo( Variant::INT, "config/polyphony", PROPERTY_HINT_RANGE, "1,256,1"));
 	p_list->push_back( PropertyInfo( Variant::OBJECT, "config/samples", PROPERTY_HINT_RESOURCE_TYPE, "SampleLibrary"));
 	p_list->push_back( PropertyInfo( Variant::REAL, "default/volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01"));

+ 32 - 13
scene/resources/animation.cpp

@@ -154,8 +154,20 @@ bool Animation::_set(const StringName& p_name, const Variant& p_value) {
 				Dictionary d = p_value;
 				ERR_FAIL_COND_V(!d.has("times"),false);
 				ERR_FAIL_COND_V(!d.has("values"),false);
-				if (d.has("cont"))
-					vt->continuous=d["cont"];
+				if (d.has("cont")) {
+					bool v = d["cont"];
+					vt->update_mode=v?UPDATE_CONTINUOUS:UPDATE_DISCRETE;
+				}
+
+				if (d.has("update")) {
+					int um =d["update"];
+					if (um<0)
+						um=0;
+					else if (um>2)
+						um=2;
+					vt->update_mode=UpdateMode(um);
+				}
+
 
 				DVector<float> times=d["times"];
 				Array values=d["values"];
@@ -353,7 +365,7 @@ bool Animation::_get(const StringName& p_name,Variant &r_ret) const {
 				d["transitions"]=key_transitions;
 				d["values"]=key_values;
 				if (track_get_type(track)==TYPE_VALUE) {
-					d["cont"]=value_track_is_continuous(track);
+					d["update"]=value_track_get_update_mode(track);
 				}
 
 				r_ret=d;
@@ -394,7 +406,7 @@ bool Animation::_get(const StringName& p_name,Variant &r_ret) const {
 				d["transitions"]=key_transitions;
 				d["values"]=key_values;
 				if (track_get_type(track)==TYPE_VALUE) {
-					d["cont"]=value_track_is_continuous(track);
+					d["update"]=value_track_get_update_mode(track);
 				}
 
 				r_ret=d;
@@ -1373,7 +1385,7 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const {
 	bool ok;
 
 
-	Variant res = _interpolate( vt->values, p_time, vt->interpolation, &ok );
+	Variant res = _interpolate( vt->values, p_time, vt->update_mode==UPDATE_CONTINUOUS?vt->interpolation:INTERPOLATION_NEAREST, &ok );
 
 
 	if (ok) {
@@ -1461,28 +1473,30 @@ void Animation::value_track_get_key_indices(int p_track, float p_time, float p_d
 
 }
 
-void Animation::value_track_set_continuous(int p_track, bool p_continuous) {
+void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) {
 
 	ERR_FAIL_INDEX(p_track, tracks.size());
 	Track *t=tracks[p_track];
 	ERR_FAIL_COND( t->type != TYPE_VALUE );
+	ERR_FAIL_INDEX(p_mode,3);
 
 	ValueTrack * vt = static_cast<ValueTrack*>(t);
-	vt->continuous=p_continuous;
+	vt->update_mode=p_mode;
 
 }
 
-bool Animation::value_track_is_continuous(int p_track) const{
+Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const {
 
-	ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
+	ERR_FAIL_INDEX_V(p_track, tracks.size(), UPDATE_CONTINUOUS);
 	Track *t=tracks[p_track];
-	ERR_FAIL_COND_V( t->type != TYPE_VALUE, false );
+	ERR_FAIL_COND_V( t->type != TYPE_VALUE, UPDATE_CONTINUOUS );
 
 	ValueTrack * vt = static_cast<ValueTrack*>(t);
-	return vt->continuous;
+	return vt->update_mode;
 
 }
 
+
 void Animation::_method_track_get_key_indices_in_range(const MethodTrack * mt, float from_time, float to_time,List<int> *p_indices) const {
 
 	if (from_time!=length && to_time==length)
@@ -1676,8 +1690,8 @@ void Animation::_bind_methods() {
 
 
 	ObjectTypeDB::bind_method(_MD("transform_track_interpolate","idx","time_sec"),&Animation::_transform_track_interpolate);
-	ObjectTypeDB::bind_method(_MD("value_track_set_continuous","idx","continuous"),&Animation::value_track_set_continuous);
-	ObjectTypeDB::bind_method(_MD("value_track_is_continuous","idx"),&Animation::value_track_is_continuous);
+	ObjectTypeDB::bind_method(_MD("value_track_set_update_mode","idx","mode"),&Animation::value_track_set_update_mode);
+	ObjectTypeDB::bind_method(_MD("value_track_get_update_mode","idx"),&Animation::value_track_get_update_mode);
 
 	ObjectTypeDB::bind_method(_MD("value_track_get_key_indices","idx","time_sec","delta"),&Animation::_value_track_get_key_indices);
 
@@ -1704,6 +1718,11 @@ void Animation::_bind_methods() {
 	BIND_CONSTANT( INTERPOLATION_LINEAR );
 	BIND_CONSTANT( INTERPOLATION_CUBIC );
 
+	BIND_CONSTANT( UPDATE_CONTINUOUS );
+	BIND_CONSTANT( UPDATE_DISCRETE );
+	BIND_CONSTANT( UPDATE_TRIGGER );
+
+
 }
 
 void Animation::clear() {

+ 16 - 4
scene/resources/animation.h

@@ -58,6 +58,13 @@ public:
 		INTERPOLATION_CUBIC
 	};
 
+	enum UpdateMode {
+		UPDATE_CONTINUOUS,
+		UPDATE_DISCRETE,
+		UPDATE_TRIGGER,
+
+	};
+
 private:
 
 	struct Track {
@@ -105,10 +112,11 @@ private:
 
 	struct ValueTrack : public Track {
 
-		bool continuous;
+		UpdateMode update_mode;
+		bool update_on_seek;
 		Vector< TKey<Variant> > values;
 
-		ValueTrack() { type=TYPE_VALUE; continuous=true; }
+		ValueTrack() { type=TYPE_VALUE; update_mode=UPDATE_CONTINUOUS; }
 	};
 
 
@@ -253,8 +261,9 @@ public:
 
 	Variant value_track_interpolate(int p_track, float p_time) const;
 	void value_track_get_key_indices(int p_track, float p_time, float p_delta,List<int> *p_indices) const;
-	void value_track_set_continuous(int p_track, bool p_continuous);
-	bool value_track_is_continuous(int p_track) const;
+	void value_track_set_update_mode(int p_track, UpdateMode p_mode);
+	UpdateMode value_track_get_update_mode(int p_track) const;
+
 
 	void method_track_get_key_indices(int p_track, float p_time, float p_delta,List<int> *p_indices) const;
 	Vector<Variant> method_track_get_params(int p_track,int p_key_idx) const;
@@ -281,5 +290,8 @@ public:
 
 VARIANT_ENUM_CAST( Animation::TrackType );
 VARIANT_ENUM_CAST( Animation::InterpolationType );
+VARIANT_ENUM_CAST( Animation::UpdateMode );
+
+
 
 #endif

+ 31 - 23
tools/editor/animation_editor.cpp

@@ -754,7 +754,7 @@ void AnimationKeyEditor::_menu_track(int p_type) {
 
 				undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",idx,animation->track_get_interpolation_type(idx));
 				if (animation->track_get_type(idx)==Animation::TYPE_VALUE) {
-					undo_redo->add_undo_method(animation.ptr(),"value_track_set_continuous",idx,animation->value_track_is_continuous(idx));
+					undo_redo->add_undo_method(animation.ptr(),"value_track_set_update_mode",idx,animation->value_track_get_update_mode(idx));
 
 				}
 
@@ -918,7 +918,7 @@ void AnimationKeyEditor::_menu_track(int p_type) {
 				pos=animation->get_length();
 			timeline_pos=pos;
 			track_pos->update();
-			emit_signal("timeline_changed",pos);
+			emit_signal("timeline_changed",pos,true);
 
 		} break;
 		case TRACK_MENU_PREV_STEP: {
@@ -934,7 +934,7 @@ void AnimationKeyEditor::_menu_track(int p_type) {
 				pos=0;
 			timeline_pos=pos;
 			track_pos->update();
-			emit_signal("timeline_changed",pos);
+			emit_signal("timeline_changed",pos,true);
 
 
 		} break;
@@ -1169,8 +1169,9 @@ void AnimationKeyEditor::_track_editor_draw() {
 		get_icon("InterpCubic","EditorIcons")
 	};
 	Ref<Texture> cont_icon[3]={
+		get_icon("TrackContinuous","EditorIcons"),
 		get_icon("TrackDiscrete","EditorIcons"),
-		get_icon("TrackContinuous","EditorIcons")
+		get_icon("TrackTrigger","EditorIcons")
 	};
 	Ref<Texture> type_icon[3]={
 		get_icon("KeyValue","EditorIcons"),
@@ -1442,15 +1443,15 @@ void AnimationKeyEditor::_track_editor_draw() {
 		if (animation->track_get_type(idx)==Animation::TYPE_VALUE) {
 
 
-			int continuous = animation->value_track_is_continuous(idx)?1:0;
+			int umode = animation->value_track_get_update_mode(idx);
 
 			icon_ofs.x-=hsep;
 			icon_ofs.x-=down_icon->get_width();
 			te->draw_texture(down_icon,icon_ofs);
 
 			icon_ofs.x-=hsep;
-			icon_ofs.x-=cont_icon[continuous]->get_width();
-			te->draw_texture(cont_icon[continuous],icon_ofs);
+			icon_ofs.x-=cont_icon[umode]->get_width();
+			te->draw_texture(cont_icon[umode],icon_ofs);
 		} else {
 
 			icon_ofs.x -= hsep*2 + cont_icon[0]->get_width() + down_icon->get_width();
@@ -1626,8 +1627,8 @@ void AnimationKeyEditor::_track_menu_selected(int p_idx) {
 		ERR_FAIL_INDEX(cont_editing,animation->get_track_count());
 
 		undo_redo->create_action(TTR("Anim Track Change Value Mode"));
-		undo_redo->add_do_method(animation.ptr(),"value_track_set_continuous",cont_editing,p_idx);
-		undo_redo->add_undo_method(animation.ptr(),"value_track_set_continuous",cont_editing,animation->value_track_is_continuous(cont_editing));
+		undo_redo->add_do_method(animation.ptr(),"value_track_set_update_mode",cont_editing,p_idx);
+		undo_redo->add_undo_method(animation.ptr(),"value_track_set_update_mode",cont_editing,animation->value_track_get_update_mode(cont_editing));
 		undo_redo->commit_action();
 	}
 
@@ -1820,8 +1821,9 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
 		get_icon("InterpCubic","EditorIcons")
 	};
 	Ref<Texture> cont_icon[3]={
+		get_icon("TrackContinuous","EditorIcons"),
 		get_icon("TrackDiscrete","EditorIcons"),
-		get_icon("TrackContinuous","EditorIcons")
+		get_icon("TrackTrigger","EditorIcons")
 	};
 	Ref<Texture> type_icon[3]={
 		get_icon("KeyValue","EditorIcons"),
@@ -1972,7 +1974,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
 							click.click=ClickOver::CLICK_DRAG_TIMELINE;
 							click.at=Point2(mb.x,mb.y);
 							click.to=click.at;
-							emit_signal("timeline_changed",pos);
+							emit_signal("timeline_changed",pos,false);
 
 						}
 
@@ -2184,8 +2186,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
 
 							track_menu->clear();
 							track_menu->set_size(Point2(1,1));
-							static const char *cont_name[3]={"Discrete","Continuous"};
-							for(int i=0;i<2;i++) {
+							String cont_name[3]={TTR("Continuous"),TTR("Discrete"),TTR("Trigger")};
+							for(int i=0;i<3;i++) {
 								track_menu->add_icon_item(cont_icon[i],cont_name[i]);
 							}
 
@@ -2594,7 +2596,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
 						}
 
 						timeline_pos=pos;
-						emit_signal("timeline_changed",pos);
+						emit_signal("timeline_changed",pos,true);
 
 
 
@@ -2940,8 +2942,9 @@ void AnimationKeyEditor::_notification(int p_what) {
 						get_icon("InterpCubic","EditorIcons")
 					};
 					Ref<Texture> cont_icon[3]={
+						get_icon("TrackContinuous","EditorIcons"),
 						get_icon("TrackDiscrete","EditorIcons"),
-						get_icon("TrackContinuous","EditorIcons")
+						get_icon("TrackTrigger","EditorIcons")
 					};
 
 					//right_data_size_cache = remove_icon->get_width() + move_up_icon->get_width() + move_down_icon->get_width() + down_icon->get_width() *2 + interp_icon[0]->get_width() + cont_icon[0]->get_width() + add_key_icon->get_width() + hsep*11;
@@ -3311,7 +3314,7 @@ int AnimationKeyEditor::_confirm_insert(InsertData p_id,int p_last_track) {
 
 		created=true;
 		undo_redo->create_action(TTR("Anim Insert Track & Key"));
-		bool continuous=false;
+		Animation::UpdateMode update_mode=Animation::UPDATE_DISCRETE;
 
 		if (p_id.type==Animation::TYPE_VALUE) {
 			//wants a new tack
@@ -3324,16 +3327,21 @@ int AnimationKeyEditor::_confirm_insert(InsertData p_id,int p_last_track) {
 				PropertyInfo h = _find_hint_for_track(animation->get_track_count()-1,np);
 				animation->remove_track(animation->get_track_count()-1); //hack
 
-
-				continuous =
-					h.type==Variant::REAL ||
+				if  (	h.type==Variant::REAL ||
 					h.type==Variant::VECTOR2 ||
 					h.type==Variant::RECT2 ||
 					h.type==Variant::VECTOR3 ||
 					h.type==Variant::_AABB ||
 					h.type==Variant::QUAT ||
 					h.type==Variant::COLOR ||
-					h.type==Variant::TRANSFORM ;
+					h.type==Variant::TRANSFORM ) {
+
+					update_mode=Animation::UPDATE_CONTINUOUS;
+				}
+
+				if (h.usage&PROPERTY_USAGE_ANIMATE_AS_TRIGGER) {
+					update_mode=Animation::UPDATE_TRIGGER;
+				}
 			}
 		}
 
@@ -3342,7 +3350,7 @@ int AnimationKeyEditor::_confirm_insert(InsertData p_id,int p_last_track) {
 		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);
 		if (p_id.type==Animation::TYPE_VALUE)
-			undo_redo->add_do_method(animation.ptr(),"value_track_set_continuous",p_id.track_idx,continuous);
+			undo_redo->add_do_method(animation.ptr(),"value_track_set_update_mode",p_id.track_idx,update_mode);
 
 	} else {
 		undo_redo->create_action(TTR("Anim Insert Key"));
@@ -3536,7 +3544,7 @@ void AnimationKeyEditor::_insert_delay() {
 			pos=animation->get_length();
 		timeline_pos=pos;
 		track_pos->update();
-		emit_signal("timeline_changed",pos);
+		emit_signal("timeline_changed",pos,true);
 	}
 	insert_queue=false;
 }
@@ -3759,7 +3767,7 @@ void AnimationKeyEditor::_bind_methods() {
 
 	ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) );
 	ADD_SIGNAL( MethodInfo("keying_changed" ) );
-	ADD_SIGNAL( MethodInfo("timeline_changed", PropertyInfo(Variant::REAL,"pos") ) );
+	ADD_SIGNAL( MethodInfo("timeline_changed", PropertyInfo(Variant::REAL,"pos"), PropertyInfo(Variant::BOOL,"drag") ) );
 	ADD_SIGNAL( MethodInfo("animation_len_changed", PropertyInfo(Variant::REAL,"len") ) );
 	ADD_SIGNAL( MethodInfo("animation_step_changed", PropertyInfo(Variant::REAL,"step") ) );
 	ADD_SIGNAL( MethodInfo("key_edited", PropertyInfo(Variant::INT,"track"), PropertyInfo(Variant::INT,"key") ) );

+ 11 - 5
tools/editor/plugins/animation_player_editor_plugin.cpp

@@ -952,7 +952,7 @@ void AnimationPlayerEditor::_animation_duplicate() {
 
 }
 
-void AnimationPlayerEditor::_seek_value_changed(float p_value) {
+void AnimationPlayerEditor::_seek_value_changed(float p_value,bool p_set) {
 
 	if (updating || !player || player->is_playing()) {
 		return;
@@ -980,7 +980,7 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value) {
 			pos=anim->get_length();
 	}
 
-	if (player->is_valid()) {
+	if (player->is_valid() && !p_set) {
 		float cpos = player->get_current_animation_pos();
 
 		player->seek_delta(pos,pos-cpos);
@@ -988,6 +988,7 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value) {
 		player->seek(pos,true);
 	}
 
+
 	key_editor->set_anim_pos(pos);
 
 	updating=true;
@@ -1078,6 +1079,7 @@ void AnimationPlayerEditor::_editor_load(){
 
 void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len) {
 
+
 	frame->set_max(p_len);
 
 }
@@ -1092,7 +1094,7 @@ void AnimationPlayerEditor::_animation_key_editor_anim_step_changed(float p_len)
 }
 
 
-void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos) {
+void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos,bool p_drag) {
 
 	if (!is_visible())
 		return;
@@ -1102,7 +1104,11 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos) {
 	if (player->is_playing()	)
 		return;
 
-	frame->set_val(p_pos);
+	updating=true;
+	frame->set_val(p_pos);	
+	updating=false;
+	_seek_value_changed(p_pos,!p_drag);
+
 	EditorNode::get_singleton()->get_property_editor()->refresh();
 
 
@@ -1254,7 +1260,7 @@ void AnimationPlayerEditor::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_animation_edit"),&AnimationPlayerEditor::_animation_edit);
 	ObjectTypeDB::bind_method(_MD("_animation_resource_edit"),&AnimationPlayerEditor::_animation_resource_edit);
 	ObjectTypeDB::bind_method(_MD("_dialog_action"),&AnimationPlayerEditor::_dialog_action);
-	ObjectTypeDB::bind_method(_MD("_seek_value_changed"),&AnimationPlayerEditor::_seek_value_changed);
+	ObjectTypeDB::bind_method(_MD("_seek_value_changed"),&AnimationPlayerEditor::_seek_value_changed,DEFVAL(true));
 	ObjectTypeDB::bind_method(_MD("_animation_player_changed"),&AnimationPlayerEditor::_animation_player_changed);
 	ObjectTypeDB::bind_method(_MD("_blend_edited"),&AnimationPlayerEditor::_blend_edited);
 //	ObjectTypeDB::bind_method(_MD("_seek_frame_changed"),&AnimationPlayerEditor::_seek_frame_changed);

+ 2 - 2
tools/editor/plugins/animation_player_editor_plugin.h

@@ -145,7 +145,7 @@ class AnimationPlayerEditor : public VBoxContainer {
 	void _scale_changed(const String& p_scale);
 	void _dialog_action(String p_file);
 	void _seek_frame_changed(const String& p_frame);
-	void _seek_value_changed(float p_value);
+	void _seek_value_changed(float p_value, bool p_set=false);
 	void _blend_editor_next_changed(const int p_idx);
 
 	void _list_changed();
@@ -158,7 +158,7 @@ class AnimationPlayerEditor : public VBoxContainer {
 
 	void _animation_player_changed(Object *p_pl);
 
-	void _animation_key_editor_seek(float p_pos);
+	void _animation_key_editor_seek(float p_pos, bool p_drag);
 	void _animation_key_editor_anim_len_changed(float p_new);
 	void _animation_key_editor_anim_step_changed(float p_len);