Flat Leon Works

アプリやゲームを作ってます。

【Unity】DOTweenで複数の移動を同時に行う

DOTweenによる移動は加算ではなく代入で行われるため、基本的には複数の移動を同時に行うことができません*1。例えば、Shakeしながら移動させようとすると、Shakeか移動のどちらかが打ち消されてしまい意図した通りには動きません。しかし、やり方を工夫することで複数の移動を同時に行うことができるようになります。

やり方

移動を代入ではなく加算で行うようにします。それにはDO〜系のメソッドではなくTo系のメソッドを利用する必要があります。

float time = 3f;

// 同時移動できない方法( 代入による移動 )
// obj.DOMove( new Vector2( 0, 100 ), time );
// obj.DOShakePosition( time );

// 同時移動できる方法( 加算による移動 )
var lastPos = obj.Pos;
DOTween.To( () => obj.Pos, (Vector3 value) => {Vector2 offset = (Vector2)value - lastPos; obj.Pos += offset; lastPos = value; }, new Vector2( 0, 100 ), time );
DOTween.Shake( () => obj.Pos, (Vector3 value) => {Vector2 offset = (Vector2)value - lastPos; obj.Pos += offset; lastPos = value; }, time );

前回の値を保存しておき、その差分を利用することで加算による移動を実現しています。

もうちょっと便利にする

このままではちょっと面倒なのでメソッド化します。

public static class Util
{
    public static Tweener DOTweenToAdd( Func<Vector2> getFunc, Action<Vector2> addFunc, Vector2 endValue, float time )
    {
        var lastPos = getFunc();
        var ret = DOTween.To( () => getFunc(), (Vector3 value) => {Vector2 offset = (Vector2)value - lastPos; addFunc( offset ); lastPos = value; }, endValue, time );
        return ret;
    }

    public static Tweener DOTweenShakeAdd( Func<Vector2> getFunc, Action<Vector2> addFunc, float time, float strength = 3, int vibrato = 10, float randomness = 90, bool ignoreZAxis = true, bool fadeOut = true )
    {
        var lastPos = getFunc();
        var ret = DOTween.Shake( () => getFunc(), (Vector3 value) => {Vector2 offset = (Vector2)value - lastPos; addFunc( offset ); lastPos = value; }, time, strength, vibrato, randomness, ignoreZAxis, fadeOut );
        return ret;
    }
}

使い方

float time = 3f;

Util.DOTweenToAdd( () => obj.Pos, (value) => obj.Pos += value, new Vector2( 0, 100 ), time );
Util.DOTweenShakeAdd( () => obj.Pos, (value) => obj.Pos += value, time );

ここではTo系に合わせたメソッドにしましたが、Transformなど特定の型を対象にするならDO〜系に合わせたメソッドも用意できると思います。

(おまけ)SetRelative()について

TweenのオプションとしてSetRelativeメソッドがあり、これを使えば相対的な移動=加算による移動になると思ったのですがそうではありませんでした。このSetRelativeを有効にするとEnd値が開始時点からの相対的な位置になるだけで、代入による移動なのは変わりませんでした。

*1:移動と回転など別のパラメータに対するTweenは同時に行うことができますが。