Skip to content

Commit

Permalink
Merge pull request #32951 from Klowner/tween-follow-null-bug
Browse files Browse the repository at this point in the history
fix Tween follow_property finishing with null
  • Loading branch information
akien-mga authored Oct 25, 2019
2 parents f259beb + d0b528e commit 96f92e5
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 5 deletions.
44 changes: 40 additions & 4 deletions scene/animation/tween.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ void Tween::_bind_methods() {
BIND_ENUM_CONSTANT(EASE_OUT_IN);
}

Variant &Tween::_get_initial_val(InterpolateData &p_data) {
Variant Tween::_get_initial_val(const InterpolateData &p_data) const {

// What type of data are we interpolating?
switch (p_data.type) {
Expand All @@ -299,7 +299,7 @@ Variant &Tween::_get_initial_val(InterpolateData &p_data) {
ERR_FAIL_COND_V(object == NULL, p_data.initial_val);

// Are we targeting a property or a method?
static Variant initial_val;
Variant initial_val;
if (p_data.type == TARGETING_PROPERTY) {
// Get the property from the target object
bool valid = false;
Expand All @@ -322,6 +322,41 @@ Variant &Tween::_get_initial_val(InterpolateData &p_data) {
return p_data.delta_val;
}

Variant Tween::_get_final_val(const InterpolateData &p_data) const {
switch (p_data.type) {
case FOLLOW_PROPERTY:
case FOLLOW_METHOD: {
// Get the object that is being followed
Object *target = ObjectDB::get_instance(p_data.target_id);
ERR_FAIL_COND_V(target == NULL, p_data.initial_val);

// We want to figure out the final value
Variant final_val;
if (p_data.type == FOLLOW_PROPERTY) {
// Read the property as-is
bool valid = false;
final_val = target->get_indexed(p_data.target_key, &valid);
ERR_FAIL_COND_V(!valid, p_data.initial_val);
} else {
// We're looking at a method. Call the method on the target object
Variant::CallError error;
final_val = target->call(p_data.target_key[0], NULL, 0, error);
ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, p_data.initial_val);
}

// If we're looking at an INT value, instead convert it to a REAL
// This is better for interpolation
if (final_val.get_type() == Variant::INT) final_val = final_val.operator real_t();

return final_val;
}
default: {
// If we're not following a final value/method, use the final value from the data
return p_data.final_val;
}
}
}

Variant &Tween::_get_delta_val(InterpolateData &p_data) {

// What kind of data are we interpolating?
Expand Down Expand Up @@ -384,7 +419,7 @@ Variant &Tween::_get_delta_val(InterpolateData &p_data) {

Variant Tween::_run_equation(InterpolateData &p_data) {
// Get the initial and delta values from the data
Variant &initial_val = _get_initial_val(p_data);
Variant initial_val = _get_initial_val(p_data);
Variant &delta_val = _get_delta_val(p_data);
Variant result;

Expand Down Expand Up @@ -718,7 +753,8 @@ void Tween::_tween_process(float p_delta) {
// Is the tween now finished?
if (data.finish) {
// Set it to the final value directly
_apply_tween_value(data, data.final_val);
Variant final_val = _get_final_val(data);
_apply_tween_value(data, final_val);

// Mark the tween as completed and emit the signal
data.elapsed = 0;
Expand Down
3 changes: 2 additions & 1 deletion scene/animation/tween.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ class Tween : public Node {

real_t _run_equation(TransitionType p_trans_type, EaseType p_ease_type, real_t t, real_t b, real_t c, real_t d);
Variant &_get_delta_val(InterpolateData &p_data);
Variant &_get_initial_val(InterpolateData &p_data);
Variant _get_initial_val(const InterpolateData &p_data) const;
Variant _get_final_val(const InterpolateData &p_data) const;
Variant _run_equation(InterpolateData &p_data);
bool _calc_delta_val(const Variant &p_initial_val, const Variant &p_final_val, Variant &p_delta_val);
bool _apply_tween_value(InterpolateData &p_data, Variant &value);
Expand Down

0 comments on commit 96f92e5

Please sign in to comment.