[Phaser3]Tweenに関するTips

2022-2-11

目次

Tweenって何?

Twitterのアプリケーションかと思いましたが違いました。
Tweenとは、ゲームオブジェクトをある状態から別の状態に変化させるとき、状態間の変化を補って段階的に描画してくれる機能です。

これによって、以下のような事ができるようになります。

  • 指定秒数かけてゲームオブジェクトを現在地から指定の場所に移動させる
  • 指定秒数かけてゲームオブジェクトを一回転させる
  • 指定秒数かけてゲームオブジェクトを透過させる

回転させる為にアングルを切り替えただけでは、パッと描画が切り替わってしまいますが、
Tweenを利用すれば指定した秒数をかけて状態を段階的に変化させるアニメーションを作成できます。

基本

ドキュメントは必ず見ておきましょう。
ドキュメント - Phaser.Tweens

主に以下の3つのクラスを使っていく事になります。

特に肝になるのはTweenManagerで、tweenを使う際は基本的にこのTweenManagerを通して使います。
シーン内で以下のように参照できます。

this.tweens;

Tweenを作成する

Tweenを作成する為のメソッド

Tweenを作成する為のTweenManagerの主なメソッドは以下の二つです。

  • add() :作成と同時にアニメーションが開始される
  • create() :アニメーションを停止した状態で作成される

引数はどちらもオブジェクトで、戻り値は Tween となります。
引数のオブジェクトにどのようなプロパティがあるかはドキュメントに記載されています。

ドキュメント - TweenBuilderConfig

this.tweens.add({});
this.tweens.create({});

それぞれでTweenを作成してみます。
例:3秒間かけてテキストを透明にする

// add()バージョン
const text = this.add.text(100, 100, 'Phaser3');
const tween = this.tweens.add({
	targets: text,
	duration: 3000,
	props: {
		alpha: 0
	}
});
// create()バージョン
const text = this.add.text(100, 100, 'Phaser3');
const tween = this.tweens.create({
	targets: text,
	duration: 3000,
	props: {
		alpha: 0
	}
});
tween.play();

二つのメソッドの違いは、Tweenの作成と同時にTweenが実行されるか否かです。
add()は同時にTweenが実行されますが、create()は戻り値のTweenインスタンスのplay()を実行する必要があります。

Tweenで変更したいゲームオブジェクトの値は以下のように設定します。

props: {
	ゲームオブジェクトの変更させたいプロパティ: 変更後の最終的な値
}

以下に、よく使うプロパティをコメント付きで参考までに置いておきます。

// targets以外はoptionalなのでお好みで

const tween = this.tweens.add({
	// Tweenアニメーションを設定するゲームオブジェクト(配列も可)
	targets: gameObject,
	// Tweenが作成されてから何秒(ms)後にアニメーション開始するのか
	delay: 2000,
	// 何秒(ms)かけてアニメーションをさせるのか
	duration: 3000,
	// イージングの設定
	ease: Phaser.Math.Easing.Linear,
	// アニメーションを繰り返す回数(-1にすると無限に)
	repeat: 1,
	// repeatされる前の待機時間
	repeatDelay: 1000,
	// アニメーション完了後に巻き戻すか否か(ヨーヨーの動きに由来した名前で可愛らしいw)
	yoyo: true,
	// loopさせる回数
	loop: 1,
	// loopされる前の待機時間
	loopDelay: 1000,
	// tween作成時にアニメーションを停止させておくか否か
	paused: false,
	// アニメーション終了時に呼び出される関数 
	onComplete: () => {},
});

Tween作成時の引数に関する追加知識

ここまでのコードでは、変化させたい値をadd()やcreate()の引数TweenBuilderConfigの中のpropsに定義してきました。

props: {
	alpha: 0
}

しかし、公式のexampleではpropsを使わない、以下のようなTweenBuilderConfigの中に直接書いているコードを多く見かけます。

const text = this.add.text(100, 100, 'Phaser3');
const tween = this.tweens.add({
	targets: text,
	duration: 3000,
	// propsにではなく、TweenBuilderConfigに織り混ぜて書いている
	alpha: 0,
});

どちらでも動くのですが、個人的にはTweenBuilderConfigのpropsに書く事をオススメします。
理由は以下です。

  • ソースコードを見たところ、まずpropsを見て、propsがなければTweenBuilderConfigの中から探すような処理になっている
  • propsを使う事で他のプロパティとの住み分けが出来る

など、走る処理の量的にもコードの見やすさ的にもpropsに書いた方がメリットがあります。

propsへの値の渡し方について

書くと長くなるのと、記事として上手くまとまらないのでガッツリとは書きませんが、
ここのコードこのサイトをみると、propsへの渡し方には色々な形があるのがわかります。

// alphaを0にする色々な方法
props: {
	// 1つめ
	alpha: 0
	// 2つめ
	alpha: {
		value: 0
	},
	// 3つめ
	alpha: { 
		from: 1, to: 0 
	},
	// 4つめ
	alpha: { 
		start: 1, to: 0 
	},
	// 5つめ
	alpha: { 
		start: 1, from: 1, to: 0
	},
	// 6つめ
	alpha: (target, key, value) => {
			value = 0;
      return value;
  }
}

