I'd like to move up and down a certain part of a 2D-enemy-spaceship via DoTween's DOMoveY-shortcut. So far so good - it almost works... but when I try to change the value of the transitionTarget during gameplay the animation doesn't change accordingly.
So the problem seems to be that the code doesn't update the Tweener. Now I'd like to know what do I have to change of my code so that the Tweener gets updated when I change the value (via inspector) of the transitionTarget during gameplay?
This is the code:
public float transitionTarget = 0f;
private Tweener transitionTweener;
private bool toggleTransition = true;
void Start()
{
TransitionTween(transitionTarget);
transitionTweener.OnRewind(() => {
Debug.Log("<<- Transition played backward and completed!");
toggleTransition = true;
});
transitionTweener.OnComplete(() => {
Debug.Log("->> Transition played and completed!");
if (toggleTransition) toggleTransition = false;
else toggleTransition = true;
});
}
void TransitionTween(float targetY) {
transitionTweener = this.transform.DOMoveY(targetY, 3f, false)
.SetEase(Ease.Linear)
.SetAutoKill(false)
.SetId("tran")
.Pause();
}
void Update() {
if (toggleTransition) {
transitionTweener.PlayForward();
}
else {
transitionTweener.PlayBackwards();
}
}
Solution 1: Assuming that it suffices for you to have the updated
transitionTargettake effect at the moment when the animation-cycle starts, there is a simple solution to your problem utilizing theChangeEndValuemethod.Moreover I suggest a simplification: Instead of rewinding the tween manually, I suggest that you use
The same amount of control can be achieved by utilizing the
OnStepCompletedcallback.Solution 2: If you do need the animation to use the updated target value instantly while the animation is still playing, then we need more clarifications. Consider the following cases for the time of the change of the
transitionTargetvalue:transitionTarget.transitionTargetvalue is yet to be reachedtransitionTargetvalue has already been surpassedI will ignore case 2. entirely, because the spaceship will have to return to the start location anyways, and that location which never changes - so in this solution like in the first, the change will only take effect, as soon as the loop is complete when the start location has been reached.
regarding 1., I suppose we can generally assume, that the movement of the spaceship should be continuous, so we will avoid any sort of "teleportation".
Unfortunately the
ChangeEndValuemethod rewinds the tween. So if we want to use this method† for case 1.1, we will have to manually "scrub" the tween to the correct position, which can be achieved with theGotomethod. However, it appears that theGotomethod does not work properly with infinite Loops (which should be reported as issue). The solution will just execute a single loop, still usingLoopType.Yoyo(the number of loops has to be 2 to go forth and back once), and restart the tween afterwards (which is a bit closer to the sample code from the question).In case of 1.2 we just scrub forward to the position in time, where we move back to the start-position, while we are at the same position, which is
2 * duration - transitionTweener.positionso without further ado, the solution:
Note: To comply with your spec, that the tween should update when the
transitionTargetis changed from within the inspector, the solution compareslastValuewithtransitionTargetevery frame in the update method. To avoid this in the real application, you could probably do the following:UpdateTarget, so you trigger it manually.transitionTargetand use the properties setter to invokeUpdateTargetUpdateTargetwhen the tween is completed:transitionTweener.OnComplete(RestartTween);†An alternative option not considered in this Answer would be to recreate the tweens in the event of a change of
transitionTarget.