原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】クロマキーシェーダを使って動画を合成する

会社行事

コロナ禍が収まったおかげで会社の色々な行事が復活し、4月の新人歓迎会が今から戦々恐々な皆さんこんにちは。わが社では新人歓迎会で既存の社員一人一人が壇上に立ち新入社員に対して自己紹介するという地獄のコーナーがあるので本当に憂鬱で仕方ありません。頑張って新人相手に自己紹介したところで3年以内に1/3は辞めるし意味ないのになぁ。

 

謎解き×謎解きなゲーム

ストレートな謎解きの一歩手前でその問題の意味自体を解読するという謎解きで包んだゲームが丁度セールで安くなっていたので購入しました。

多民族がそれぞれ異なる言語で分断された世界を舞台に、主人公(プレイヤー)が各々の民族が語る言葉の意味を解き明かしながら、民族間の軋轢を解消していく、という形でゲームは進みます。
「軋轢を解消していく」とは言え、主人公が民族間の紛争に積極的に介入していくというわけでなく、各民族が暮らすそれぞれの世界へ侵入し、そこで交わされている言葉と行動を見ながら各民族が使う文字の意味と文法を理解して、間接的に民族間の会話の翻訳者となり、それにより民族間の誤解が解けていく、というストーリーとなっています。

各民族の世界では主人公(プレイヤー)は歓迎されたり、敵視されたり、助けを求められたりするので、それらの問題に対処するための解決法を探り、提示された謎解き(パズル)を行っていきます。

謎解き(パズル)自体は記号の順序立て(並べ替え)やスライドパズル、お使い系(必要なアイテムを探してくる)といった既存のADVゲーム、脱出系ゲームにありがちなもので目新しさはないのですが、その問題を解くために先程の言語解読という謎解きを行う必要があるため、そういった二段構えの謎がプレイヤーの探求心をそそり、ゲームプレイを奥深いものにしています。
言語の解読というと難しいテーマに思われがちですが、想像よりもかなり遊びやすくデザインされており、プレイヤーが途中で挫折しないよう色々と仕掛けが練られて非常に完成度の高い作品だと思います。謎解きが好きな方はチャレンジをお勧めします。

 

素材提供

詳細は省きますがつい先日、大物Vtuberの方が自身のMVの一部を合成用素材として公開されています。

t.co有難い事に綺麗なブルーバックの動画となっているので、これならUnityでも気軽に合成してゲーム内に取り入れられるのでは?と思いチャレンジしてみました。

上記の公開されている動画はYoutubeからダウンロードしてUnityのProiectウィンドウ内にドラッグ&ドロップすればプロジェクト内に取り入れる事ができます。

 

Unityで動画を再生するのは非常に簡単で、まずは動画を表示するためのオブジェクト(PlaneやQuad)をゲーム内に作成します。

中央の白い四角がスクリーン用オブジェクト

スクリーン用のオブジェクトは出来るだけ動画のアスペクト比に合うようにサイズ調整します。
次にオブジェクトにInspectorウィンドウのAdd Componentから、VideoPlayerコンポーネントを追加します。

後はVideoClip欄に再生したい動画ファイルを指定してデバッグを実行すれば自動的に動画が再生されます。

動画を再生

これはVideoPlayerの「Render Mode」の設定に「Material Override」が指定されているので、スクリーンオブジェクトのマテリアルに動画の映像が上書きされている為ですが、このままの指定だと上の動画のようにブルーバックも表示されてしまう結果となります。

 

クロマキーシェーダ

ブルーバックを消す(透過させる)にはクロマキーシェーダを使用する方法が最も手軽な方法でしょう。
クロマキーシェーダとはその名の通り特定の色を透過させるシェーダで、アセットストア上には有料アセットとして存在していますが、今回は凹みTipsさんが公開しているクロマキーシェーダを使用します。

tips.hecomi.com

このクロマキーシェーダでは使用するTextureに対して指定した色を透過させてオブジェクトを表示します。
このTextureにVideoPlayerが再生する画像を指定すれば良いわけです。

VideoPlayeが再生する画像をTextureに描き出すには先程の「Render Mode」の設定を「Render Texture」に変更します。

 

RenderTextureはProjectウィンドウ上で右クリック→Createから作成します。

作成したRenderTextureは解像度(サイズ)を再生したい動画のアスペクト比に合うように設定します。

 

そして先程のVideoPlayerコンポーネントのTargetTexture欄に作成したRenderTextureを指定します。

 

クロマキーシェーダはスクリーン用オブジェクトのマテリアルのシェーダに設定します。

シェーダのTextrureにVideoPlayerコンポーネントで指定したRenderTextureを指定、ChromaKeyのColor欄に動画のブルーバックの色(青)を指定します。

