20200802のUnityに関する記事は5件です。

シンプルなImageEffect その12。HSV調整

TwitterにアップしたHSV調整イメージエフェクトのシェーダコードを貼っておきます。

きっかけはyokotaro氏のツイート
「ニーアらしさとは「Photoshopで彩度を半分にすること」です」
というツイートを見た事。
10個近くImageEffectを投稿してきましたが、そういえばHSVを調整できるイメージエフェクトを作ってなかったですね。。
HSV調整ができれば、ImageEffect上で「ニーアらしさ」を実装できるはず。

手順としては、RGBカラーをHSV(色相、彩度、明度)空間に変換して、調整し再びRGBカラーに戻します。
RGB→HSV、HSV→RGBの変換式についてはググれば山の様に出てきますが、
せっかくなのでUnityEngine.Color.RGBtoHSV()、UnityEngine.Color.HSVtoRGB()のコードを参考にして実装します。
※下記コードで言うとRGBToHSVHelper(),RGBtoHSV(), HSVtoRGB()が参考&修正部分です。

hsv.shader
Shader "ScreenPocket/ImageEffect/HSV"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _HueOffset("Hue Offset", Range(-1,1)) = 0
        _SaturationMultiply("Saturation Multiply", Range(0,2)) = 1
        _SaturationOffset("Saturation Offset", Range(-1,1)) = 0
        _ValueMultiply("Value Multiply", Range(0,2)) = 1
        _ValueOffset("Value Offset", Range(-1,1)) = 0
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            half3 RGBToHSVHelper(
                half offset,
                half dominantColor,
                half colorOne,
                half colorTwo)
            {
                half3 hsv;
                hsv.z = dominantColor;
                if (hsv.z == 0.0)
                {
                    hsv.x = 0;
                    hsv.y = 0;
                    return hsv;
                }

                half num1 = colorOne <= colorTwo ? colorOne : colorTwo;
                half num2 = hsv.z - num1;
                if (num2 != 0.0)
                {
                    hsv.y = num2 / hsv.z;
                    hsv.x = offset + (colorOne - colorTwo) / num2;
                }
                else
                {
                    hsv.y = 0.0f;
                    hsv.x = offset + (colorOne - colorTwo);
                }

                hsv.x /= 6.0;
                if ( hsv.x >= 0.0)
                    return hsv;
                hsv.x += 1.0;
                return hsv;
            }

            half3 RGBtoHSV(half3 rgb)
            {
                if (rgb.b > rgb.g && rgb.b > rgb.r)
                    return RGBToHSVHelper(4.0, rgb.b, rgb.r, rgb.g);
                if (rgb.g > rgb.r)
                    return RGBToHSVHelper(2.0, rgb.g, rgb.b, rgb.r);

                return RGBToHSVHelper(0.0, rgb.r, rgb.g, rgb.b);
            }

            half3 HSVtoRGB(half3 hsv)
            {
                if (hsv.y == 0.0)
                {
                    return hsv.zzz;
                }

                if (hsv.z == 0.0)
                {
                    return half3(0,0,0);
                }

                half num1 = hsv.y;
                half num2 = hsv.z;
                half f = hsv.x * 6.0;
                int num3 = (int)floor(f);
                half num4 = f - (half)num3;
                half num5 = num2 * (1.0 - num1);
                half num6 = num2 * (1.0 - num1 * num4);
                half num7 = num2 * (1.0 - num1 * (1.0 - num4));

                switch (num3)
                {
                case -1:
                    return saturate(half3(num2,num5,num6));
                case 0:
                    return saturate(half3(num2,num7,num5));
                case 1:
                    return saturate(half3(num6,num2,num5));
                case 2:
                    return saturate(half3(num5,num2,num7));
                case 3:
                    return saturate(half3(num5,num6,num2));
                case 4:
                    return saturate(half3(num7,num5,num2));
                case 5:
                    return saturate(half3(num2,num5,num6));
                case 6:
                    return saturate(half3(num2,num7,num5));
                default:
                    return half3(0,0,0);
                }
            }

            half _HueOffset;
            half _SaturationMultiply;
            half _SaturationOffset;
            half _ValueMultiply;
            half _ValueOffset;
            sampler2D _MainTex;

            half4 frag (v2f i) : SV_Target
            {
                half4 col = tex2D(_MainTex, i.uv);
                half3 hsv = RGBtoHSV(col.rgb);

                hsv.x = frac(hsv.x + _HueOffset);
                hsv.y = saturate(hsv.y * _SaturationMultiply + _SaturationOffset );
                hsv.z = saturate(hsv.z * _ValueMultiply + _ValueOffset );

                col.rgb = HSVtoRGB(hsv);
                return col;
            }
            ENDCG
        }
    }
}

