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

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

【Unity】Observerパターンの構築に役立つMessagePipe

悲哀

例の「年収4万で廃業」の話題を知りインディゲーム開発者としての悲哀を感じるより先にSNSでちょっとした話題になったことを羨ましく感じた狭量な皆さんこんにちは。例の方はゲームリリース時も一部SNSで話題になり、有名なゲーム実況者にも取り上げられていたので「実力不足」云々を嘆く前にSNSでバズる力があることを誇った方が良いと思います。それから開発者でもないただのゲームレビュアーがこの件に関して動画のネタにしているは非常に不快です。

 

Observerパターン

Observerパターンとはデザインパターンの一種で、プログラム内で発生したイベント(事象)を他のオブジェクトへ通知する形で処理が行われます。

Observerパターン

 

近年では通知者(Subject)と受信者(Observer)の1対1もしくは1対多といった直接的な関係を利用するのではなく、両者の間に仲介者(Broker)を置くことで通知者(Subject)と受信者(Observer)がより疎結合の状態となるよう工夫されたPub/Subパターンと呼ばれる手法が多く利用されているようです。

Pub/Subパターン

この場合、各々のモジュールは以下の通りとなります。

  • Publisher」は、発生した事象をBrokerに通知する
  • Broker」は、Publisherから受けた通知をSubscriberへ通知
  • Subscriber」は、Brokerから通知を受信して、それに応じた処理を行う

これによりPublisher、Subscriber双方の仕様相違や更改による影響などは全てBrokerの中で吸収することができるため、より柔軟なメッセージ伝達が可能となります。

 

MessagePipe

このようなパターンの処理をシンプルな記述で実装するには今回紹介する「MessagePipe」を利用する事が最適です。
MessagePipeはUnityで使えるハイパフォーマンスのPub/Subパターンの実装を提供するライブラリで、GitHubにて公開されています。

github.com

ただ、MessagePipeの導入はPackageManagerよりUPM経由で導入すると手早く導入することが出来ます。UnityのメニューからProjectSettingsを開いて、次のようにOpenUPMに対するURLを追加します。



するとPackageManagerから「My Registries」からインストールが利用可能となるので「MessagePipe」を選択します。
注意する点として、MessagePipeはDIライブラリ前提で組まれている為、導入に当たってはVContainerが必要です。また、UniRxも必須なのでそれらが未導入の場合は、PackageManagerの中から「MessagePipe.VContainer」「VContainer」「UniTask」を選び、事前に導入しておいてください。

 

基本的な使い方

簡単な使用例として、キーボードの矢印キーが押下された回数をそれぞれカウントする処理を考えます。


この場合、「Publisher」はキーの入力を受け付けて、そのキーコードをBroker経由で「Subscriber」へ送信します。
Subscriber」は受信したキーコードを判定してキー押下の回数を更新し、画面へ表示します。

 

■Publisher側の処理

Publisherは入力されたキーコードをBrokerに向けて通知するので、そのインターフェースを最初に定義します。
VContainerを利用するのでコンストラクタでそのインターフェースをVContainer側から受け取り、キーコードの送信処理でこのインターフェースを利用します。

using UnityEngine;
using MessagePipe;
using VContainer.Unity;
using System;

public sealed class TestInputEventProvider : ITickable
{
    /// <summary>
    /// MessagePipeへのメッセージ送信用インタフェース
    /// </summary>
    private readonly IPublisher<KeyCode> _inputPublisher;

    public TestInputEventProvider(IPublisher<KeyCode> argPublisher)
    {
        _inputPublisher = argPublisher;
    }

    /// <summary>
    /// 毎フレーム実行
    /// </summary>
    public void Tick()
    {
        if (Input.anyKeyDown)
        {
            // 押下キーコードを取得する
            foreach (KeyCode code in Enum.GetValues(typeof(KeyCode)))
            {
                if (Input.GetKeyDown(code))
                {
                    // メッセージを送信
                    _inputPublisher.Publish(code);
                    break;
                }
            }
        }
    }
}

 