実行結果はこちら、Unityのゲーム空間内に大物Vtuberさんの動画を合成させる事ができました。

 

別バージョンがこんな感じ、違和感なく動画を合成できます。

 

宣伝

数学的脱出ゲーム「W.T.」早期アクセス版リリース中です。
歯ごたえのある脱出ゲームとなっているので腕に自信のある方のチャレンジ、お待ちしております。

store.steampowered.com

【Unity】UniTaskのWaitUntilやWaitUntilValueChangedは便利

DLC

エルデンリングDLCの為に一年以上ぶりにエルデの地へ降り立ったものの操作方法を忘れて遺灰すら呼び出せない褪せ人の皆さんこんにちは。なんでも情報によるとDLCで遊ぶ為にはモーグウィン王朝のクリアが必須らしいのですが、二周目を始めて中途半端に放置していたせいで王朝へ辿り着くまでの道のりが遠すぎて今更そこまで到達できるか不安です。なんせ二周目開始早々に白面のヴァレーを倒してしまったので聖別雪原まで行かないといけない。早く操作方法を思い出して6月までにはDLC開始条件を満たしておきたいと思います。

 

ソウルライクである必要がなかったゲーム

PS Plusの2月分のフリープレイ対象になっていたのでダウンロードして遊んでみました。

18世紀のフランス革命を舞台にしたソウルライクゲームで主人公はマリーアントワネットに使える機械人形(オートマタ)という設定。
同じソウルライクゲームのLies of Pと似たような設定ですが、発売はこちらの方が早く、「ぼくのかんがえたさいきょうのダークソウル」的なLies of Pと比べ、「ソウルライク」のゲームルールに乗っ取りながらも手軽にスピーディなアクションが楽しめるゲームとなっています。
剣や斧、槍といったオーソドックスな武器は殆ど使用せず、鉄扇やトンファー、マスケット銃、仕込み爪といった一風変わった仕掛け武器を使用してオートマタという設定を活かした独特なモーションによる戦闘は独自性に富んでいて非常に楽しい要素でした。
各ステージも建物の上や地下を巡り立体的に交差して迷宮的な構造を成しており探索して飽きない作りになっていたと思います。

とは言え、「ソウルライク」と銘打っているものの難易度的には非常に低く、それほどゲームが上手くない私でも殆どのボスを初見で撃破できる程。その反面、道中の敵は複数体を同時に対処しなければならないよう配置されており(特にゲーム後半)、少し鬱陶しく感じる場面も多かった気がします。
自キャラの操作はスムーズで、戦闘の軽快さや爽快感は非常に高いものがあります。普通のアクションRPGとして見れば十分に評価されるべきゲームだと思うのですが、「ソウルライク」という縛りがあるせいで、「ソウルライク」特有の難易度と攻略の達成感を期待するプレイヤーには物足りなく感じるでしょう。
開発側はユーザ層を広げる為に初心者向けの「ソウルライク」を目指したのかもしれませんが、普通に新規のアクションRPGとしてゲームデザインを組み立てた方がもっと評価を得られたのではないでしょうか。

 

UniTask

Unityで非同期処理っぽい事をするにはCoroutineを使うのが一般的でしたが、ここ最近ではUniTaskを利用する方が増えてきているようです。

UniTaskとはC#のTaskと同じような機能を持つAPIですが、Unity用に最適化されておりC#の標準のTaskやUnityのCoroutineよりもパフォーマンス性が高く、既存のCoroutineからの処理の転用も容易、かつ無料なので、まぁ導入にはメリットしかないわけです。

UniTaskの導入はGitHubから取得したunitypackageをインポートするだけです。

github.com

 

UniTaskの基本的な使用法はC#のTaskとほぼ同様で、async/awaitを使って非同期処理を実施します。例えば「3秒待ってstring型の戻り値を返す」という処理なら

private async UniTask<string> UniTaskWait()
{
    // 待機処理はawait
    await UniTask.Delay((int)(3 * 1000));

    return "End";
}

という実装になります。

 

静的メソッド

UniTaskを利用する大きな利点の一つとして静的メソッドが豊富に用意されている事も挙げられます。

上記の指定時間を待つ「Delay」というメソッド以外に1フレーム待機するメソッド(Yield)や、起動したTaskの全ての完了を待つメソッド(WhenAll)、もしくはどれか一つの完了を待つメソッド(WhenAny)と色々ありますが、特に使用頻度が高いのは、指定した条件がtrueになるまで待機するメソッド(WaitUntil)と指定したオブジェクトの特定の値が変化するまで待機するメソッド(WaitUntilValueChanged)ではないでしょうか。