ポイントはHSVのH(色相)に関してだけは周期性があるのでsaturate()ではなくfrac()を使っている所でしょうか。
あと、計算式はLDR用に元コードの一部のHDR用if文を端折っていたりします。
※HLSL化した時に面倒くさいので今回からfixedは使わないようにしました。fixed化したい場合は該当箇所を書き換えてください。

_SaturationMultiplyに0.5を入れれば「ニーアらしさ」をリスペクト出来るかと。
他にも色相調整でガラッと雰囲気を変えることも出来るので、色々試してみたいですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TextMeshProを利用し、PixelMplusを綺麗に表示する

概要

タイトル通り、 TextMeshPro を利用して、8bitビットマップふうフォント、 PixelMplus を綺麗に表示する手順についてです。

また、 PixelMplus には、 10ピクセル12ピクセル にそれぞれ BoldRegular と4種類がありますが、今回は 10ピクセルRegular を利用します。

サクッと行けるかと思いましたが、意外と面倒だったので、健忘録として残します。

環境

Unity : 2020.1.0f1
OS : Windows 10
TextMeshPro : 3.0.1

準備概要

前準備としては以下となります。

  1. PixelMplus フォントをダウンロード
  2. Unity のプロジェクトを 2D で作成
  3. UnityPicelMplus を読み込む
  4. UnityTextMeshPro のアセットを追加
  5. Font Asset CreatorFont Asset を作成

利用手順概要

Scene内で行う、実際の大まかな手順は以下となります。

  1. SceneText - TextMeshPro を追加
  2. TextMeshPro コンポーネントの設定
  3. 表示確認

準備

PixelMplus フォントをダウンロード

itouhiroはてなブログさんの記事中程に ダウンロード リンクがあるので、こちらからフォントが入ったzipをダウンロードしましょう。
具体的なファイルは PixelMplus10-Regular.ttf となります。

image.png

Unity のプロジェクトを 2D で作成

他のモードでも行けるかもですが、今回は 2D でプロジェクトを作りました。

image.png

UnityPicelMplus を読み込む

Assets 配下に適当にフォント用フォルダ等を作って、そこに PixelMplus10-Regular.ttf ファイルをドラッグ&ドロップするだけでOKです。

image.png

UnityTextMeshPro のアセットを追加

デフォルトでは TextMeshPro は利用できないので、 PackageManager からパッケージをインストールします。
image.png
Packages: Unity Registry を選択。 TextMeshPro を探して、 Install
image.png

Font Asset CreatorFont Asset を作成

Font Asset Creator のパネルを開く

TextMeshPro のパッケージが追加されると、 Window から関連メニューが開けるようになります。
Font Asset Creator を選択しましょう。
image.png

Font Asset Creator

このようなパネルが表示されます。

image.png

今回は各値を以下のように設定します。

項目 概要 今回設定する内容 設定根拠
Source Font File フォントを設定 PixelMplus10-Regular.ttf
Sampling Point Size 作成するフォントのサイズ Custom Size > 10 フォントが10ピクセルで作成されているため
Packaging Method フォントの生成手続き? Fast Optimumにすると時間がかかってしまいます。おそらく生成時のフォントの綺麗さなどにえいきょうするのではとおもいますす、今回は Fast でも綺麗に出力できました
Padding フォントアトラスでのフォント間の感覚 4 根拠がある数値ではないですが少し幅とっておけば大丈夫かと
Atlas Resolution フォントアトラスを作成する画像の縦横サイズ 512 x 512 フォントサイズやCustom Character List の文字数によって要調整
Charactor Set 対象文字列の指定方法 Custom Characters 今回は漢字は使わないので、直接文字列リストで指定
Select Font Asset 今回は利用しない
Custom Character List 生成する文字列一覧 ※次項記載 使いたい文字を記入
Render Mode Font Atlasの生成モード RASTER にじみを発生させないために。 ちなみに、RASTERの場合フォントサイズがずれてると画像が乱れます。

