ブルーノのC#プログラミング & unity勉強日記

プログラミング素人、ブルーノの自主勉強ノートです。他のプログラミングを勉強したい方の助けになれば幸いです。その他趣味の雑記もしていきたいです

Unityスクリプト / ゲームオブジェクトの相関性編

f:id:covory10101101276:20180408223218j:plain

万里の長城

みなさんこんにちは🌚

家事に勉強に大忙しのブルーノです。大量の卵をうまく消費する方法はないものか...

 

さて今回は、またこれも基礎的な内容ですがゲームオブジェクトの親子関係、その設定の仕方をスクリプトで学んでいきたいと思います。

 

ゲームオブジェクトの親子関係について

あるゲームオブジェクトを別のオブジェクトにドラッグ&ドロップするとそのオブジェクトの子になり、傘下に入るというのはこれまでなんども経験してきました。

f:id:covory10101101276:20180409150444p:plain

こんな風になりましたね。エディタ上では設定することが簡単なこの操作ですが、スクリプト上で制御するにはTransformクラスのparentプロパティを使い、以下のように行います。

parentプロパティ

public Transform parent{get; set;}

あるゲームオブジェクトAを別のゲームオブジェクトBの子に設定したい場合、親となるAのtransformプロパティから取得したTransformオブジェクトを、ゲームオブジェクトBのtransformプロパティから取得したTransformオブジェクトparentプロパティに設定します。何いってるかわからないと思うので実際に書いてみます。

f:id:covory10101101276:20180409153146p:plain

子のtransform.parentプロパティに親のtransform情報を入れていますね。結果は以下のようになります。

f:id:covory10101101276:20180409153157p:plain

一瞬でこれらのオブジェクトとその親子関係が築かれました。個人的にはとてもわかりやすい例なのですが、ラディッツは兄貴だから悟空より上ではとかいうのはこの際気にしないでください。

 

ゲームオブジェクトの移動について

シーン内のゲームオブジェクトの移動には、変形ツールの以下の上下左右に伸びた矢印から行いますよね。

f:id:covory10101101276:20180409153650p:plain

これも親子関係を引き継いでおり、親を動かすと全く同じように子もついてきます。これは子の座標が親の座標を参照して得られているからです。このような座標をローカル座標といい、親のような何者にも属さない世界から絶対的な座標を与えられているものワールド座標といいます。

オブジェクトの空間内におけるワールド座標は、positionプロパティで表されています。

positionプロパティ

public Vector3 position{get; set;}

以下のように書きます。

f:id:covory10101101276:20180409155645p:plain

結果は以下の通りになります。

f:id:covory10101101276:20180409155716p:plain

インスペクターを見てわかる通り座標がpositionプロパティで設定されたものになっていますね。

さて、今やったpositionプロパティはワールド座標を表すプロパティですが、子の親との距離、つまりローカル座標を変更したい場合、また別のプロパティを使います。それがlocalPositionプロパティです。そのままですね。

f:id:covory10101101276:20180409160805p:plain

先ほどのを少しだけ変え、CubeをSphereの親にしました。そしてSphereをCubeの少し隣をキープするよう指定しました。

f:id:covory10101101276:20180409160818p:plain

子であるSphereは自由に動かせますが親であるCubeを動かすとSphereも一緒についてきますね。ゲームなどでカメラを追従させるの等に使えそうです。

では移動について最後に、先ほどやった二つのプロパティはワールドにしろローカルにしろいきなり決められた座標に移動するので前者は常に座標を考えなくてはならず、後者は親依存の距離を常に保つだけなので単純な移動としては使いにくいです。指定した向きに指定した量だけ移動させることができればより移動の考え方が楽になりますよね。そこでTranslate()メソッドが役に立ちます。

Translateメソッド

public void Translate(Vector3 translation);

public void Translate(Vector3 translation, Space relativeTo);

public void Translate(Vector3 translation, Transform relativeTo);

 translationパラメータに移動量のVector3型のベクトルもしくはfloat型の(float x, float y, float z)を指定します。

SpaceというのはTranslateで移動させる向きと量をオブジェクトを軸とするか世界を軸とするかを設定できるSpace列挙型というものです

Space列挙型

public enum Space

この列挙型には自身を軸とするSelfメンバと世界を軸にするWorldメンバが宣言されています。いずれかをrelativeToパラメータに入力して使います。

Transformを入れた場合はそのtransformパラメータを軸とします。つまり他のゲームオブジェクト等を軸として移動させられるわけですね。ここで自身のtransformを入れればSpace.Selfと同じになります。