ちなみにWaitUntilの逆で指定した条件がfalseになるまで待機するメソッド(WaitWhile)もちゃんと用意されています。

 

WaitUntilでは条件文を指定できるので例えば

// Y方向の位置が0超過するまで待機
await UniTask.WaitUntil(() => transform.position.y > 0); 

Debug.Log("上昇");

上記のような条件で処理を待つことができます。

 

WaitUntilValueChangedの場合は下記のような指定により

//Y方向への移動を検知する
await UniTask.WaitUntilValueChanged(transform, x => x.position.y); 

オブジェクトの状態(Y方向)が変化するのを待つことが出来ます。

 

使用例

具体的な使用例としてカウントダウンタイマのようなものを作ってみました。

中央の数字がカウントダウンする毎に背景色が変化し、カウントダウンが終了したら「Start」の文字を表示します。

背景色の変更はWaitUntilValueChangedを使用しカウントを表示するテキスト(TextMeshPro)の変更を待って行います。「Start」の文字表示は終了条件に達したフラグを参照するようにWaitUntilを使って待っています。

public TextMeshPro ContText;
bool isStart = false;

private async UniTaskVoid ColorChange()
{
	// ContTextの文字(text)の変更を待つ
	await UniTask.WaitUntilValueChanged(ContText, x=> x.text); 
	
	// 背景色を変更する
} 

private async UniTaskVoid WordDisp()
{
	// フラグ(isStart)がtureになるのを待つ
	await UniTask.WaitUntil(() => isStart); 
	
	// Startの文字を表示
} 

 

宣伝

数学的脱出ゲーム「W.T.」早期アクセス版リリース中です。
歯ごたえのある脱出ゲームとなっているので腕に自信のある方のチャレンジ、お待ちしております。

store.steampowered.com

【Unity】VContainerの使用例(MVPパターン)

ロゴ変更

プロジェクトのロゴを変更して切羽詰まった気分を一新したいルーザーの皆さんこんにちは。以前のロゴはとある方に発注して作成して頂いた物だったので、変更するのは忍び難かったのですが、昨年末からどうも思うようにいかない事が多く、停滞気味の状況に変化を加えるべくロゴを新しくしました。
(それに伴いブログのタイトル画像も変えました)

 

ファーストインパクトで乗り切るゲーム

Xでトレーラーが発表された時にかなり話題になっていたものの、本編発売後はそれほど取り上げられることが少なかったゲームを購入しました。


「写真をかざすと写真の中の世界が顕在化(3D化)する」というアイデアはパズルのメカニクスとして斬新でゲーム開始時のファーストインパクトは非常に大きいと思います。思わず「すげー」と声がでそうになるほど。

同じようなコンセプトのゲームで『Superliminal』というゲームがありますが、遠近感の錯覚を利用しオブジェクトの大小を変えることで解法を探す『Superliminal』と比べ、こちらは「2Dの写真で3D空間を上書きする」というメカニクスであるため、到達不能と思える場所には壁を写した写真をかざして足場を作る、数が不足しているアイテムは写真に映してコピーを作るといった、どちらか言えばストレートな考え方で正解に辿り着く問題が多い印象です。

この為、パズルの難易度的には低く、ゲーム後半でも詰まる場面は殆どありませんでした。ボリューム的にも3,4時間程度で終わってしまう為、人によっては物足りないものに感じるかもしれません。
とは言え、Steamのレビューでも「非常に好評」となっているように、「写真で空間を上書きする」というアイディアを可能な限り活かしてゲームに落とし込めており、徐々に難易度が上がっていくパズルに対して、それを解いた時の爽快感は終盤まで落ちる事はありませんでした。
3,4時間程度で終わるボリュームの少なさも、逆に言うと「写真で空間が上書きされる」という最初の驚きを超えるような事象は最後まで起きないので、このクリア時間程度で終わるのが丁度良い塩梅なのかもしれません。

 

VContainerとMVPパターン

前回の記事でUnityでDIコンテナを実現するアセットVContainerを紹介しました。

www.karvan1230.com

その具体的な利用例として最も最適なのがMVPパターンによる実装だと思います。
MVPパターンとはデザインパターンの一種で、ザックリ説明するとPresenterという仲介者を挟むことでプロジェクトの内部処理(Model)と表示処理(View)との依存関係を無くそう、という設計思想になります。