一通り設定が完了したら、 Generate Font AtlasFont Atlas が生成され、 SaveFont Asset として、保存ができます。

以上で前準備が整いました。
次は、実際Scene内に作成した Font Asset を利用していきます。

Custom Character List

今回、ファミコンっぽいゲームを作りたくてこの手続を進めているため、漢字が不要なので、以下のようなリストで Font Atlas を作成しました。
記号はなんかあると便利そうなので一応入れてます。

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё‐―‘’“”†‡‥…‰′″※‾℃Å←↑→↓⇒⇔∀∂∃∇∈∋√∝∞∠∥∧∨∩∪∫∬∴∵∽≒≠≡≦≧≪≫⊂⊃⊆⊇⊥⌒─━│┃┌┏┐┓└┗┘┛├┝┠┣┤┥┨┫┬┯┰┳┴┷┸┻┼┿╂╋■□▲△▼▽◆◇○◎●★☆♀♂♪♭♯ 、。〃々〆〇〈〉《》「」『』【】〒〓〔〕ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをん゛゜ゝゞァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ・ーヽヾ仝!#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚¢£¬ ̄¥

日本語全体を利用されたい場合は kgsiさんが作成されている、 japanese_full.txt を利用させていただくのが良いかと。

利用手順

SceneText - TextMeshPro を追加

Hierarchy メニューから UI > Text - TextMeshPro を選択。
TextMeshPro のコンポーネントがついた Text が作成されます。

image.png

TextMeshPro コンポーネントの設定

TextMeshPro のコンポーネント配下のようになっています。

image.png

今回はそれぞれ以下のようにせっていしました。
記載してない部分はデフォルト値のままです。

項目 概要 今回設定する内容 設定根拠
Text Input 表示させたい文字
Font Asset Font Asset Creater で作成した Font Asset
Font Size フォントサイズ 10 ピクセルサイズを合わせます。 大きくしたい場合は10の倍数で上げていかないと、ドットの太さなどが揃いません
Spacing Options (em) フォント間のスペース等 Character:10
Line:10
この辺は特に根拠もないので、自身の感覚で適宜幅を決めてください

表示確認

こんな感じになりました。
ドットが綺麗に表示できています。
image.png
ちなみに、 解像度設定を free Aspect にしていると、若干ドットがずれたりする場合があります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity:Debug】端末に繋いでデバッグする

Unity2020で端末に繋いでVSでデバッグする方法

検証:Unity2020.1

ビルドするときに画像の箇所にチェックを入れる
AndroidもiOSも同じ
debugger_02.png

あとはVSでPCで行うときみたいにアタッチするだけなんだけど
アタッチリストに端末が表示されない時があるので画像の「デバッグ > Unityデバッガーのアタッチ」で開くダイアログから繋いでる端末を選択
debugger_01.png

これでブレーク張れるようになるのでデバッグが捗ります

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【習い事レビュー】TECH ACADEMY Unityコース - テックアカデミー ・ユニティーコース-

2019年4月=2019年6月まで、
【TECH ACADEMY Unityコース(三カ月)】(約¥300,000)に関して、
実際私が体験したうえでのレビューを綴ります。
受講を検討されていらっしゃる方のご参考になればと思います。

評価:△
『メンターは良いが……果たしてそれでコスパに見合うのか?』

コースの概要
TECH ACADEMY Unityコース(以後、テックアカデミー またはユニティコース)は、
ゲームエンジン『Unity』に関して短期間・オンラインにて学習を完了させるコースです。
専門学校、専修学校とは違い、履歴書に『大卒』『専門学校卒』という肩書がつくものではありません。
おそらく一般的な学割も適応されません。
(ただし、Adobe Creative Cloud のような開発に必須なツールやアプリは安く買えるかも?)

受講の形態は、まず、専用ウェブサイトに記載されたテキストを学習します。
授業動画視聴ではなく、あくまでもテキストです。これらをこなすのに、一日最低二時間ずつ学習してもひと月半はかかる見込みです。
次に、各トピックの最後に製作課題が与えられ、実際に自らUnityで作ったプロジェクト(編集中のアプリのようなもの)を提出します。
添削して頂けるのは『メンター』と呼ばれる、いわゆる指導役、先生です。
メンターは現役のエンジニアが副業として請け負っている場合が多いようです。
現役の視点で製作物の講評をしてくれます。
トピックは確か10項目。製作物は6つあったかと思います。