■Subscriber側の処理

SubscriberはBrokerから受信する通知のインターフェースを定義します。SubscriberはMonoBehaviourを継承しますがコンストラクタでの注入を可能にするため[Inject]アトリビュートを付与しておきます。
ISubscriberのSubscribeで受け取り先の関数を定義しています。

using UnityEngine;
using VContainer;
using MessagePipe;
using Cysharp.Threading.Tasks;

public class TestSubscribeCounter : MonoBehaviour
{
    /// <summary>
    /// MessagePipeからのメッセージ受信用インターフェース
    /// </summary>
    [Inject] private readonly ISubscriber<KeyCode> _inputSubscriber;

    // Start is called before the first frame update
    void Start()
    {
        // 入力イベントの受信を開始する
        _inputSubscriber.Subscribe(OnInputEventReceived)
                                .AddTo(this.GetCancellationTokenOnDestroy());
    }
    
    /// <summary>
    /// 入力イベント処理
    /// </summary>
    /// <param name="code"></param>
    private void OnInputEventReceived(KeyCode code)
    {
        // キーコードを判定し、カウンタを更新する
        // 長くなるので割愛
        
    }
}

 

■DIの設定

Publisher,SubscriberともにVContainerにて依存性の注入を行う為、VContainerのLifetimeScopeを定義し、VContainerにPublisher,Subscriberのクラスと「Broker」役となるMessagePipeの登録を行います。

using VContainer;
using VContainer.Unity;
using MessagePipe;
using UnityEngine;

public class TestCountLifetimeScope : LifetimeScope
{
    protected override void Configure(IContainerBuilder builder)
    {
        // MessagePipeの設定
        var options = builder.RegisterMessagePipe();
        builder.RegisterMessageBroker<KeyCode>(options);

        // InputEventProviderを起動
        builder.RegisterEntryPoint<TestInputEventProvider>(Lifetime.Singleton);

        // ヒエラルキー上でTestSubscribeCounterがアタッチされているものを登録
        builder.RegisterComponentInHierarchy<TestSubscribeCounter>();
    }
}

 

Unityのシーン内に空のオブジェクトを作り、前述したLifetimeScopeのコンポーネントをアタッチしておきます。このアタッチされたGameObjectが起点となって「Publisher」「Subscriber」の初期処理が実行されます

 

これらを動作させた結果が以下の動画となります。
キー押下のイベント通知が行われ、UIテキストが更新されているのが分かります。

 

まとめ

MessagePipeを使用するとシンプルな処理で疎結合なObserverパターンが実装できるのが分かりました。
今回は紹介してませんがメッセージのハンドリングは「非同期」にできたり、「多対多」も実現できるようです。
Observerパターンはゲーム製作では結構な頻度で使用するので、MessagePipeの導入と使い方を覚えておいても損はないと思います。

【アセット紹介】プラットフォーム型ゲームで必要な機能が一通りそろった「Platform Project」

Unity1week

気が付けばUnity1weekが終了していいたうっかりものの皆さんこんにちは。今回からは参加はしないものの、投稿されたゲームは沢山遊ぼうと思っていたのですが、福岡インディーゲームEXPOで出展したゲームをアレコレ修正していたらUnity1weekの期間が終わっていました。
上位にランクインした作品を見ると投稿作品のレベルが益々上がっているようで、ゲームとしてバランスよく完成しているものが上位を占めているように感じます。もうそのままアプリとしてストアに出せそうなレベル。ここ数年で小規模インディのレベルがドンドン上がっているので、私も負けずに精進しないといけないですね。

 

指標になりそうなゲーム

前作の「Wo Long」がゲームクリア後即アンインストールしたぐらいプレイが辛かったので、今回は発売日での購入はスルーして同日発売だった別のゲームを購入したのですが、そちらの方が更に遊ぶのが辛くて結局予定より早く購入することになりました。