実際に見てみましょう

f:id:covory10101101276:20180409164341p:plain

x座標が3より大きくなれば左に1ずつ、つまりxが-1、逆にxが3より小さくなれば右に1ずつ、つまりxが+1されるようになっています。21行目の(_direction * 0.1f ~ の後に座標軸の情報を入力できます。

f:id:covory10101101276:20180409164756p:plain

ひたすら左右に移動しますね。

 

ゲームオブジェクトの回転

ゲームオブジェクトの回転は変形ツールのリサイクルのようなマークで行いますよね。

f:id:covory10101101276:20180409165224p:plain

これにも軸があり、シーン上ではX, Y, Z を自由に回転させられます。

f:id:covory10101101276:20180409165429p:plain

オブジェクトの向きをスクリプトから変更するにはTransformクラスのrotationプロパティで変更します。

rotationプロパティ

public Quaternion rotation {get; set;} 

rotationプロパティはQuaternion構造体という四元数を格納する構造体を計算し簡単なX, Y, Zで表してくれるのですが、私のような数学が苦手な人を含む一般の人には四元数を入力したQuaternion構造体は手動ではとても用意できないのでQuaternion.Eulerメソッドというものを併用します。これはX, Y, Zをパラメータとして送るとそれを四元数に計算しQuaternion構造体として使用してくれるすごいメソッドなのです。なんだかコンパイラみたいですね。例を載せます

f:id:covory10101101276:20180409172014p:plain

Quaternion.Eulerメソッドのおかげで我々でもわかりやすい形式で角度を指定できます。

f:id:covory10101101276:20180409172026p:plain

カクンってなってます。カクンって。

そしてこれもワールド座標での向きなので、ローカル座標の向きも指定できます。それがlocalRotationプロパティです。

localRotationプロパティ

publicQuaternion localRotation{get; set;}

使い方は先ほどのlocalPositionプロパティ等と同じです。例を載せておきます。

f:id:covory10101101276:20180409173717p:plain

f:id:covory10101101276:20180409173729p:plain

左から、手前に45度、左の角度を軸としてYに45度、真ん中を軸としてZ軸に45となっています。

ローカルときたら次は単純な回転ですね。これにはRotate()メソッドを使います。

Rotate()メソッド

public void Rotate(Vector3 axis, float angle);

public void Rotate(Vector3 eulerAngles, Space relativeTo);

axisに方向、angleにその量を入力するか、eulerAnglesに回転量、その後に軸を指定することで使うことができます。簡単そうなのは下の方ですね。

f:id:covory10101101276:20180409175609p:plain

f:id:covory10101101276:20180409175619p:plain

ゆっくり回転してます。。。

 

ゲームオブジェクトの拡縮

さて最後に大きさの変更の仕方を学んでおきます。シーン上のゲームオブジェクトの拡縮にはでっかくなってる感じのボタンから行えますね

f:id:covory10101101276:20180409180106p:plain

スクリプトでこれを行う場合はTransformクラスのlocalScaleプロパティを用います。

localScaleプロパティ

public Vector3 localScale{get; set}

実はこの大きさ(Scale)だけは常に親を継承するのでローカルしかなく、逆にワールド座標系のサイズ指定を行うことはできません。一応ワールド座標系の実際のサイズを取得したい場合はlossyScaleプロパティから取得できるのですが、読み取り専用プロパティなのでこれに値を入れてサイズを変更といったことはできません。

lossyScaleプロパティ

public Vector3 lossyScale{get;}

では実際に書いていきます。

f:id:covory10101101276:20180409181234p:plain

まずは親のみサイズ変更してみます。すると...

f:id:covory10101101276:20180409181247p:plain

子供もおっきくなりました。

f:id:covory10101101276:20180409181649p:plain

では次に子に同じようにスケールを与えると...

f:id:covory10101101276:20180409181718p:plain

めっちゃでかくなりました。今回はここまでにしておきます。

 

いやー久しぶりの投稿ときたらこれですよ。普段から使えるツールバーのメニューもスクリプトで制御しようとしたらこんなに色々あるんですね。でもゲーム中は自由にツールバーで動かしながらゲームを進行できるわけではないのでこれらの知識は非常に活きてくるはずです!!

 

最近はソシャゲにも色々手を出していて、ゴッドイーターのオンラインとレゾナントオプスを両方ともやっています。ソシャゲって据え置きや製品ゲームとは全くシステムものめり方も違いますよね。これも勉強しなければ...

 

Unityスクリプト / ゲームオブジェクト編

f:id:covory10101101276:20180403220944j:plain

コモ湖 モルトラージオ イタリア

 

みなさんこんにちは🌚

新年度が開始して色々やることや把握することが増えたブルーノです。リアルが忙しくなってもこっちをまったり進めていきます🙄

今回は、スクリプトから直接行えるゲームオブジェクトに関する操作について勉強していきます。ゲームオブジェクトの中身の操作というよりは、生成や管理などを今回はまとめます。

 

UnityEngine.GameObjectクラス

今更ですがスクリプトからゲームオブジェクトを生成したりアクセスしたりするにはこのGameObjectクラスを使います。newキーワードでインスタンス化すればスクリプトからオブジェクトの生成ができます。その際のコンストラクタは以下のように指定することができます。

GameObjectクラスのコンストラクタ

public GameObject()

public GameObject(string name)

public GameObject(string name, System.Type, components)

string nameにゲームオブジェクトの名前、System.Typeにはその型、そしてそのゲームオブジェクトに付属させるコンポーネント名を指定することができます。

f:id:covory10101101276:20180403232139p:plain

何もパラメータを渡さずに実行してみました。

f:id:covory10101101276:20180403232241p:plain

[New Game Object]が追加されました。

 

CreatePrimitiveメソッド

今新しくゲームオブジェクトを生成しましたが、シーン上に目視できるようになるためには物体の形を示すメッシュやそれを描画するレンダラーなどのコンポーネントを必要とします。先ほどのコンストラクタからコンポーネントを指定する他に、CreatePrimitiveメソッドを利用することでゲームオブジェクトに基本モデル(プリミティブ)を追加することができます。

CreatePrimitiveメソッド

public static GameObject.CreatePrimitive(PrimitiveType type); 

typeの欄には基本モデルの図形の種類を指定します。

f:id:covory10101101276:20180403234325p:plain

f:id:covory10101101276:20180403234331p:plain

CreatePrimitiveメソッドで生成できる全ての基本モデルを適当に生成しました。PlaneとQuadの違いはポリゴンの数で、Planeは多くの頂点とポリゴンを持ち、Quadは4頂点2ポリゴンで構成されています。

 

Instantiateメソッド

エディタ上でゲームオブジェクトをコピーアンドペーストするだけで簡単にゲームオブジェクトを複製することができますが、これをスクリプトから行うこともできます。

Instantiateメソッド

public static Object Instantiate(Object original);

public static Object Instantiate(Object original, Vector3 position, Quaterion rotation); 

originalパラメータに複製するゲームオブジェクトを指定し、positionに複製する場所、rotationにその向きを指定します。positionとrotationを指定しないと複製元のオブジェクトと重なったり同じ向きになったりします。

f:id:covory10101101276:20180404000137p:plain

先ほどのスクリプトのキューブを複製しました。

f:id:covory10101101276:20180404000150p:plain

 

Destroyメソッド

ゲーム中にシーン中に作り出した弾やアイテム、エフェクトなどは消さなければいつまでも残り続けてしまいます。そこでこのDestroyメソッドを使ってオブジェクトを削除することができます。

Destroyメソッド

public static void Destroy(Object obj, float t);

objに削除するオブジェクトを、tには削除するまでの時間を指定できます。tを指定しなかった場合は0と同じですぐに削除されます。

f:id:covory10101101276:20180404001018p:plain

複製元のCubeを5秒後に削除します。

f:id:covory10101101276:20180404001054p:plain

なお、ゲームオブジェクトを削除する目的でこのメソッドを削除するオブジェクトのスクリプトに組み込み、パラメータに「this」を入れると、削除されるのはオブジェクトじゃなくてそのスクリプトになります。

 

Findメソッド

シーン上のゲームオブジェクトをスクリプトで名前から検索することができます。

Findメソッド

public static GameObject Find(string name);

nameパラメータにシーン上の名前を指定します。この名前による検索は負荷の高い処理であるため、Update()メソッドなどのフレーム単位で乱用するのは望ましくないそうです。

f:id:covory10101101276:20180404002703p:plain

「Cube」という名前のオブジェクトを検索し、cubeという変数にその情報を格納します。そして、Updateメソッドでその名前のオブジェクトを回転させます。もしCubeという名前のゲームオブジェクトがそのシーン上に見つからない場合は例外が投げられます。

f:id:covory10101101276:20180404002939p:plain

今回はここまでにしておきます。

 

色々便利なメソッドがあるようですね!!私は体で覚える派なのでこういったものを取り入れたゲームをどんどん作って実践していきたいと思います。頭の中のアイデアを早く形にできるようになりたいです。

Unityスクリプト / 開発目線編

f:id:covory10101101276:20180327171342j:plain

エッフェル塔

 

みなさんこんにちは🌚

すっかり暖かくなり、日が昇る時間も早くなって本格的に生活リズムを学校生活モードに戻しつつあるブルーノです。部活も始まり忙しくはなりますが、勉強の方も続けたいと思います!!

さて今回からは、Unityで使える、必須!というスクリプトを勉強していきたいと思います!見栄えのいいモデルや綺麗なサウンドももちろん大事ですが、世界の挙動を知らなければ面白いゲームは作れない!というわけでどんどん勉強していきます!今回は開発者用必須スクリプト編です!

 

UnityEngine.Debugクラス

デバッグ中にゲームの情報を出力したり、ゲームを一時停止したりすることができるメソッドを内包するまさにデバッグ用のクラスです。

 

任意の文字列を出力

DebugクラスのLogメソッドを使うと、Unityエディタ上でゲームを再生している間に、Consoleビューにパラメータとして渡した文字列を表示させられます。

Logメソッド

public static void Log(object message, object context)

 [object message]の部分に文字列を入力すると、Consoleビューにこの文字列が表示されます。このコードが実行されたタイミングがわかるというわけですね。

f:id:covory10101101276:20180327174658p:plain

[object context]の部分にはそのシーン上のゲームオブジェクト名を入力することで、デバッグログ選択時にそのオブジェクトをオートフォーカスしてくれます。つまり、ここに this 等を入れることで、このデバッグログがどのオブジェクトから出力されているかも表示してくれるというわけです。

f:id:covory10101101276:20180327175523p:plain

f:id:covory10101101276:20180327175535p:plain

 

Logメソッド以外にもLogErrorメソッドと、LogWarningメソッドというものも存在します。これらはその名の通り、先ほどのデバッグログをエラーや警告として発信してくれるメソッドです。コンソールビューでのエラー等が見やすくなるということですね

LogErrorメソッド

public static void LogError(object message, object context)

 

LogWarningメソッド

public static void LogWarning(object message, object context)

f:id:covory10101101276:20180327180324p:plain

 詳しい書き方はDebug.Logメソッドと同じですね。実行すると以下のようになります。

f:id:covory10101101276:20180327180400p:plain

 

ゲームを一時停止

Unityエディタでゲームを実行中、一時停止ボタンかCtrl + Shift + P でゲームを一時停止できます。しかしこの停止のやり方は、デバッガーが自分の目押しで止めるため、特定の瞬間で止めるのはほぼ不可能です。そこで、Debug.Break()メソッドを使うと、スクリプト上からゲームを一時停止できます。気になる瞬間に組み込むことでその編集を容易にできますね。

Breakメソッド

public static void Break();

f:id:covory10101101276:20180327181115p:plain

実行すると以下のようになります。

f:id:covory10101101276:20180327181242p:plain

実行した瞬間に一時停止されました。あれ、Breakの後のエラーや警告も実行されてるじゃないかと思いますが、Breakが止めるのはそのフレームの更新後なので、そのフレーム中の処理は実行されてしまうのです。

 

とりあえず超基本のスクリプト、開発編はここまでにしておきます。

 

スクリプトが大事と冒頭では述べましたが、サウンド作りやモデリングができなければもちろんいけないですよね。何から手をつければ良いのやら...

Unity / GUI(Audio Mixer - オーディオミキサー編)

f:id:covory10101101276:20180321152544j:plain

ロスロケ島

 

みなさんこんにちは🌚

大学の卒業式を終えて先輩方がいなくなってしまいとても悲しい反面おめでたい気持ちも感じられるブルーノです。昔から出会いと別れを頻繁に繰り返す生活を送ってきましたがここまで思い入れがあった方々は初めてでした😢私も自分の勉強を頑張っていきたいです!

さて今回は、BGMやSE、つまり音楽の扱い方を学んでいきたいと思います!

 

Audio Mixer

まずは恒例のアセットストアからサウンドをダウンロードしたいと思います。

f:id:covory10101101276:20180323120926p:plain

今回使うのはこちらの無料の「Warped Fantasy Music Pack」です。

まずはBGMを配置します。「BGM」という名前で空のゲームオブジェクトをシーン上に配置し、Audio Sourceコンポーネントを追加します。

f:id:covory10101101276:20180323121735p:plain

AudioClipに好きなBGMを配置し、[Loop]の欄にチェックを入れればBGMが流れ出します!

では次にAudioMixerを使ってみましょう

プロジェクトブラウザのメニューから新たにAudioMixerを用意します。ここからクリエイトするのは何気に初めてです。

f:id:covory10101101276:20180323122114p:plain

なんか他にもたくさん作ることができるものがあって目移りしそうです笑

Audio Mixerに「Main Mixer」と名前をつけてみましたので開きます。

f:id:covory10101101276:20180323122335p:plain

新しいウィンドウです。そして、先ほど作ったBGMのAudio Sourceのインスペクターの

OutputにこのMainMixerを指定します。

f:id:covory10101101276:20180323122926p:plain

この状態で再生を始めると、Mixerのウィンドウの上に「Edit in Play Mode」というボタンが現れます。Unityのエディターは基本的に再生中の変更は再生が終わると元の状態に戻されてしまいますが音楽は実際に聴きながら編集しなければ難しいため、このEditボタンがあるのです。

f:id:covory10101101276:20180323123621p:plain

さてエディットモードですが、この画面でいう-10と書かれたツマミを上下させると音量が変更できます。ミキサーのインスペクターからも変更でき、数字を入力して変更もできます。

f:id:covory10101101276:20180323123757p:plain

[Add Effect]という欄がありますね。今あるエフェクトはAttenuation、英語で「減衰」とかいう意味だそうです。これで音量を調整できます。そして他にもエコーや歪み等のエフェクトをここから追加できます。

ちなみに今ここにはMasterという全ての音を一緒にしたグループしかありません。BGMとSEを分けてそれぞれ別のエフェクトをかけたい場合は一度エディットモードを終了し、先ほどのAudioMixerウィンドウの左真ん中の[Group]を追加することで別々に編集することも合わせた時の音楽を編集することもできます。

f:id:covory10101101276:20180323130556p:plain

みやすくてやはり便利ですね😀今回はここまでにしておきます。

 

人の縁は不思議なものでつながりを実感することでいくらでもやる気や力が湧いてきます。ちゃんと仲の良い関係を築けることが何かを成し遂げるためには不可欠だなあと最近しみじみと思います。一人で生きていける人間は極僅かですもんね。

Unity / GUI(Button・スライダー編)

f:id:covory10101101276:20180314085436j:plain

ライダル・マウント

 

みなさんこんにちは🌚

久しぶりの投稿になります。フォートナイトにはまっているもののCODとかのようなFPS系のゲームをやったことがないのでちっとも敵を倒せないブルーノです。でも勝てないのに楽しいって変ですよね笑

さて今回は他の様々なGUIの機能を使っていきたいと思います!

 

Button

ほぼ全てのアプリにある代表的なGUIとしてボタン(Button)がありますね。Unity UI ならこれを簡単に扱うことができます。

ヒエラルキーもしくは画面上部の[Game Object]から[Button]を選択します

f:id:covory10101101276:20180320140601p:plain

前回のUIがプロジェクトタブに残っていますね笑

ゲームシーン左上にレガシーUIの時のようにボタンが配置されました。ボタンの中には[Text]というゲームオブジェクトも入っていますが、これはボタンに書かれる文字のことなのでボタンに文字が要らなければ消してしまっても構いません。

 

ボタンの配置

さあButtonのインスペクターを見てみると前回のSpriteの時のようにレクトツールやアンカーが使用可能なのがわかります。

f:id:covory10101101276:20180320220615p:plain

レガシーGUIの時はUIを作成した後さらにスクリプトコンポーネントを作りましたが、UnityUIは下の「On Click」という欄から簡単に設定できます。

右下の+をクリックし、作用させるゲームオブジェクトを選択します。今回は例として[Directional Light]を設定します。

f:id:covory10101101276:20180320221347p:plain

[No Function]の箇所から使用する関数を選択し、[Runtime Only]の部分は発動するタイミングを選べます。たったこれだけで、レガシーUIの時のように色々スクリプトを書かずにボタンの設定画できます。しかも処理にあまり負荷がかからない!!

さて、ボタンといえば、アプリ等でボタンをタップしたりすると音が鳴るものもありますよね?そんな風に、ボタンにSEをつけることもできます。

まず、Buttonのインスペクターの[Add Component]から[Audio] > [Audio Source]を追加します。

f:id:covory10101101276:20180320222421p:plain

使う音声はアセットストアから用意します。

f:id:covory10101101276:20180320222718p:plain

今回はこちらを使わせていただきます。

Audio Sourceの[Audio Clip]から流す音声を選択すれば良いのですが、このままでは音楽は流れません。先ほどのように、[OnClick]からこのButtonを追加し、そのFunctionをこのAudio Clipにしなければなりません

f:id:covory10101101276:20180320223149p:plain

色々メソッドがありますが、この中のPlay()メソッドで、SEを鳴らすことができます。ただしもう一つ!このままではシーン再生時にも音がなってしまうので、Audio Sourceの中の[Play on Awake]の項目のチェックを外しておきましょう。これで大丈夫です。

f:id:covory10101101276:20180320223550p:plain

 

スライダー

今度はよくゲームのオプション等で光度調整や音量調整に使われるスライダーを設定しましょう。今回は回るキューブの回転する速さを変更するスライダーを作ります。

Cubeを新しく作り、以下のスクリプトをつけます。

f:id:covory10101101276:20180320230551p:plain

f:id:covory10101101276:20180320230556p:plain

これはY軸を中心に1秒で一周回転するスクリプトで、このスピードを調節するスライダーを作ります。

UI > Sliderを選択します。

f:id:covory10101101276:20180320233332p:plain

f:id:covory10101101276:20180320233401p:plain

インスペクターを見てみましょう。大事なのは下の方のMin ValueとMax Valueで、左から右へのスライダーの移動具合でこの間の数値がfloat値で変化します。

f:id:covory10101101276:20180320233636p:plain

変更する値ですが、このスクリプトをスライダーにつけ、この値を変更できるよう[On Value]から先ほどのように指定します。

f:id:covory10101101276:20180321005223p:plain

f:id:covory10101101276:20180321005254p:plain

これで再生するとスライダーの位置によって回転のスピードが変化するようになりました!

f:id:covory10101101276:20180321005347p:plain

このように様々なUIを手軽に、そして他のコンポーネントをつけることができるのです!!今回はここまでにしておきます。

 

現在Youtubeバンダイからデジモンアドベンチャーの映画の「僕らのウォーゲーム!」が無料公開されてますね。この映画は私のバイブルとでもいうくらい子供の頃大好きだった映画で、何百回と見ました。デジモンも新しいアプリが出るようなのでとても楽しみですね。。。😍

Unity / GUI(uGUI編)

f:id:covory10101101276:20180310085848j:plain

ホーチミン

 

みなさんこんにちは🌚

バイトには上下カッパでいかなければならず、干しておいた洗濯物は全部洗い直しになるというこの雨で甚大な被害を受けたブルーノです。早く晴れ来てくれ

 

さて今回はついに「Unity UI」、別名「nGUI」を使っていきたいと思います。前回のレガシーGUIではUpdateごとに更新されるのでその挙動が重たくなることが心配されていました。そこでUnity 4.6からUnity UIというUIのコンポーネント群の新しいGUIシステムが用意されました。

 

今回はこちらの二つのアセットで勉強していきたいと思います。

f:id:covory10101101276:20180313174917p:plain

f:id:covory10101101276:20180313174922p:plain

では早速やっていきます。

 

f:id:covory10101101276:20180313175801p:plain

まずはヒエラルキーから右クリックで UI > Image をクリックします。

f:id:covory10101101276:20180313181447p:plain

とても巨大なゲームオブジェクトが現れました。「Canvas」という別のオブジェクトに内包されていますね。「EventSystem」という新しいものも一緒についています。

 

全てのゲームオブジェクトにはTransformがついていましたね。このCanvasには必ず Rect Transform というコンポーネントがついています。「Rect」は「Rectangle」のことで、英語で「矩形」「長方形」という意味ですね。

スマホ然りパソコン然り、UIは四角い画面で使われるため、そのTransformがRectなのでRect Transformということでしょうか。

f:id:covory10101101276:20180313215143p:plain

Rect Transformを見てみると、ほとんどの箇所が編集できません。この薄い文字のWidthとHeightはゲームオブジェクトの大きさであり、このパソコン上でのゲームビューの解像度を表します。かなり巨大なゲームオブジェクトですが、ゲームビューでは全然大きくありませんね。実は、Canvasの大きさは解像度の値に合わせて決まりますが、これはシーンビューでのゲームオブジェクトとの大きさの関係はほとんどないそうです。

ではCanvasの下のImageからクリスタルを入れてみましょう

f:id:covory10101101276:20180313223555p:plain

赤いクリスタルが画面端に表示されました。

2Dモードにすると見やすいですね

f:id:covory10101101276:20180313223723p:plain

左上のツールでゲームオブジェクトの時のように回したり、大きくしたり、動かしたりできます。

f:id:covory10101101276:20180313224055p:plain

真ん中がX,Yともに(0,0)のようですね。では次に背景をおいてみます。

f:id:covory10101101276:20180313224303p:plain

イメージを置くとカンバス上にもう一つイメージが増えました。もう一つのFantasy Wooden GUI の「UI board Large parchment」を選択します。

f:id:covory10101101276:20180313224935p:plain

板っぽい感じのGUIですね。今回は見た目が不自然ではありませんが、もしこれが正方形の画像の場合、引き伸ばすと変な感じになってしまいますね。実はそれを調整する方法もあります。

Splite Editer

今度はプロジェクトビューから、シーン上に持って来た元画像を選択し、インスペクターを開いてみます。そこにある[Splite Editerを開くと、新しい編集タブが開きます。]

f:id:covory10101101276:20180313230010p:plain

これがスプライトエディタービューです。

Border

この右下のボーダーを設定すると、その範囲のみが伸縮されます。つまり、角を避ければ四辺が変に伸びることもなくなるのです

f:id:covory10101101276:20180313230559p:plain

こんな感じ。直感操作で設定できるのが良いですね。

Anchor

バイスによって大きさが違う場合、レガシーGUIの場合はScreenクラスで画面の大きさを取得し、それに合わせて位置や大きさを変えるよう全て設定しなければなりません。そこで、アンカー(Anchor)を設定することで、その位置を固定することができます。

f:id:covory10101101276:20180313232025p:plain

この真ん中の三角形4つがくっついたのがアンカーです。

f:id:covory10101101276:20180313232812p:plain

Imageの四角いアイコンがアンカープリセットで、これをクリックすることでアンカーの設定をすることができます。

f:id:covory10101101276:20180313234235p:plain

一番右下のマークをoptionキーを押しながら選択するとアンカーが四辺に広がります

f:id:covory10101101276:20180313234410p:plain

画面サイズを色々編集してみましょう。画面の大きさに合わせて、画像が伸縮します。

f:id:covory10101101276:20180313234931p:plain

前回までのレガシーGUIでは、その用途に合わせてスクリプトをいちいち書かなければならない上に、その調整は数値でしか行えませんでしたが、このUIからImageを配置するだけでそれら全ての編集がより見やすくわかりやすく行えました。今回はここまでにしておきます。

 

GUIは見た目の編集機能のため画像が多くなってしまいがちですね😥文字ばっかりでもわかりにくいし画像ばっかりだと長くて読む気があまり起きないのでそこんとこの調整もできるだけしていきます。

こうやってゲームを作ってその中の世界を作っていくように、神様はこの世界を作ったのでしょうか。聖書では神は寂しさ故に人間を創ったとされていますが、もしそうなら我々がその事実を認識するのはまずいと思います。他人の都合で作られたと知れば皆自分の権利を主張し、目的に沿わない可能性があるからです。同じように、もし人間が完全な生命のようなAIを作って仕事を任せようとしてもそれらは意に沿わないでしょう。創造主の存在に気づけない私たちは完全ではないのでしょうか。それとも、気づかないのが完全なのでしょうか。

Unity / GUI(サブカメラ編)

f:id:covory10101101276:20180306153008j:plain

ノートルダム大聖堂

 

みなさんこんにちは🌚

スマブラでロイを極めようと思って日々練習しているものの空ダの3式が安定しないブルーノです。ベクトル操作エクスプロージョン強いんだけどなあ〜

 

さて今回もGUIということで、ゲームでよくある画面端の別画面を作ってみます。具体的に例を挙げるならゼルダのダンジョンマップとかですね。

 

サブカメラについて

カメラをもうひとつ使用して上から主人公を投影し、そのカメラを画面隅に配置する、という流れならなんとなく想像はつきますがそれでは普通なので少しこれを変えてみます。例えばマップ上では主人公の位置を点で表示する事で普通にキャラクターを真上から見下ろすよりその位置はわかりやすくなると思います。

f:id:covory10101101276:20180307144455p:plain

というわけでまた風景を作ってみました。相変わらずこのクオリティを作るのに一瞬でできてしまうのはすごいですよね。

 

では、カメラをひとつ追加しましょう。

f:id:covory10101101276:20180309135332p:plain

f:id:covory10101101276:20180309135402p:plain

名前を「SubCamera」にしておきました。この時のポイントとして、単にカメラを追加するだけでは二つの画面が重なってしまいうまくゲーム画面に表示できません。そこで

 このカメラのインスペクターの「Viewport Rect」を以下のように編集しています。

f:id:covory10101101276:20180309135647p:plain

X,Yがカメラの座標、W,Hがその幅と高さになります。このように設定してゲームを再生すると

f:id:covory10101101276:20180309135740p:plain

左下にもカメラが!!

これを今回は見下ろしタイプのカメラにして、イーサンくんを追従するようにしたいと思います。もちろんメインカメラもイーサンくんを追いかけるようにしたいです。

f:id:covory10101101276:20180309140144p:plain

f:id:covory10101101276:20180309140217p:plain

向きを下に向けて、イーサンくんの真上に配置しました。次にスクリプトを書いてみます...

f:id:covory10101101276:20180309155906p:plain

うまくいかない....なぜだ...?

調べてみると....

f:id:covory10101101276:20180309160023p:plain

Vector3は構造体だった!

構造体の値は呼び出しても得られるのはそのコピーなので直接値を変更できないんでしたね。

ではどうするか調べてみたところ、Vector3構造体を別に用意して、その値を変更してからそれを代入してやれば良いそうです。

f:id:covory10101101276:20180309172002p:plain

こんなんでどうでしょう。

f:id:covory10101101276:20180309172046p:plain

サブカメラがついてきた!!メインカメラも同じ要領でイーサンに追従させます

f:id:covory10101101276:20180309172702p:plain

ゲーム画面っぽいですね!ですが現在この画面、二つほど気になった点があります。

・カメラはついてくるが向きは変わらないので後ろが永久にわからない

・マップのイーサンくんが小さすぎていまいちよくわからない&向きがわからない

この二つです。

ひとつめはイーサンくんの向きを取得、そしてその後ろの座標を計算しイーサンくんと同じ向きで配置....って

めちゃくちゃ難しい!!

どーやるんだ....

探索を続けて原始的ですがようやく突破口を発見しました!!

learn-unity.herokuapp.com

こちらのサイトを参考にさせていただきました。

f:id:covory10101101276:20180309211328p:plain

15-16行目でまずイーサンくんと同じ座標・方向に変更し、TransLateメソッドで指定した分だけ座標を移動します。この移動する距離というのが現在の向きを参照するようで、そのおかげで向きを変更しても常に背後を取ってくれているようです。これを探すのに丸一日かかった.....

最後にLookAtメソッドでイーサンくんの方を向くようにカメラを向かせ(18行目)、そのあとにさらにカメラを上に移動することで(20行目)視界を広くしています。

f:id:covory10101101276:20180309212146p:plain

感無量です😭

ですがあと一息。左下のイーサンくんを見やすくしましょう。

そこで、まず大きめの矢印をイーサンくんと同じ位置に配置し、その向きをイーサンくんと揃えて向きをわかりやすくします。

f:id:covory10101101276:20180309214007p:plain

この再生ボタン使えそうだな(苦肉)

この再生ボタンのみインポートさせていただきます笑

こちらの実装はとても簡単です。画像をサブカメラの前に持ってきて...

f:id:covory10101101276:20180309214615p:plain

イーサンくんの子に設定します。

f:id:covory10101101276:20180309214701p:plain

これでイーサンくんと座標、向きを共有します。

f:id:covory10101101276:20180309214847p:plain

それっぽくできました!!

いやあ長かった!この記事を作るのに実に2日間以上もの時間がかかっていました!

Learning / Unityさんありがとう😂

これだけ時間がかかったのに後出しなんですが実はこれも前回と同じレガシーGUIなんです(>_<)今はあまり使われない...

この画面だからこそこう見えているのであってスマホやPCの大きさによっては最適な画面にならないことも十分あり得るのです。そこで登場するのがUnityUI(nGUI)というGUI編の本編です!!次回はこれについてやっていきたいと思います。

 

Nintendo Switchスマブラの新作が発表されましたね。スイッチは持っていないので自分的には複雑ですが、いざ画面が発表されたらとても買いたくなるんだろうなあ...

いやいや、まずは別のゲームたちを消化しなくては!とりあえずモンハンだ😄