コースの特徴
他の法人のオンラインコースを満遍なく受講したわけではありませんが、テックアカデミー独特のコースの特徴は、
・週二回のメンタリング制度
・オリジナルアプリのリリースがゴール
・選べる受講期間
・転職サービス『TECH ACADEMY キャリア』の利用
という点です。

・メンタリング制度について
前述したとおり、メンターは受講者の製作物の講評をしてくださる方です。現役エンジニアの方が多いです。
それに加えて、テックアカデミーでは週に二回、ビデオ通話による【メンタリング】があります。
スカイプのようにリアルタイムで対面して会話を行うことです。
時間は30分です。
いつでも受け付けられてるわけではなく、受講当初に曜日、時間帯を指定し、以後それが固定されます。
注意すべきは、ドタキャン二回で以後、メンタリングを受け付けてもらえなくなる恐れがあることです。
キャンセルは遅くとも前日の内に行うようにしましょう。

このメンタリング制度はすこぶる使えます。
メンターにより当たりはずれはあるでしょうが、私が担当してくださった30歳前後の先生はとても丁寧なご指導をして下さる方でした。
プログラミングに関する質問の他、後述するオリジナルアプリに搭載する機能を相談する際はテックアカデミーの学習外の内容にも関わらず、
またゲーム業界(Unityはゲームエンジンなので、就職先の第一候補がゲーム業界になると思います)
の内情をお尋ねした際も、嫌がらずにお答えいただきました。
(尋ね方にもよるかもしれません)
あなたがどれほど積極的に、または尋ね上手な人であるかによって、テックアカデミーの受講内容以上の成果をこのメンタリングによって得られるかもしれません。
この制度に受講料の大半の価値があるといっても良いでしょう。
(後述しますが、それだけテキスト教材がクソ一歩手前だという裏返しです)

・オリジナルアプリのリリースがゴール
本コースの最終的な目標、課題が『アップルストア、もしくはGoogle Playへのアプリのリリース』となっています。
つまり、スマホアプリとして公開するという事です。
その為の学習基礎と、公開の方法は学習にて身につきます。
私見ですが、Google Play の方が敷居が低くて失敗しにくいです。
最悪、Unityroomなどの無料ゲーム投稿サイトへの投稿でも、可としてくれる場合もあるそうです。
オリジナルアプリをリリースしたという実績は、未経験の方が転職活動の際にある程度優位性があるはずです。(それでも苦労していますが)
企業側も、いまいちどんな会社で何カ月勉強しただけという分かりにくい実績よりも、具体的な製作物を見ていただく方が分かりやすいでしょう。

・選べる受講期間
テックアカデミーでは同じコースであっても人によって受講期間をどれだけ取るか選択できる幅があります。
Unityコースでは、最短で4週間、最長で16週間です。
それによって授業料もかなり変動します。2020年夏現在は、社会人であれば15万円~30万円と二倍のふり幅があります。
ただし、時間からの単価でみれば、長い方が安上がりです。
4週間のプランでは、毎日8時間以上学習してもやり切るのは厳しいかもしれません。
オリジナルアプリの製作にも時間がかかります。
個人的には、就業中の方であれば12週程度をおすすめします。

・転職サイト『TECH ACADEMYキャリア』の利用
テックアカデミーでは専用の転職サイトを持っているようです。
私はあまり活用できていないので、多くは語れませんが、傾向としてはウェブ系・都市部・契約または正社員の求人が多い印象です。

・良い点。ダメな点
 
〇前述したとおり、メンターとメンタリングの制度は充分価値があります。このコースの全てといえるかもしれません。おそらく他のオンライン学習サービスの中でも比較的質は良いと思います。(確約しませんが)
 
〇オリジナルアプリリリースというゴールも、分かりやすく具体的です。もしあなたがそこまで作りこめる自信が無くても、学習を進める内に「こんなアプリを作りたい」と思えるかもしれませんし、最悪、提出した成果物を少しいじった程度の物でも合格できます。本当の最悪は提出できないことで、受講者の半数は提出すらできないそうです。
 ちなみにオリジナルアプリはテックアカデミーのコンテストに投稿できます。おそらく学習を終えた後でも投稿できるので、受講中に受賞することは非常に難しいと思いますが、受賞すれば箔がつくと思います。