上の図では事務処理を行う部署(Model)とプレゼンテーションを行う部署(View)は互いの仕事に全く関与せず、それを仲介する部署(Presenter)を通してデータのやり取りを行っています。こうすることで、たとえどちらかの部署に大きな内部変更があったとしても、もう一方の部署の業務には影響を与えることが無くなります。
これよりModelとViewとは互いの依存関係は無くなりますが、逆にこれらを仲介するPresenterはどうしてもModelとViewに依存する形となってしまいます。
そこでVContainerを利用すればPresenterもModelとViewに依存しない形として実装することが可能となります。

サンプルプロジェクト

今回はUnity公式からデザインパターンの学習用としてリリースされているサンプルプロジェクトを使って見たいと思います。

github.com

こちらにMVPデザインパターン用のシーンがあります。

 

このシーンでは画面中央の的に対してマウスをクリックすると画面下部のHealth値とそれを示すバー(スライダー)が減っていきます。

これはマウスの入力(Clickイベント)を受け付けると

  1. Presenterに対してHealthの更新を依頼する
  2. PresenterはModelに対してHealthの減算を依頼する
  3. 同時にPresenterはModelが発行する更新ベントの受け手に登録
  4. ModelがHealthの減算を行い、更新イベント発行
  5. イベントを受けたPresenterがViewへ表示の更新を依頼

という順序で処理が行われます。

上図でもわかる通り、現状ではModelとViewは互いに疎結合ですが、PresenterはModelとViewに依存しています。

 

VContainerを導入

ここでVContainerの登場です。

 

まず事前準備としてPresenterは参照しているModelとViewのインスタンスをコンストラクタの引数に設定してVContainerから受け取れるようにします。

次にVContainerのLifeTimeScopeを継承したクラスを作り、その中でPresenter,Model,Viewを登録します。

各クラスの登録は必ずConfigureメソッド内で行いますが、登録に用いるメソッドはPresenter,ModelとViewで異なります。

Model、Presenterはそれぞれシーン内で一意で良いため、「Lifetime.Singleton」というオプションをつけて登録(Register)します。
Viewは、シーン内に存在するスライダー(Viewがアタッチされている)が処理の対象となるため、ヒエラルキー内でViewクラスがアタッチされているオブジェクトを探して登録する必要があります。この為、登録には「RegisterComponentInHierarchy」を使用します。

ここまで実装出来たらVContainerへの登録は完了したので、後はマウスクリックの入力を受け付けたタイミングでVContainerから取得したPresenterクラスへHealthの更新を依頼して処理を実行します。

■実装例

 

おわりに

VContainerの使用例の説明を行いました。

DIコンテナを導入することでSOLID原則に沿った綺麗な設計を行うことが出来る事が分かった思います。

とはいえ、このパターンを実装すれば色んな問題が解決する、というわけではないので導入前にはプロジェクト内のどの場面で利用できるのかきちんと整理する事が重要です。

 

宣伝

数学的脱出ゲーム「W.T.」早期アクセス版リリース中です。
歯ごたえのある脱出ゲームとなっているので腕に自信のある方のチャレンジ、お待ちしております。

store.steampowered.com

 

【アセット紹介】DIコンテナを使った疎結合デザインの実現 VContainer -概要編-

マスク

コロナ禍が一旦落ち着いてやっとマスクから解放されたと思っていたらインフルエンザと花粉症で再びマスク生活に戻った皆さんこんにちは。ここ最近外を歩くとマスクをしている人の方が多い気がします。電車とかノーマスクで乗っていたらちょと視線を感じるし。

 

SOLID原則

個人でゲームを開発している分には開発した本人がメンテナンスを出来さえすればどんなコードでも構わないのでしょうが、チーム開発だったり、私みたいに作っている最中に仕様変更を繰り返すような人間には出来るだけSOLID原則に沿った設計で開発を進める方が、後々の作業のし易さに直結すると思います。
SOLID原則とはソフトウェアの拡張性や保守性を高めるために設計時に考慮すべき開発原則で、ネットで調べれば解説記事が数多く上がっていますし、私もこのブログで記事にしています。

www.karvan1230.com

 

SOLID原則の中では基本的に各クラスは一つの役割を担うべき(複数の機能を持たない)なので、設計時に機能を細分化して各クラスに実装しますが、とはいえメイン処理に該当するクラスでは各機能を担うクラスへ処理依頼を出したり、処理結果を取得したりする必要があり、どうしても各クラスを参照する密結合な実装になりがちです。

密結合な例

 

そうするとメイン処理側は参照している各機能クラスが全て実装された後でないと実装できないし、各機能クラスが更新される度に影響を考慮する必要となります。

この為、それらの問題点の回避策として各機能クラスへの参照は共通的なInterfaceを介して行うようにする、といったデザイン設計がとられる事が多いです。
そうすることでメイン処理側も各機能の実装を待たなくても良いですし、各機能クラスの更新や入れ替えといった作業にも耐えうることが出来ます。

