(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]

DoScaleとAnimationCurveの併用で起きた問題と解決方法【Unity】【アセット】【DOTween】【トラブルシューティング】


このエントリーをはてなブックマークに追加

この記事でのバージョン
Unity 2018.4.1f1
DOTween v1.2.250 (DOTweenPro V1.0.155)


はじめに

Unityで位置や大きさなどのアニメーション、

いわゆるTweenを実装するアセットとしてお馴染みのDOTween



そんなDOTweenを使っていて、以下のような感じでちょっとハマった事があったので、

f:id:kan_kikuchi:20190714062234g:plain


今回はその現象と解決した方法について記事にしてみました。


なお、記事中の画像は以下のアセットを使っております。





DoScale

DOTweenはDoScaleを使うことで、簡単にスケールのアニメーションが実装出来ます。

//アニメーション対象の武器のTransform
[SerializeField]
private Transform _weapon = null;
  
/// <summary>
/// ボタンがクリックされたら実行される
/// </summary>
public void OnClick() {
  Debug.Log("Tween実行!");
  //武器を1秒かけて、スケール0にする
  _weapon.DOScale(0f, 1.0f);
}
f:id:kan_kikuchi:20190714060925g:plain



DoScale + AnimationCurve

UnityにはAnimationCurveという、曲線を自由に設定できる機能(?)があります。



そしてこのAnimationCurveをDOTweenで利用したい場合はSetEaseを使います。

//アニメーション対象の武器のTransform
[SerializeField]
private Transform _weapon = null;
  
//Tweenの動きを設定するための曲線
[SerializeField]
private AnimationCurve _animationCurve = null;
  
/// <summary>
/// ボタンがクリックされたら実行される
/// </summary>
public void OnClick() {
  Debug.Log("Tween実行!");
  //武器を1秒かけて、_animationCurveの動きに合わせて、スケール0にする
  _weapon.DOScale(0f, 1.0f).SetEase(_animationCurve);
}
f:id:kan_kikuchi:20190713073511j:plain
f:id:kan_kikuchi:20190714061048g:plain



ちょっとハマった事

ここからが本題かつ問題なのですが、

以下のようにスケールが1 → 0.2 → 1みたいな感じのTweenをしようとした際、

f:id:kan_kikuchi:20190714055224j:plain


普通にDOScaleすると動きませんでした。

//武器を1秒かけて、_animationCurveの動きに合わせて、アニメーションさせたかった(動かない)
_weapon.DOScale(1f, 1.0f).SetEase(_animationCurve);
f:id:kan_kikuchi:20190714061350g:plain


おそらく最初のスケールが1だったので、

開始時と終了時のスケールが同じで、Tweenする必要がないと判断されて動かないようです。

f:id:kan_kikuchi:20190714060517j:plain


なので、Tween前にスケールを0にしてから実行すると、動きはしたのですが、

なぜか最初の一回だけ一瞬消えるようになりました。

//一旦、武器のスケールを0にする
_weapon.transform.localScale = Vector3.zero;

//武器を1秒かけて、_animationCurveの動きに合わせて、アニメーション
_weapon.DOScale(1f, 1.0f).SetEase(_animationCurve);
f:id:kan_kikuchi:20190714062234g:plain


最終的にDOScaleを使わず

値をTweenさせて、その値を使った処理を自分で実装するDOTween.Toを使って解決しました。

//timeを0 ~ 1まで変化させ、その間のAnimationCurveの値をEvaluateで取得し、スケールのTweenを実行
DOTween.To(
  () => 0, //値(time)の初期値
  (time) => _weapon.transform.localScale = Vector3.one * _animationCurve.Evaluate(time),//値を使った処理
  1.0f, //値(time)の最終値
  1.0f //Tweenの時間
);
f:id:kan_kikuchi:20190714062330g:plain


一応、これでやりたい事は出来たのですが、

もしかしたらもっと正攻法的なやりかたがあるのかもしれません

(もしご存知の方がいらしたらご一報頂けると幸いです!)