△転職サービスは活用しづらい
 というのが私の本音です。というのも、そもそもUnityコースは求人が少なく、限定的でした。業界の傾向ではありますが、都市部限定なので地方出身者からしたらハードルが上がり、求人ラインナップもイマイチな会社が多いので、思い切って飛び込む勇気が持てませんでした。転職を諦めたというわけではなく、まだ力不足と感じたので、別の学習サイト、求人サービスを利用しながらチャンスを狙っています。

△充分な実力がついたとは言い難い
 後述するテキスト教材にも関わりますが、三カ月程度で学習を終えるレベルなので、他の2~4年かけて学習してきた新卒の専門学校生、大学生と比べると力量が見劣りしてしまいます。競争も厳しいでしょう。思い切って転職活動して上手くいくか、またはこのコースを第一歩として、更に学習を続けるか、それとも諦めるかという進路になるかと思います。

×テキスト教材が詐欺まがい
 これには正直がっかりしました。市販されている三千円程度の実用書と大差ない内容です。明らかに料金に見合いません。
 独自の内容と言えば、GitHub、Slackの活用と設定方法。またアプリのリリースの方法でしょうか。
 GitHubは今でも重宝していますが、しかしアプリのリリース方法の解説は、正直不満です。
 リリース直前になってアセットバンドルやら上手くビルドできない不具合が起きても、センターに尋ねる以外のサポートはありません。そのメンタリングも、もうコースの終盤ですのであと2,3回しかないという場合になりがちです。
 説明を端折っているところも見受けられ、Androidでのビルドにおいて、特定の機能を加えなくてはいけないのにその記述がないなど、詰めが甘く感じました。
 また、教材自体が少し古いと感じました。今では改訂されているのでしょうか?

×メンターにおしつけすぎじゃないか?
 前述した通り、このコースの価値の大半はメンターにあるのに、テックアカデミーという会社自体からは後にも先にも具体的なサポートやケアを受けた記憶がありません。営業メールが時々来るぐらいでしょうか? 受講中も簡単なメールのやりとりを数回しただけです。悪い見方をすれば、お金貰ったら後は管理だけといった具合でしょうか。
 受講者の方の中には、質問下手だったり人見知りしたり、たまたまメンターが悪かったりで、メンタリングで充分な恩恵を受けられない可能性もあります。そういった方にはお金をドブに捨てるような講座です。
 反面、このコースをすぐにではないにしろしっかりと活かし、目標を達成する受講者もいらっしゃることでしょう。
 すべてはやる気と運と地頭といったところです。

まとめ
〇 質の良いメンターと週二回のメンタリング
〇 オリジナルアプリリリースという具体的な実績を伴うゴール
△ 転職サービスがイマイチ
✕ テキスト教材はクソ
✕ テックアカデミー自体からのサポートが薄い

結論
『『メンターは良いが……果たしてそれでコスパに見合うのか?』
評価は『△』

と私は結論づけます。
もっと安く学習するなら『Udemy』や『LinkedIn』でも充分かもしれません。
もっと箔をつけたいのなら、『デジタルハリウッド』や、あなたがお若ければ専門学校に入り直したり、夜間や通信コースを取る方がベターかもしれません。
しかし私にとっては、紛れもなくゲーム開発者の第一歩を踏み出せたキッカケであり、学習から一年経ち、今なおゲーム開発を学習し続けても成果が上がっているとは言えませんが、思い切って受講してみて良かったといえるコースだったかなと思います。

最後までお目通しいただきありがとうございました。
ちなみにこのコースを受講した際に私がリリースしたアプリが↓
『Smile Me Baby』
https://play.google.com/store/apps/details?id=com.Company.SmileMeBaby&hl=ja
https://unityroom.com/games/smile_me_baby

最近リリースしたものがこちらです↓
『トレジャークエスト』
https://play.google.com/store/apps/details?id=com.Kabakamon.TreasureQuest&hl=ja
https://unityroom.com/games/treasurequest

もしよろしければお試しいただければと思います。
以上、ありがとうございました。
 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity]UniRxとZenject(Extenject)で実行環境に応じたユーザー操作を監視して自機を動かす

はじめに