コーエーテクモゲームスのTeam NINJAが製作に携わったオープンワールドのアクションRPGです。
Team NINJAと言えば「死にゲー」と呼ばれる高難易度アクションゲームを作ることで有名で、前作の「Wo Long」はパリィができないと人権が無いようなゲームでしたが、今作ではその尖った部分が随分とマイルドになっており、「パリィできれば更に楽しい」ぐらいのレベルの難易度です。
また、「仁王」などで見られた攻撃法を「上段・中段・下段」と切り替える必要があった戦闘も、「流派」という概念に残されてはいるものの、そちらも「切り替えられたら楽しい」ぐらい塩梅で、難しい操作を必要とすることなくTeam NINJA製ゲームの持ち味だった高速でスタイリッシュなアクションを楽しむことができます。

高難易度アクションRPGとして一つの到達点にあるエルデンリングが戦技・魔法を使ったスキル合戦による面白さを表現しているのに対し、こちらのゲームではシンプルな操作によるアクションの面白さを追及しており、複雑なコマンドを必要としない最小限の操作で万人が「操作して楽しい」と思えるアクションゲームに仕上がっています。
今後、同じような形のアクションRPGを評価する際の一つ指標になりそうなゲームだと言えるのではないでしょうか。

 

テンプレートアセット

Unityのアセットストアを利用する理由としては、ゲーム製作で必要となる素材の購入や開発が便利になるツールの導入、といったものが挙げられますが、アセットストアでは色んな種類のゲームの基盤として利用できるアセットも販売されています。

例えばアクションゲームを作ろうとする際には、キーボード/ゲームパッドからの入力処理や自機の移動処理、当たり判定、敵の挙動ばかりでなではなく、状況に応じたアニメーションの切り替えや、各種ギミックの動作等々、プログラミングを作り込む必要のあるものが大量に発生しますが、それらを予め用意されたテンプレートを利用して素材を差し替えるだけで済むとすれば、作業工数は削減されゲームの完成はより早いものになると思います。
また、それ(素材を差し替えるだけ)を良しとしない場合でも、ゲームに必要な処理がどのように作り込まれて実装されているのか、を知ることはゲーム開発者として勉強になるし、レベルアップに繋がる事でしょう。

先日購入したのはそう言った意味で非常に有用な3Dのプラットフォーム型ゲームのテンプレートアセットでした。

 

プラットフォーム型ゲームとは文字通り、足場(=プラットフォーム)の上でジャンプすることがゲームプレイに不可欠な要素となるゲームで、その代表作としてスーパーマリオがあげられることが多いですが、このアセットはその3Dバージョン、3Dマリオのようなゲームのテンプレートとなっています。

www.youtube.com

 

Platformer Project

このアセットではゲームのコア部分のみではなく、タイトル画面、ゲームデータのロード画面、ステージセレクト画面といいた製品版として必要な機能のテンプレートも備えている為、それらに対して特に個性的な仕様を加える必要が無ければ、素材を入れ替えるだけでそのまま利用することが出来ます。

データロード画面

ステージセレクトからメインシーンへ

タイトル画面からデータロード画面へ

 

また、用意されている素材も豊富でキャラクターのアニメーション、SE等は別のアセットを追加で購入する必要がないぐらいに用意されています。

アニメーション設定

SEファイル

自機の移動処理、カメラ操作のスクリプトはキー/マウス入力だけでなくゲームパッドも対応している為、これらの処理を作り込む必要はありません。

 

学習の為に

プラットフォーム型ゲームに限らず3Dのアクションゲームでは状況に応じたアニメーションの切り替えも必要となってきます。
歩く→走るだけでなく、水の中に入れば泳ぐアニメーション、柱につかまればよじ登るようなアニメーションの切り替えが必要です。

柱によじ登る

 

プールで泳ぐ

私がこのアセットを購入した大きな理由は、上の動画のようにこのアセットではそれらが既に実装されている為、実際に動かしながらこれらの処理についてのスクリプトを参照して学習する事ができる為です。