Interfaceを利用した疎結合モデル

 

上の図のようにメイン処理側が参照する各機能クラスのInterfaceは外部から渡される形式とすればメイン処理と各機能クラスは完全な疎結合な状態になることができます。では、各機能クラスのインスタンスは誰が生成してメイン処理に渡してくれるのか?
そういった役目を担ってくれるのが「DIコンテナ」と呼ばれるフレームワークになります。

DIコンテナの利用

 

VContainer

DIコンテナはクラス間の密な依存関係を外部で一元管理して疎結合な関係を実現し、問題を解決します。
Unityでは「Extenject(旧 Zenject)」といったアセットが有名ですが、今回は「VContainer」というアセットを取り上げます。

VContainerはExtenjectと比較して軽量で、シンプル形式のAPIを使用するため実装がわかりやすく、且つ無料です。
GitHubにunitypackageがリリースされているので、そちらをダウンロードしてUnityのプロジェクト内に取り入れる事ができます。

github.com

Unityでは基本的にGameObjectにMonoBehaviourを継承したクラスをアタッチして処理の起点としますが、VContainerを使用することで、純粋なC# クラスのエントリポイントをつくることができます。

これによりMonoBehaviourとは切り離して純粋なロジックのみのクラスを実装でき、より依存性が低い設計モデルを構築する事ができます。

 

概要

VCointanerは以下の流れで使用します。

  1. ContainerBuilderを生成
  2. ContainerBuilderに使いたいクラスを登録
  3. ContainerBuilderからIObjectResolverを生成
  4. IObjectResolverを通して使いたいクラスを取得

これを先ほどの図を使って表すとこんな感じ

VContainerを使用した関係図

手順だけを見ると少し複雑でコードの量が増える気さえしますが、上の1~3の部分はそれを担うコンポーネントがシーン内に一つあればよく、IObjectResolverから受け取るクラス(上の図ならMainService)はContainerBuilder内で一様(Singleton)に保持されているのでどこから取得されても同じものを使用する事ができます

これよりクラス間のデータの引き渡しもコンテナ内のクラス(上の図ならMainService)を介して行う事ができるので利便性が向上します。

 

Hello Worldは次回

概要の説明だけで記事が長くなってしまったので、具体的な使用例は次回紹介したいと思います。

 

【小ネタ】DOTweenのSetEaseの第二引数って何に使うのか

アベイラブル

「デフォルト」や「エビデンス」などの言葉を会話の中に混ぜる人はよくいますが「アベイラブル」を使ってくる人は初めて遭遇した皆さんこんにちは。どうやら「available=利用可能=手が空いてる」らしいのですが、何の連想ゲームですか?それなら素直に「手が空いてます」と言えよ。

 

福岡インディーゲームEXPO

先週末は東京ゲームダンジョン4が行われていた為、X(旧Twitter)やYoutubeでは展示作品の紹介や会場のレポート、プレイした感想等の投稿を見る事ができます。東京から遠く離れた地方民としては会場の様子を知ることができて有難い限りなんですが、やっぱり参加したかったなぁ、という思いが強いです。
去年初めて展示会イベントに参加して、自作ゲームを遊んでもらえて、直接感想を聞ける体験の重要さを知ったので、展示会イベントには積極的に参加しようと決めたのですが、東京に行くにも大阪に行くにもそれなりに時間と経費が掛かり、懐の関係上、おいそれと出掛ける事は出来きません。
出来れば地元の福岡でもインディーゲームの展示会イベントがあればなぁ、と思っていたところ、つい先日福岡インディーゲーム協会より「福岡インディーゲームEXPO」が開催される発表がありました!

www.fukuoka-indiegame.com

キャナルシティ博多で3/23,24の二日間行われること以外の詳細は発表になっていないのですが、展示会イベントに参加できず燻っている私にとっては非常に嬉しい発表です。
「福岡インディーゲームEXPO」は2022年にも一度開催されていますが、その時は参加できなかったんですよね。「次に開催された時は」と思っていたので、準備期間が約二か月とあまりありませんが、これから参加の準備を進めたいと思っています。まぁ、現時点では参加要項が分からないので参加できるのかわかりませんが。

 

Easing

DOTweenでEasingを指定する時は大抵「Ease.Liner」「Ease.InSine」などDOTweenが用意した列挙型クラスを使うのですが、変化率を確認しながら指定したい場合はAnimationCurveをSetEaseにそのまま指定することもできます。
一般的なEasingのAnimationCurveは有難い事に有志の方がPackageとして公開されているのでこちらを導入することをお勧めします。

baba-s.hatenablog.com