Unityの開発ではいろいろと便利なアセットが公開されていますが、そのうちUniRx, Zenjectについて理解を深めておこうと思いました。
わかってはいましたが、これが非常に奥が深く…これはとにかく使ってみないとわからんと思い至り、表題の内容で実際に使ってみたのでその記録を残しておきます。
(個人的な備忘録・頭の整理の側面が強いです)

環境

  • Unity : 2019.3.0f6 64bit
  • UniRx : 6.2.2
  • Zenject(Extenject) : 9.1.0

書いた内容

  • やろうとしたこと
  • やってみたこと
    • Zenjectを用いた動的な入力方法切り替え
    • UniRxを用いた各種操作の監視
  • まとめ

やろうとしたこと

とりあえずこんな感じのシーンをえいやと描いて、自機(真ん中の紙飛行機)を左右に動かしてみようと思いました。
1.jpg
自機を動かす入力方法を以下のように切り分けます。
・Android/iOS端末では画面のボタンで操作
・PCなどではキーボードの左右キーで操作

やってみたこと

Zenjectを用いた動的な入力方法切り替え

何はともあれ(?)以下の記事を何度も読んで、Zenject(今はExtenject)の導入に限らず疎結合な設計とインターフェースについて知見を得ました。

参考:Zenject入門その1 疎結合とDI Container

今回自分がやろうとしていることに当てはめるとこんな感じになりそうです。
2.jpg
・Playerは左右に移動するだけなのでIInputProviderに用意するIFはGetMoveのみ
・タッチ入力とキーボード入力を担当するInputProviderについて環境に応じたものをBindする(Zenject)

上記に追加で調べて対応した内容としては
・同じ型のButton2つをBindする際はIDを指定すれば別々にBindできる
・Monovihaviourでなくてよいクラスは継承を外し、コンストラクタで参照先をBindする
といった点がありました。
コンストラクタインジェクションだと[Inject]アトリビュートおよびusing Zenject;が不要なので、Zenjectなしの環境に対する可搬性が高いです。
(ただしID指定している場合は[Inject(Id = xxx)]表記が必要…)

これでやりたいことはだいたい実現できますが、個人的に少し気になった点がありました。それはPlayerが毎フレーム(Updateのたびに)「そのフレームで左右移動の操作がされているか」をGetしに行くという構図です。
このような構図は様々なところで目にしますが、個人的にPlayerがUpdate関数でポーリングするのではなく、各種操作が実行された際にPlayerを動かすというイベントドリブンな構成にもしてみたいと思いました。

UniRxを用いた各種操作の監視

前述のZenject入門記事を書かれたtorisoupさんのスライドで紹介されている内容を参考に、自分もMVPモデルを意識して構成を見直しました。

参考:UniRxでMV(R)Pパターンをやってみた

・Presenter新規追加
・uGUIボタン・キーボード操作をPresenterが監視し、操作があったらPlayerに反映する
・各種入力および操作はUniRxの仕組みでSubscribeすることで監視下に入る
・InputProviderおよびPlayerはPresenterを参照しない
・Presenterは各種入力およびPlayerを参照する この参照にDIを用いる

こんな感じになりました。
3_2.jpg

前の構成ではIInputProviderというinterfaceがあり、いい感じに動的なBindがされていたのですが…
今回の構成ではInputProvider側で公開するのがIObservableプロパティでありメソッドではないのでinterfaceにできず、Baseクラスという位置づけにしました。

[2020/8/2訂正]
interfaceはプロパティを持つことができるのでIInputProviderのままで実装できました。

あとはクラス図の構成で実装を進め、ZenjectのScene ContextとInstallerを作成して(すみませんこのあたりの詳細は割愛)動作確認です。
4.gif
※Editorですが画像取得のためuGUI入力有効にしてあります

よかった動きました(^^)それにしてもシンプルな…

ソースコードなどはGithubに置いてあります:
https://github.com/zeffy1014/Unity_InputPractice

まとめ

今回の一連の学習では

  • UniRxによる各種操作の監視
  • Zenjectによる動的な監視対象の紐づけ

について軽くかじって咀嚼・消化することができたかなあと思います。幸いアレルギーは出なかったので、この辺りを足がかりにUniRX, Zenjectの他機能についても使えるようになれればと考えています。

ただ注意すべきは、UniRxやZenjectを使うことが目的になってはいけないということで。
何よりもまずはよりよい設計を意識し、それでUniRxやZenjectが必要になったら使うのだぞということを常に頭に置いておこうと思います。

以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む