これ以外にも、敵に対して正面からぶつかるとダメージを受け、ジャンプして上から叩くと敵を倒せるようになっており、これらについても実装方法を学ぶことができます。

 

注意点

このアセットでは上記の処理についてタグやレイヤーを利用している為、アセットをプロジェクトに導入する際にタグやレイヤーの設定に対して上書きが必要になります。
この為、既に製作途中のゲームのプロジェクトに対してこのアセットを導入する際には注意が必要です。
できれば新規プロジェクトにこのアセットを導入した上でゲーム製作に取り掛かるようにして下さい

【レポート】福岡インディーゲームエキスポ2024に出展した話

D-Pad

インディーゲームの展示会に出展したら大柄な外国人4人に囲まれて展示したゲームについて議論を交わしているけど英語がサッパリなのでオロオロするだけだった英語弱者な皆さんこんにちは。取り合えず十字キーの事をD-Padと呼んでいる事は分かりました。展示したゲームが言葉での説明を必要としないゲームだった為か、外国の方でも楽しんで頂けたようで良かったです。有難うございました。

 

福岡インディーゲームエキスポ2024

というわけで3/23(土),24(日)の二日間にわたって開催された福岡インディーゲームエキスポ2024に出展してきました。

www.fukuoka-indiegame.com


開場がキャナルシティ博多という大きな商業施設という事もあり、開催日両日とも生憎の雨模様だったものの来場者が途切れるという事があまりなく、手が空いて時間を持て余したのは初日の開始一時間と二日目の終了一時間前の時間帯ぐらいでしょうか、おかげさまで配布用に用紙していた紙製のクリアファイルは全て捌ける事が出来ました(一日目で全部配布し終えそうな勢いでした)

 

去年まではアーリーアクセス版の宣伝のために「W.T.」を展示会に出展していたのですが、今回は次回作の製作に向けて市井の方が方々から意見をもらう為に「Under A Groove」のデモ版を出展しました。ノーツが降ってくるようなリズムゲームとは少し趣向を変えて遊べるMV的なリズムアクションゲームとなっています。

youtu.be

全く無名のゲームタイトルなだけに展示会では素通りされるかと不安でしたが、存外にも多くの方に遊んで頂き、狙い通りに様々な意見を頂けて意義のある出展になりました。

特に初日の土曜日にはゲーム好きな方だけでなく、ゲーム実況をされている方、ゲームを制作している方などゲームに対して一家言ありそうな方々が多く来場されていたようで、こちらがプレイした感想を求めると、結構詳細に意見や疑問点を伝えてくれる方が多かった印象です。

そのおかげで自分では気づけなかった問題点や、改良点を知ることが出来ましたし、このゲームに対して私が強み(アピールポイント)だと思っている部分について賞賛頂ける事が多く自信を持つことが出来ました。

なので今回は展示会のレポート言うよりは、試遊された方から頂いた意見や質問などから、私が感じた事、気づいた事について記事に纏めてみたいと思います。

 

パブリックイメージ

上にあげているプレイ動画は初日に頂いた意見を元に応急処置で二日目に間に合いそうな箇所を修正したバージョンのプレイ動画です。
修正した箇所はいずれもゲーム中に起こるイベントで、パブリックイメージ(広く一般に認識されているイメージ)とは異なるリアクションとなっていた為に違和感を訴えられた箇所でした。

 

◆修正点1:正否を表現する色

画面下部の両端からノーツが移動してくるバーはノーツが中央に来るタイミングで色が変わります。
これはボタンを押すジャストのタイミングを表現していますが、当初は画面の背景に青系の色が多い事もあり、視認しやすいように赤系の色に変わるようにしていたのですが、これを「(操作を)間違ったのか?」と戸惑う方が多かったようで「操作の正否が分かりづらい」との意見を頂きました。

多くのゲームではプレイヤーが操作を誤った際のエフェクトには赤系の色が使われているため、赤系の色を見るとNGだと認識される方が多いのだと思います。逆に青、緑系の色はSafeの印象となるので、二日目は緑色の表示に変更しました

 