上記のPackage導入後は、AnimationCurveのウィンドウで歯車アイコン→Presetsから「EasingFuncitions」指定して使用することができます。

 

第二引数

DOTweenのドキュメントを確認して知ったのですが、SetEaseには特定のEasingにのみ対応したパラメータが存在します。

assetstore.unity.com


まず、Back系のEasing(InBack,OutBack)に対しては「Backする大きさ」を第二引数で指定できます。
試しにInBackでデフォルト値(1.70158)より大きな値を第二引数に指定して比べてみるとこんな感じ。

確かにBackする距離が伸びている事が分かります。

 

次にElastic系(InElastic,OutElastic)に対しては「振幅の大きさ」を第二引数で指定できます。
こちらも先程と同じようにデフォルト(1.70158)と、それより大きな値を第二引数に指定した場合を比べてみると

こんな感じで挙動に違いが出る事が分かりました。

 

EaseFactory

SetEaseには拡張的な使い方として「EaseFactory」を使用してストップモーションで再生しているかのように動作させる事もできます。
指定の仕方は以下のように、Easingをラッパーして第一引数に停める頻度?を設定するようです。

transform.DOMoveX(4, 1).SetEase(EaseFactory.StopMotion(5, Ease.InOutQuint));

イマイチ使いどころが分からないんですが、取り合えずEase.Linerについて比較してみます。

確かにTweenが途切れ途切れで再生されるような感じですが、EaseFactory.StopMotionの第一引数は「停める回数」の指定ではないようで、値を大きくすれば止まる回数は多くなりますが、値の回数分止まるわけではありませんでした

3を指定したら3回止まるわけではない。

う~ん、やっぱり使いどころが分からない。この機能を使った良いアイデアがある方はぜひご教授下さい。


【アセット紹介】現状では最速?のTweenアセット「LitMotion」

不慣れ

左手デバイスのボタンを右手で押してる不器用な皆さんこんにちは。購入して一週間以上経ちますが未だに不慣れで、ショートカットを登録したボタンを探す→右手でボタンを押す、の順で操作しており私の左手はちっとも活躍していません。まぁUnityでマウス操作をしながらキーを押す、というシチュエーションがあまり無い所為でもありますが。

 

フリーライドとリスペクトの間

フロムゲーが「ソウルライク」という名の下に多数の(特にインディー系の)ゲームから模倣されているように、ポケモンにおいても「ライク」としてカテゴライズされて一般化していれば、たとえ模倣の度合いが過ぎても大騒ぎには発展しなかったかもしれません。
しかし残念ながらこれまで「類似」とされてきたゲームの殆どが躓くか一時的なヒットに終わって「ライク」化するまでに至っていないので、今回のように「ぼくのかんがえたさいこうのポケモン」的ゲームが批判されるのは仕方のない事だなと思っています。

特に「ポケモン」に対して思い入れのあるファンにとっては、いくら制作側が「法的に問題ない」と強弁しても、日本で長らく愛されてきた強いIPをフリーライドしているようにしか見えないでしょうし、「ポケモン」に類似する「パル」に対して強制労働や虐待、殺害が行えるゲームデザインは許せないものでしょう。
私としては「クラフト要素のあるポケモン」「サバイバル要素のあるポケモン」というアイデアを具現化するというだけでもかなり凄い事だと思いますし、元ネタに対しても十分敬意を払っているように感じますが、今回の騒動は制作側がそれを世間一般に理解してもらえる為の努力が足りなかったのかなぁ、という感想です。

 

LitMotion

前回の記事で高速なTween系アセット「Magic Tween」を紹介しましたが、これと同じ作者の方が新しいTween系アセットを公開しています。

annulusgames.com

ECSを使用して高速化を実現した「Magic Tween」よりも更にECSの仕様に合わせて高速化を図ったアセットらしく、公開されたスペックでは「DOTweenの5倍以上、MagicTweenと比較しても1.5倍ほどと極めて高速」のようです。

このアセットの導入に必要な要件は以下の通り

  • Unity 2021.3 以上
  • Burst 1.6.0 以上
  • Collection 1.5.1 以上
  • Mathematics 1.0.0 以上

こちらのアセットもGitで公開されている為、導入する場合はGitURLを利用します。
UnityのWindowメニューからPackageManagerを開いて「+」ボタン > git URLからパッケージを追加してください

https://github.com/AnnulusGames/LitMotion/blob/main/README_JA.md

 

基本的な使い方

MagicTweenではDOTweenとほぼ変わりない使用法でTweenを生成することができましたが、こちらのLitMotionではECSのデータ指向に沿う為か全く違う指定の仕方でTweenを生成します。
具体的には

  1. floatやVector3等の値をTweenさせるMotionクラスを生成する
  2. MotionクラスでTweenされている値(floatやVector3等)の反映先を指定する
  3. LoopやEasing、完了コールバックなどのオプションはMotionの拡張メソッドで設定する