また、現在の値にプラスしていくようにするには以下のように文字列で書きます。

// 現在のxに100プラスした位置まで移動する
props: {
	x: '+=100',
}

作成されたTween

作成されたTweenは、Tweenクラスのインスタンスになります。
このクラスは名前の通り、作成されたTween自体の情報とメソッドを持つクラスです。
プロパティやメソッドはドキュメントを参照してください。
ドキュメント - Phaser.Tweens.Tween

参考までに、以下のようなものがあります。

const tween = this.tweens.add({
		// 略
});
// tweenを実行する
// ※ play()は以下の場合にのみ使えます(これ以外の場合は自動で実行される)
// 1:create()で作成した
// 2:pauseをtrueにして作成した
// 3:tweenの実行が終了している
tween.play();
// 一時停止する
tween.pause();
// 一時停止から再会する
tween.resume();
// 初めから実行し直す
tween.restart(); 

delayなどのプロパティも変更する事が可能なので、Tween作成後にも色々とカスタマイズ出来るようです。

Timelineを作成する

複数のTweenを用いて、以下のような一連のTweenを作る事が出来る機能です。

Tweenその1を実行 → Tweenその1が完了 → Tweenその2を実行 → Tweenその2が完了→ Tweenその3を実行 → Tweenその3が完了

Timelineを作成する為のメソッド

Timelineを作成する為のTweenManagerの主なメソッドは以下の二つです。

  • timeline() :作成と同時にアニメーションが開始される
  • createTimeline() :アニメーションを停止した状態で作成される

どちらも引数は任意でオブジェクトを渡します。
引数のオブジェクトにどのようなプロパティがあるかはドキュメントに記載されています。
ドキュメント - TimelineBuilderConfig
戻り値はTimelineとなります。

this.tweens.timeline();
this.tweens.createTimeline();

試しに、timeline()でTimelineを作成してみます。
例:3秒間かけて以下のアニメーションを実行する

テキストのxを200に → テキストのyを200に → テキストのxを100に → テキストのyを100に

const text = this.add.text(100, 100, 'Phaser3');
const timeline = this.tweens.timeline({
	targets: text,
  totalDuration: 3000,
  loop: -1,
  tweens: [
	  {
      props: {
        x: 200
      }
    },
    {
      props: {
        y: 200
      }	    
    },
    {
      props: {
        x: 100
      }
    },
    {
      props: {
        y: 100
      }
    }
   ]
 });

tweensというプロパティに、個々のTweenを作成する為のTweenBuilderConfigのオブジェクトを配列で渡しています。
Timelineを実行すると、この配列の先頭のTweenから実行されていくようになっています。

以下に、TimelineBuilderConfigのプロパティを一部コメント付きで参考までに置いておきます。

const timeline = this.tweens.timeline({
	// Tweenアニメーションを設定するゲームオブジェクト(配列も可)
	targets: gameObject,
	// 個々のTweenを作成する為のTweenBuilderConfigのオブジェクトを配列で渡す
	tweens: [],
	// timelineを何秒(ms)かけて実行させるのか
	totalDuration: 2000,
	// 個々のTweenを何秒(ms)かけて実行させるのか
	// ※ 個々のTweenBuilderConfigで設定した方がいい
	// ※ totalDurationと併用できない
	duration: 3000,
	// イージングの設定
	ease: Phaser.Math.Easing.Linear,
	// 個々Tweenを繰り返す回数(timelineを繰り返す設定にはloopを使う)
	repeat: 1,
	// repeatされる前の待機時間
	repeatDelay: 1000,
	// 個々のTweenを実行後に巻き戻すか否か(timelineを巻き戻す設定は見たところ無い)
	yoyo: true,
	// timelineをloopさせる回数
	loop: 1,
	// loopされる前の待機時間
	loopDelay: 1000,
	// tween作成時にアニメーションを停止させておくか否か
	paused: false,
	// アニメーション終了時に呼び出される関数 
	onComplete: () => {},
});

注意点として、そのプロパティがTimelineを形成する個々のTweenに対して作用するのか、Timeline自体に対して作用するのかを意識する必要があります。

例えば、 Timelineを繰り返し実行したいときにrepeatを使うと、個々のTweenに対して作用し思ったような動作になりません。Timelineを繰り返し実行したいときはloopを使います。

作成されたTimeline

TweenManagerのadd()やcreate()によって作成されたTimelineは、Timelineクラスのインスタンスになります。
名前の通り、作成されたTimeline自体の情報とメソッドを持つクラスです。
プロパティやメソッドはドキュメントを参照してください。
ドキュメント - Phaser.Tweens.Tween

参考までに、以下のようなものがあります。

const timeline = this.tweens.timeline({
		// 略
});
// 一時停止する
timeline.pause();
// 一時停止から再会する
timeline.resume();
// 初めから実行し直す
timeline.restart();

Tweenを追加する事もできます。timelineの最後に追加されます。

// 引数はTweenBuilderConfig
timeline.add({
	// 略
});

参考

公式サンプル - TWEENS
ドキュメント - Phaser.Tweens
ドキュメント - Phaser.Tweens.Tween
ドキュメント - Phaser.Tweens.TweenTimeline
ドキュメント - Phaser.Tweens.TweenManager
GitHub - ソースコード