◆修正点2:ゲームパッドの振動

プレイ動画からは分かりませんが、ボタンを押したタイミングで判定がOKの場合はゲームパッドが振動するように処理を行っていました。

これはこのゲームを作る際に参考にしたゲーム(洋ゲー)がチェックOKの時にパッドが振動するようになっており、私も「操作が正解した」手ごたえを感じる事ができると思い、この仕様を採用したのですが、こちらもパッドが振動するのはミスをした所為だと勘違いされる方が多く、プレイ後に「パッドが振動するのはOKの時?NGの時?」と質問される事が多々ありました。

多くのアクションゲーム等で自機がダメージを受けた際にパッドが振動する為に、このゲームでも同じような認識を持たれたのだと思います。
二日目にはパッドが振動する条件を逆に(誤った時に振動)すると、このような意見を言われる方はいなかったので、こちらの方がパブリックイメージとして浸透しているのだと感じました。

 

ゲームの仕様を決める際にはデザイン的な趣向や制作側の都合よりもパブリックイメージを考えて、遊んでいる方が違和感を感じないような仕様にした方が無用なストレスなく遊んでもらえるという事が分かったので今後の参考にしたいと思います。

 

盲点だった事

展示会開催中での修正は間に合わなかったのですが頂いた意見の中で最も多かった意見は「操作が成功した時のエフェクトを派手にした方が成否が分かりやすい」というものでした。
これは私としては意外な意見で、というのも、このゲームでは操作の正否によって発生するアニメーションが大きく異なるような仕様になっている為です。

操作の成否によるアニメーションの分岐

それでもこのような意見が聞かれるのはどうしてだろう?と自問したところ、「そもそも初見のプレイヤーは正否のアニメーションを知らない」という事に気づきました。つまりOKの場合のアニメーションを見ても、NGの場合のアニメーションを見ても、初見のプレイヤー側はそのアニメーションが「OKを表現しているのか、NGを表現しているのか分からない」という事。

これは気づけば単純な事ですが、制作者として完全に盲点でした。

通常の音ゲーのように「JUST」や「BAD」等の文字ではなくアニメーションの変化でそれを表現しようとしましたが、それだけではプレイヤーに伝わらない、とは言え「(正否を文字表示するのは)ダサいから止めた方が良いですね」とおっしゃる方もいたので、ここら辺はもう少し表現方法を練る必要がある事に気づかされました。

 

他にも途中でゲームコントローラーを表示して十字キーの上にノーツを表示する、ようなイベントの箇所では、ボタンではなく実際にコントローラーの十字キーを押して操作しようとする方もチラホラ見受けられ、ここは「全てがボタン一つで操作可能とするか」「画面の通りにスティック、十字キーも押して操作できるようにするか」悩みどころだと感じました。

感想を下さる方の中でも意見が分かれていたので、対応策はこれから模索していくことになると思います。

 

全体の感想

色々と課題点を上げましたが、試遊して頂いた方の反応はおおむね好評だったと思います。中には手放しで絶賛してくれる方もいて非常に心強い思いになりましたし、小さなお子さんが私のゲームを指さして「これやりたい」と駆け寄って来てコントローラーを手に取ってもらった時は本当に嬉しかったです。

また、今回はいつになく名刺交換をさせて頂く機会が多かったり、周りの出展者の方とも少なからずお話しすることが出来ましたし、空いた時間で遊ぶことも出来ました。(東京で出展した前二回は他のブースに遊びに行くような余裕はなかった)

それにこのブログの読者さんにも声を掛けてもらったりと(嬉しかったです)、非常に実りある出展になったのではないかと思っています。

心残りは一日目の終わりに開催された懇親会に出席できなかった事ですが、これは次回のお楽しみに取っておきたいと思います。

 

来てくださった方々、遊んで下さった方々、

本当に有難うございました!

【告知】福岡インディーゲームエキスポ2024に出展します

香水