上記の手順でTweenを作成、実行します。
この為、ソースへの記述は以下のようになります。

var value = 0f;
LMotion.Create(0f, 10f, 2f)  // 開始値,終了値,動作時間
    .WithEase(Ease.OutQuad)
    .WithComplete(() => Debug.Log("Complate!"))
    .Bind(x => value = x);

上のソースの「LMotion.Create(0f, 10f, 2f)」の部分が「値をTweenさせるMotion」を意味します。
拡張メソッドの「WithEase」「WithComplete」でEasing、完了コールバックを指定しています。
最後の「Bind」の箇所で「値の反映先を指定」する事になります。
よって上のソースでは「valueの値が2秒で0から10へ変化し、完了後に"Complate!"というログを出力する」という動作となります。

LMotion.CreateでTweenさせる事が出来る変数の型は以下の通りです。

  • int
  • long
  • float
  • double
  • Vector2,Vector3,Vector4
  • Quaternion
  • Color
  • Rect

 

GameObjectを動かしたい

もっと具体的にDOTweenのようにGameObjectを動かしたい場合は、「Bind」の箇所でGameObject.transformのpositionに値を設定する事になります。

Transform target;

LMotion.Create(Vector3.zero, Vector3.one, 2f)
    .Bind(x => {target.position = x;});
上のソースだと「targetの位置を2秒で(0,0,0)から(1,1,1)へ移動させる」という動作になります、
ただ逐一、Bindの中で反映処理を記述するのは面倒くさいので、positionを動かす場合は専用のBindメソッド「BindToPosition」を利用します。

 

Transform target;

LMotion.Create(Vector3.zero, Vector3.one, 2f)
    .BindToPosition(target); // target.positionにバインドする

position以外にもLocalPositionやeularAngle,localScale等、専用のBindメソッドが幾つか用意されているので詳細は作者の方が公開しているドキュメントを確認してください。

annulusgames.github.io

 

注意点

ドキュメント方で作者の方も述べられていますが、高速化に特化して設計されたアセットであるためMagicTweenほどDOTweenと同様の機能を備えているわけではありません

特にSeqneuceは実装されておらず、今後も実装される事はないようなので、Tweenを組み合わせる場合はコルーチンやUniTask等を使用して自力で組み合わせる必要があります。
また、オプションについても残念ながら相対的(Relative)なTweenを指定するオプションはないので、相対的な動作をさせたい場合はそれを踏まえた値を指定するか、Bindの拡張メソッドを作成する事になります。
Bind拡張メソッドについて上記のドキュメントで具体的な実装方法が書かれているので、試しに相対的な移動(RelativeMotion)についてBind拡張メソッドを作ってみました。

 

まとめ

上記のように記述方法がDOTweenとは大きく異なるため、MagicTweenのようにDOTweenから直接的に移行するのは難しいかもしれません。
また、DOTweenと比較して機能は限定的であるため、使いどころ及び実装方法を事前に検討する必要があります。
それでも「DOTweenの5倍以上」というスペックは魅力的ですしドキュメント等も充実している為、これから新規にプロジェクトを起こす際には導入を検討しても良いのではないでしょうか。

【Unity】ハイパフォーマンスと噂のTweenアセット「MagicTween」を触ってみた

Reddit

海外ではXやらインスタよりもメジャーだと聞いて自作ゲームの宣伝のために導入したものの一切活用できていない情報弱者な皆さんこんにちは。無駄に通知だけは毎日受信しているのですが全てのメッセージが英語の為、全く意味が分かりません。誰か助けて。

 

左手デバイス

以前クラファンで購入予定だったもののプロジェクトが停止となり(返金された)、それ以降購入する予定がなかったのですが、ここ最近の怠惰な自分を反省し、ゲーム開発へのモチベーションを上げる為に購入してみました。

 

ack05 ショートカットリモート ワイヤレス接続 or 有線接続両方対応の左手デバイス | XPPen公式ストア

キーボードのショートカットを割り当てたり、一連の操作をマクロ的に実行する事ができるアイテムです。本来はタブレットで絵を描くような方が使用する為のデバイスなんですがUnityでもキーのショートカット割り当てやSceneビューでの拡大縮小の操作を行う事ができます。

これまではTransformのGlobal/Localの切替や、Gameビュー/Sceneビューの切替、空オブジェクトの生成などの操作はゲーム制作内で頻度が高く地味に面倒だったのですが、それらをこのデバイスのキーに割り当てることで作業効率が少し上がった気がします。

