17
8

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 3 years have passed since last update.

【Unity】DOTweenでたまに見るあの警告への対処方法

Last updated at Posted at 2020-01-30

はじめに

Unityでトゥイーンと言えば、アセットDOTweenが有名です。
Free版でも十分な機能を備えている上に大変使いやすく、個人的にはもはや外せないくらいです。

さて、DOTweenを使って開発しているとたまに出くわす警告(もしくはエラー)があります。
毎回対処するのですが、しばらくするとやり方を忘れてしまうのでメモがてら共有します。
ちなみに警告の状態であれば多分放置してても特に実害はないです。なんか気持ち悪いので消したいという人へ。

警告(エラー)内容

警告の場合

エディタ再生を終了したタイミングで下記の警告が出ます。

dotween_warning.png

DOTWEEN ▶  SAFE MODE ▶ DOTween's safe mode captured [エラー数] errors. This is usually ok (it's what safe mode is there for) but if your game is encountering issues you should set Log Behaviour to Default in DOTween Utility Panel in order to get detailed warnings when an error is captured (consider that these errors are always on the user side).

エラーの場合

Utility Panelで「Safe Mode」のチェックを外していると、エディタ再生中に警告ではなくエラーが出ます。

dotween_error.png

MissingReferenceException: The object of type '[なんかのコンポーネント]' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.

dotween_utility.png

発生する状況

例えば、こんな感じのスクリプトがあったとします。
RectTransformをちょっと動かすだけの単純なコードです。

DotweenTest.cs
using DG.Tweening;
using UnityEngine;

[RequireComponent(typeof(RectTransform))]
public class DotweenTest : MonoBehaviour
{
    private RectTransform _rectTransform = null;

    private void Awake()
    {
        _rectTransform = GetComponent<RectTransform>();
    }

    private void Start()
    {
        // Tween開始
        Vector2 start = Vector2.zero;
        Vector2 end = new Vector2(0f, -30f);

        _rectTransform.anchoredPosition = start;
        _rectTransform.DOAnchorPos(end, 10f).SetEase(Ease.OutQuart);
    }
}

これを動かし、トゥイーンが終わる前に(シーン遷移などで)アタッチされているゲームオブジェクトが破棄されると上の警告(エラー)が出るようになります。
ゲームオブジェクトはもうないのに、それに対するトゥイーン処理が残り続けているのがマズいみたいですね。

対処方法

(これがトゥイーン完了まで消えない前提で組まれているとかならそのままでもいいかもしれませんが、)一番はゲームオブジェクトが消える際にトゥイーンも一緒に破棄してあげることかなと思います。
具体的にはTweenを覚えておいてOnDisableの中でKillです。
(こいつは何を言っているんだ???…って感じかと思いますが、下記のコードを見て頂ければ一発かと思います。)

DotweenTest.cs
using DG.Tweening;
using UnityEngine;

[RequireComponent(typeof(RectTransform))]
public class DotweenTest : MonoBehaviour
{
    private RectTransform _rectTransform = null;
    private Tween _tween = null;

    private void Awake()
    {
        _rectTransform = GetComponent<RectTransform>();
    }

    private void Start()
    {
        // Tween開始
        Vector2 start = Vector2.zero;
        Vector2 end = new Vector2(0f, -30f);

        _rectTransform.anchoredPosition = start;
        _tween = _rectTransform.DOAnchorPos(end, 10f).SetEase(Ease.OutQuart);
    }

    private void OnDisable()
    {
        // Tween破棄
        if (DOTween.instance != null)
        {
            _tween?.Kill();
        }
    }
}

補足

上のコードのif判定ですが、エディタ再生終了時のオブジェクト破棄順序次第でDOTweenComponent(画像参照)が先に破棄されると出る後述のエラーを回避するためです。
シングルトンあるある。

dotween_component.png

エラーメッセージ
Some objects were not cleaned up when closing the scene. (Did you spawn new GameObjects from OnDestroy?)

参考

17
8
1

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
17
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?