渋谷ほととぎす通信

Unity・ゲーム開発 技術で一生食べていく情報発信

Unity DOTweenのガベコレ頻度を下げる方法

f:id:esakun:20150825162207p:plain

DOTweenのメソッドを洗っていると気になるものが目につきました。

SetRecyclableメソッド

いかにも内部でTweenerインスタンスをPoolし、
再利用することでガベージコレクションの発生率を下げてくれるのではと。

あわよくばパフォーマンスも上がるかもしれないと。

こちらのコードとUnityのProfilerでにらめっこしながら検証しました。

環境

  • DOTween 1.1.310

検証サンプル

f:id:esakun:20161008220824g:plain

強制的にガベージコレクションを発生させるため、
大量のオブジェクトを生成しTweenさせています。

結果

ガベージコレクションの頻度が下がりました。

SetRecyclable未使用 Ver.

f:id:esakun:20161008221009p:plain

SetRecyclable使用 Ver.

f:id:esakun:20161008221024p:plain

DOTweenのソースを確認する

ではどのように処理しているのかソースコードを見ていきます。

TweenManagerの217行目

Tweenが終了したタイミングで isRecyclable フラグがtrueのものは
_pooledTweeners 配列に格納されています。

if (_maxPooledTweenerId < maxTweeners - 1) {
    _pooledTweeners[_maxPooledTweenerId + 1] = t;
    _maxPooledTweenerId++;
    if (_minPooledTweenerId > _maxPooledTweenerId) _minPooledTweenerId = _maxPooledTweenerId;
} else {
    for (int i = _maxPooledTweenerId; i > -1; --i) {
        if (_pooledTweeners[i] != null) continue;
        _pooledTweeners[i] = t;
        if (i < _minPooledTweenerId) _minPooledTweenerId = i;
        if (_maxPooledTweenerId < _minPooledTweenerId) _maxPooledTweenerId = _minPooledTweenerId;
        break;
    }
}

TweenManagerの64行目

Tweenerを取り出す部分で_pooledTweeners
存在していたらPoolされたものを使用しています。

for (int i = _maxPooledTweenerId; i > _minPooledTweenerId - 1; --i) {
    Tween tween = _pooledTweeners[i];
    if (tween != null && tween.typeofT1 == typeofT1 && tween.typeofT2 == typeofT2 && tween.typeofTPlugOptions == typeofTPlugOptions) {
        // Pooled Tweener exists: spawn it
        t = (TweenerCore<T1, T2, TPlugOptions>)tween;
        AddActiveTween(t);
        _pooledTweeners[i] = null;
        if (_maxPooledTweenerId != _minPooledTweenerId) {
            if (i == _maxPooledTweenerId) _maxPooledTweenerId--;
            else if (i == _minPooledTweenerId) _minPooledTweenerId++;
        }
        totPooledTweeners--;
        return t;
    }
}

このようにインスタンスを生成しない分、
ガベージコレクションを下げているのが分かります。

まとめ

大量のオブジェクトを何度もTweenさせる場合であれば、
ガベージコレクションによるスパイク頻度を
軽減させる方法 としては良い気がします。

検証コード

あわせてどうぞ