「ショートカットなんて覚えれば良いだろう」と言われたらそれまでなんですが、このデバイスなら1グループで10個ほどの操作が割り当てられ、グループを切り替えれば4グループ×10キー程の操作を扱えるので、私のような忘れっぽい方には非常に便利です。

また「どのキーにどの操作を登録したか忘れる」というような方でも、キー用のシールが付属しているのでそれなりに目印になります。
まぁ、Unityを扱う上では必須ではないのですが、有ればそれなりに有用なツールになると思います。

 

MagicTween

これまでTween系のアセットと言えばDOTween一択で使用していたのですが、調べてみると新しいTween系のアセットがソコソコ出回っているようで、その中でも「MagicTween」というアセットはECS(Entity Component System)を使用したTween系アセットらしく、かなりパフォーマンスに優れているらしい。公開されているパフォーマンスの比較を見ても圧倒で気に優れているので導入を検討することにしました。

パフォーマンス比較

このアセットはアセットストアで売られているアセットではなく、有志の方によって作成され、Gitで公開されているアセットです。

その為、導入にはアセットストア経由ではなくGitURLを利用するため、事前にGitをPCにインストールしておきます。

gitforwindows.org

また、ECSを利用するためUnityのPackageManagerから「Entities」を導入しておく必要があります


ちなみにUnityのバージョンはUnity 2022.1以上である事が必須です。

Gitをインストールし、Entitiesを導入したことを確認したらPackageManagerの「Git URL からパッケージを追加」から以下のURLを指定してインストールを行います。

https://github.com/AnnulusGames/MagicTween.git?path=/MagicTween/Assets/MagicTween

 

使い方

作者の方のHPにて詳しく解説されているのでそちらを参考にするのが一番正確なんですが、ザックリ解説するとDOTweenと殆ど同じような 記述形式で使う事ができます

annulusgames.com

例えば移動系のメソッドの場合、DOTweenと同じくtranformの拡張メソッドして使用する事が出来る為

transform.TweenPosition(終了位置, 動作時間);

の記述となり、EasingやRelativeなどのオプション指定はSetterから設定することができます。

transform.TweenPosition(終了位置, 動作時間)
          .SetRelative(true)
          .SetEase(Ease.Liner);

コールバックの指定もDOTweenと殆ど同じです。

transform.TweenPosition(終了位置, 動作時間)
          .SetRelative(true)
          .SetEase(Ease.Liner)
          .OnComplete(コールバック関数);

 

しかし残念ながらPath移動に関して経由地毎のコールバック(OnWaypointChange)は無いようです。
これに関してはPath移動専用のコールバックという事もあり、優先度的に低いと判断されたのかもしれません。

この他にも複数のTweenを登録できるSequenceもDOTweenと同様に使う事ができ、DOTweenではPro版のみの機能であったTextMeshに対するTweenのメソッドも用意されています
各種メソッドやオプションの細かい説明、利用法に関しては有難い事にReadMeも(日本語で)用意されているので、そちらを参考すれば困ることはないと思います。

github.com

注意点

このようにUnity 2022.1以上のバージョンを使っていてEntitiesパッケージの導入に差し障りがなければ、DOTweenからMagicTweenへの移行はパフォーマンス面の利点を考えれば十分検討する価値があると思います。
しかしながら、DOTweenとの挙動の違いは多少存在するようで、前述のOnWaypointChangeコールバックがない事に加えて、任意の値を変更するToメソッドにおいてはOnUpdateのコールバックのみで値を参照すると、Tweenが完了しても目的の値までには達しない、という事が分かりました。

Toメソッドで0から10まで変更→OnUpdateコールバックで参照した場合

 

OnCompleteコールバックでも加えて参照するようにすれば目的の値まで到達することは確認できたので、この辺に関してはDOTweenからそのまま移行する、というわけには行かないようです。

OnUpdateとOnCompleteで参照した場合

 

他にもPath移動のPathの指定によってはDOTweenのPath移動とは少し違う挙動が見受けられたので、DOTweenから完全に移行する前には一度挙動を確認することをお勧めします。

何よりこのアセットは有料のアセットではなく、有志の方によって公開されているアセットです。
作者の方に対して際限ない動作保証や継続的な更新を期待することはお門違いだと思うので、その点を踏まえた上で自己責任で使用される事を願います。

 

宣伝

数学的迷宮脱出ゲーム「W.T.」早期アクセス版リリース中です。

store.steampowered.com

色々と難局に遭遇して牛歩の進みなんですが、製品版リリースに向けて頑張っているので、何卒応援の程、よろしくお願いいたします。

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。