満員電車の中で横に並んだオバさんの香水の匂いがきつくて吐きそうになった弱者男性の皆さんこんにちは。あんなのラジカセ担いで爆音で鳴らしているのと同じだからね、あなたの好みが他者の好きとは限らないので匂いのテロは本当に迷惑だと分かって頂きたい。

 

福岡IGE2024

ここ4,5年の間にインディーゲームという存在が広く一般的に認知されてきた影響なのか、全国各地でインディーゲームの出展イベントが開かれるようになりました。
古くからあるデジゲー博の他に、東京ゲームダンジョンやゲームパビリオンjp(大阪)、ぜんため(岐阜)、BITSUMMIT(京都)、INDIE GAME MARKET(仙台)など多々あり、私の地元福岡でも一度2022年に出展イベント(福岡インディーゲームエキスポ)が開かれています。
残念ながら去年は諸般の事情により開催されなかったのですが、今年は早々に福岡インディーゲームエキスポ(福岡IGE)の第2回目の開催が決定しております。

www.fukuoka-indiegame.com

今回は3/23,24の二日間による開催で、しかも福岡を代表する商業施設であるキャナルシティ博多が会場となっています。
出展作品数が40弱と、他のイベントに比べ若干少ない事は否めないのですが、その分、出展する側はアピールするチャンスが多いという事なので、去年東京ゲームダンジョンやデジゲー博に出展した経験を活かし、会場を訪れたお客さんに作品をアピールしたいと思います。

また、上記のリンクでも記載されていますが、ゲーム展示以外にも地元タレントさんや、ゲームクリエイターによるトークショーがあったり、多数のVtuberさんによるゲーム紹介があったりと、ゲーム展示というよりゲーム祭り的な雰囲気のイベントになりそうなので、多くの方に来場してもらい楽しんで頂けたらなぁ、と思っています。

 

Under A Groove

東京ゲームダンジョンやデジゲー博ではSteamでアーリーアクセス版を配信している「W.T.」の展示会用Ver.を出展しました。

store.steampowered.com

福岡インディーゲームエキスポでも当初は「W.T.」を出展する予定だったのですが、前二回の出展で「W.T.」に対するお客さんの大体のリアクションは掴めたので、今回は宣伝を目的とするよりも次回作として試作中のゲームに対する反応を知りたいと思い、新しゲームを出展することにしました。

 

Under A Groove」というタイトルで「シチュエーションをGrooveする 」をゲームコンセプトに一風変わったリズムアクションゲームとなっています。

未だ構想と試作を繰り返している段階でゲームとしてハッキリと仕様が固まってないのですが、今の段階で遊んでもらう事でこのゲームのコンセプトを伝えるために不足しているもの、必要な要素を見つけたいし、このゲームの売りと(私が)考えている部分に思い違いがないか確かめたい、そんな考えで出展を決めました。

 

このゲームについては「Snow Town Under A Groove」というタイトルで今回とは別のバージョンでUnity1Weekに参加したのですが、思うようにコメントをもらう事が出来なかった事も福岡IGEでの出展の要因の一つとなっています。

unityroom.com

なので少し不安もありますが、遊んで頂く以上は楽しんで頂きたいのはゲーム開発者なら誰でも思う事、福岡IGEまでには少しでもブラッシュアップして、より面白いと思ってもらえるようなバージョンに仕上げていくつもりなので、当日参加される方は是非手に取って遊んでみてください!

 

私の出展ブースはNo.16、上の図の場所となっています。周りにはインディゲーム界隈では有名な方も出展されていますが、気後れせずお客さんに声を掛け、この「Under A Groove」を遊んで頂き、配布物を配っていきたいと思います。

 

ちなみに配布物はいつも通り紙製のクリアファイルでデザインは以下のようになっています。

(青枠の部分はクリアファイルの形で実際には印刷されていません)

 

3/23,24 キャナルシティ博多でお待ちしております。

よろしくお願いいたします!

 

 

【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

 

◇プライバシーポリシー

●個人情報の利用目的

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

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

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

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

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

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

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

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

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

●免責事項

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

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

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

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

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

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