3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Unity】DoTween の Tween や Sequence をほぼ途中から再生できる拡張メソッド

Last updated at Posted at 2023-01-30

概要

DoTween を途中から再生する方法が見つからなかったので作ってみました。
具体的には、Tween や Sequence を n 秒スキップする拡張メソッドを作り、それを利用して途中から再生できる拡張メソッドを作りました。

gif.gif
上の gif は、10秒で反時計回りに一周する sequence を用意して Cube に適応し、Button を押すと 2.5 秒スキップするようにしたものです。

実装方法は、次のフレームで目的の再生位置になるように timeScale を調整し、次のフレームで timeScale を元に戻すというものです。
Skip() にマイナスの値を入れた場合は、n 秒前の再生時間になるよう Restart() と Skip() を実行します 。

途中から再生する正式な方法や改良案などがありましたら、コメントをお願いします。

注意事項

スキップ前後のTime.deltaTimeがほぼ同じという前提で実装しているので、FPSが不安定なほど目的の再生位置からズレます。
1フレーム進める必要があるので、停止中の Tween/Sequence でも1フレームだけ再生します。

コード

お手持ちの DoTweenEx クラスに追加してご利用ください。

DoTweenEx.cs
using DG.Tweening;
using UnityEngine;

namespace Extensions
{
    public static class DoTweenEx
    {
        /// <summary>
        /// [Caution] The more unstable the FPS, the more back and forth from the specified time.
        /// Since it is necessary to play 1 frame, let it play for 1 frame even if it is paused.
        /// </summary>
        public static Tween Skip(this Tween tween, float second, bool ignoreTimeScale = true)
        {
            if (second == 0f) return tween;
            var isPlayed = tween.IsPlaying();
            if (second < 0f)
            {
                var elapsedSecond = tween.Elapsed(true);
                second = elapsedSecond + second;
                tween.Restart();
                if (second <= 0f)
                {
                    if (!isPlayed) tween.Pause();
                    return tween;
                }
            }
            var timeScale = tween.timeScale;
            tween.timeScale = (second + (isPlayed ? Time.deltaTime : 0f)) / Time.deltaTime / (ignoreTimeScale ? 1f : timeScale);

            if (!isPlayed) tween.Play();

            DOVirtual.DelayedCall(float.Epsilon, () =>
            {
                if (tween == null) return;
                tween.timeScale = timeScale;
                if (!isPlayed) tween.Pause();
            });
            return tween;
        }
        /// <summary>
        /// [Caution] The more unstable the FPS, the more back and forth from the specified time.
        /// Since it is necessary to play 1 frame, let it play for 1 frame even if it is paused.
        /// </summary>
        public static Sequence Skip(this Sequence sequence, float second, bool ignoreTimeScale = true)
        {
            if (second == 0f) return sequence;
            var isPlayed = sequence.IsPlaying();
            if (second < 0f)
            {
                var elapsedSecond = sequence.Elapsed(true);
                second = elapsedSecond + second;
                sequence.Restart();
                if (second <= 0f)
                {
                    if (!isPlayed) sequence.Pause();
                    return sequence;
                }
            }

            var timeScale = sequence.timeScale;
            sequence.timeScale = (second + (isPlayed ? Time.deltaTime : 0f)) / Time.deltaTime / (ignoreTimeScale ? 1f : timeScale);
            
            if (!isPlayed) sequence.Play();

            DOVirtual.DelayedCall(float.Epsilon, () =>
            {
                if (sequence == null) return;
                sequence.timeScale = timeScale;
                if (!isPlayed) sequence.Pause();
            });
            return sequence;
        }
        public static Tween Restart(this Tween tween, float skipSecond, bool ignoreTimeScale = true)
        {
            tween.Restart();
            return tween.Skip(skipSecond, ignoreTimeScale);
        }
        public static Sequence Restart(this Sequence tween, float skipSecond, bool ignoreTimeScale = true)
        {
            tween.Restart();
            return tween.Skip(skipSecond, ignoreTimeScale);
        }
    }
}
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?