// Instead of advancing the tween from the previous position each time, // uses the given position to calculate running time since startup, and places the tween there like a Goto. // Executes regardless of whether the tween is playing. // Returns TRUE if the tween needs to be killed internal static bool DoGoto(Tween t, float toPosition, int toCompletedLoops, UpdateMode updateMode) { // Startup if (!t.startupDone) { if (!t.Startup()) { return(true); } } // OnStart and first OnPlay callbacks if (!t.playedOnce && updateMode == UpdateMode.Update) { t.playedOnce = true; if (t.onStart != null) { t.onStart(); if (!t.active) { return(true); // Tween might have been killed by onStart callback } } if (t.onPlay != null) { t.onPlay(); if (!t.active) { return(true); // Tween might have been killed by onPlay callback } } } float prevPosition = t.position; int prevCompletedLoops = t.completedLoops; t.completedLoops = toCompletedLoops; bool wasRewinded = t.position <= 0 && prevCompletedLoops <= 0; bool wasComplete = t.isComplete; // Determine if it will be complete after update if (t.loops != -1) { t.isComplete = t.completedLoops == t.loops; } // Calculate newCompletedSteps (always useful with Sequences) int newCompletedSteps = 0; if (updateMode == UpdateMode.Update) { if (t.isBackwards) { newCompletedSteps = t.completedLoops < prevCompletedLoops ? prevCompletedLoops - t.completedLoops : (toPosition <= 0 && !wasRewinded ? 1 : 0); if (wasComplete) { newCompletedSteps--; } } else { newCompletedSteps = t.completedLoops > prevCompletedLoops ? t.completedLoops - prevCompletedLoops : 0; } } else if (t.tweenType == TweenType.Sequence) { newCompletedSteps = prevCompletedLoops - toCompletedLoops; if (newCompletedSteps < 0) { newCompletedSteps = -newCompletedSteps; } } // Set position (makes position 0 equal to position "end" when looping) t.position = toPosition; if (t.position > t.duration) { t.position = t.duration; } else if (t.position <= 0) { if (t.completedLoops > 0 || t.isComplete) { t.position = t.duration; } else { t.position = 0; } } // Set playing state after update bool wasPlaying = t.isPlaying; if (t.isPlaying) { if (!t.isBackwards) { t.isPlaying = !t.isComplete; // Reached the end } else { t.isPlaying = !(t.completedLoops == 0 && t.position <= 0); // Rewinded } } // updatePosition is different in case of Yoyo loop under certain circumstances bool useInversePosition = t.loopType == LoopType.Yoyo && (t.position < t.duration ? t.completedLoops % 2 != 0 : t.completedLoops % 2 == 0); // Get values from plugin and set them if (t.ApplyTween(prevPosition, prevCompletedLoops, newCompletedSteps, useInversePosition, updateMode)) { return(true); } // Additional callbacks if (t.onUpdate != null) { t.onUpdate(); } if (t.position <= 0 && t.completedLoops <= 0 && !wasRewinded) { if (t.onRewind != null) { t.onRewind(); } } if (newCompletedSteps > 0 && updateMode == UpdateMode.Update && t.onStepComplete != null) { for (int i = 0; i < newCompletedSteps; ++i) { t.onStepComplete(); } } if (t.isComplete && !wasComplete) { if (t.onComplete != null) { t.onComplete(); } } if (!t.isPlaying && wasPlaying && (!t.isComplete || !t.autoKill)) { if (t.onPause != null) { t.onPause(); } } // Return return(t.autoKill && t.isComplete); }