Unityスクリプト / ゲームオブジェクトの相関性編
みなさんこんにちは🌚
家事に勉強に大忙しのブルーノです。大量の卵をうまく消費する方法はないものか...
さて今回は、またこれも基礎的な内容ですがゲームオブジェクトの親子関係、その設定の仕方をスクリプトで学んでいきたいと思います。
ゲームオブジェクトの親子関係について
あるゲームオブジェクトを別のオブジェクトにドラッグ&ドロップするとそのオブジェクトの子になり、傘下に入るというのはこれまでなんども経験してきました。
こんな風になりましたね。エディタ上では設定することが簡単なこの操作ですが、スクリプト上で制御するにはTransformクラスのparentプロパティを使い、以下のように行います。
parentプロパティ
public Transform parent{get; set;}
あるゲームオブジェクトAを別のゲームオブジェクトBの子に設定したい場合、親となるAのtransformプロパティから取得したTransformオブジェクトを、ゲームオブジェクトBのtransformプロパティから取得したTransformオブジェクトのparentプロパティに設定します。何いってるかわからないと思うので実際に書いてみます。
子のtransform.parentプロパティに親のtransform情報を入れていますね。結果は以下のようになります。
一瞬でこれらのオブジェクトとその親子関係が築かれました。個人的にはとてもわかりやすい例なのですが、ラディッツは兄貴だから悟空より上ではとかいうのはこの際気にしないでください。
ゲームオブジェクトの移動について
シーン内のゲームオブジェクトの移動には、変形ツールの以下の上下左右に伸びた矢印から行いますよね。
これも親子関係を引き継いでおり、親を動かすと全く同じように子もついてきます。これは子の座標が親の座標を参照して得られているからです。このような座標をローカル座標といい、親のような何者にも属さない世界から絶対的な座標を与えられているものはワールド座標といいます。
オブジェクトの空間内におけるワールド座標は、positionプロパティで表されています。
positionプロパティ
public Vector3 position{get; set;}
以下のように書きます。
結果は以下の通りになります。
インスペクターを見てわかる通り座標がpositionプロパティで設定されたものになっていますね。
さて、今やったpositionプロパティはワールド座標を表すプロパティですが、子の親との距離、つまりローカル座標を変更したい場合、また別のプロパティを使います。それがlocalPositionプロパティです。そのままですね。
先ほどのを少しだけ変え、CubeをSphereの親にしました。そしてSphereをCubeの少し隣をキープするよう指定しました。
子である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と同じになります。
実際に見てみましょう
x座標が3より大きくなれば左に1ずつ、つまりxが-1、逆にxが3より小さくなれば右に1ずつ、つまりxが+1されるようになっています。21行目の(_direction * 0.1f ~ の後に座標軸の情報を入力できます。
ひたすら左右に移動しますね。
ゲームオブジェクトの回転
ゲームオブジェクトの回転は変形ツールのリサイクルのようなマークで行いますよね。
これにも軸があり、シーン上ではX, Y, Z を自由に回転させられます。
オブジェクトの向きをスクリプトから変更するにはTransformクラスのrotationプロパティで変更します。
rotationプロパティ
public Quaternion rotation {get; set;}
rotationプロパティはQuaternion構造体という四元数を格納する構造体を計算し簡単なX, Y, Zで表してくれるのですが、私のような数学が苦手な人を含む一般の人には四元数を入力したQuaternion構造体は手動ではとても用意できないのでQuaternion.Eulerメソッドというものを併用します。これはX, Y, Zをパラメータとして送るとそれを四元数に計算しQuaternion構造体として使用してくれるすごいメソッドなのです。なんだかコンパイラみたいですね。例を載せます
Quaternion.Eulerメソッドのおかげで我々でもわかりやすい形式で角度を指定できます。
カクンってなってます。カクンって。
そしてこれもワールド座標での向きなので、ローカル座標の向きも指定できます。それがlocalRotationプロパティです。
localRotationプロパティ
publicQuaternion localRotation{get; set;}
使い方は先ほどのlocalPositionプロパティ等と同じです。例を載せておきます。
左から、手前に45度、左の角度を軸としてYに45度、真ん中を軸としてZ軸に45となっています。
ローカルときたら次は単純な回転ですね。これにはRotate()メソッドを使います。
Rotate()メソッド
public void Rotate(Vector3 axis, float angle);
public void Rotate(Vector3 eulerAngles, Space relativeTo);
axisに方向、angleにその量を入力するか、eulerAnglesに回転量、その後に軸を指定することで使うことができます。簡単そうなのは下の方ですね。
ゆっくり回転してます。。。
ゲームオブジェクトの拡縮
さて最後に大きさの変更の仕方を学んでおきます。シーン上のゲームオブジェクトの拡縮にはでっかくなってる感じのボタンから行えますね
スクリプトでこれを行う場合はTransformクラスのlocalScaleプロパティを用います。
localScaleプロパティ
public Vector3 localScale{get; set}
実はこの大きさ(Scale)だけは常に親を継承するのでローカルしかなく、逆にワールド座標系のサイズ指定を行うことはできません。一応ワールド座標系の実際のサイズを取得したい場合はlossyScaleプロパティから取得できるのですが、読み取り専用プロパティなのでこれに値を入れてサイズを変更といったことはできません。
lossyScaleプロパティ
public Vector3 lossyScale{get;}
では実際に書いていきます。
まずは親のみサイズ変更してみます。すると...
子供もおっきくなりました。
では次に子に同じようにスケールを与えると...
めっちゃでかくなりました。今回はここまでにしておきます。
いやー久しぶりの投稿ときたらこれですよ。普段から使えるツールバーのメニューもスクリプトで制御しようとしたらこんなに色々あるんですね。でもゲーム中は自由にツールバーで動かしながらゲームを進行できるわけではないのでこれらの知識は非常に活きてくるはずです!!
最近はソシャゲにも色々手を出していて、ゴッドイーターのオンラインとレゾナントオプスを両方ともやっています。ソシャゲって据え置きや製品ゲームとは全くシステムものめり方も違いますよね。これも勉強しなければ...
Unityスクリプト / ゲームオブジェクト編
みなさんこんにちは🌚
新年度が開始して色々やることや把握することが増えたブルーノです。リアルが忙しくなってもこっちをまったり進めていきます🙄
今回は、スクリプトから直接行えるゲームオブジェクトに関する操作について勉強していきます。ゲームオブジェクトの中身の操作というよりは、生成や管理などを今回はまとめます。
UnityEngine.GameObjectクラス
今更ですがスクリプトからゲームオブジェクトを生成したりアクセスしたりするにはこのGameObjectクラスを使います。newキーワードでインスタンス化すればスクリプトからオブジェクトの生成ができます。その際のコンストラクタは以下のように指定することができます。
GameObjectクラスのコンストラクタ
public GameObject()
public GameObject(string name)
public GameObject(string name, System.Type, components)
string nameにゲームオブジェクトの名前、System.Typeにはその型、そしてそのゲームオブジェクトに付属させるコンポーネント名を指定することができます。
何もパラメータを渡さずに実行してみました。
[New Game Object]が追加されました。
CreatePrimitiveメソッド
今新しくゲームオブジェクトを生成しましたが、シーン上に目視できるようになるためには物体の形を示すメッシュやそれを描画するレンダラーなどのコンポーネントを必要とします。先ほどのコンストラクタからコンポーネントを指定する他に、CreatePrimitiveメソッドを利用することでゲームオブジェクトに基本モデル(プリミティブ)を追加することができます。
CreatePrimitiveメソッド
public static GameObject.CreatePrimitive(PrimitiveType type);
typeの欄には基本モデルの図形の種類を指定します。
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を指定しないと複製元のオブジェクトと重なったり同じ向きになったりします。
先ほどのスクリプトのキューブを複製しました。
Destroyメソッド
ゲーム中にシーン中に作り出した弾やアイテム、エフェクトなどは消さなければいつまでも残り続けてしまいます。そこでこのDestroyメソッドを使ってオブジェクトを削除することができます。
Destroyメソッド
public static void Destroy(Object obj, float t);
objに削除するオブジェクトを、tには削除するまでの時間を指定できます。tを指定しなかった場合は0と同じですぐに削除されます。
複製元のCubeを5秒後に削除します。
なお、ゲームオブジェクトを削除する目的でこのメソッドを削除するオブジェクトのスクリプトに組み込み、パラメータに「this」を入れると、削除されるのはオブジェクトじゃなくてそのスクリプトになります。
Findメソッド
シーン上のゲームオブジェクトをスクリプトで名前から検索することができます。
Findメソッド
public static GameObject Find(string name);
nameパラメータにシーン上の名前を指定します。この名前による検索は負荷の高い処理であるため、Update()メソッドなどのフレーム単位で乱用するのは望ましくないそうです。
「Cube」という名前のオブジェクトを検索し、cubeという変数にその情報を格納します。そして、Updateメソッドでその名前のオブジェクトを回転させます。もしCubeという名前のゲームオブジェクトがそのシーン上に見つからない場合は例外が投げられます。
今回はここまでにしておきます。
色々便利なメソッドがあるようですね!!私は体で覚える派なのでこういったものを取り入れたゲームをどんどん作って実践していきたいと思います。頭の中のアイデアを早く形にできるようになりたいです。
Unityスクリプト / 開発目線編
みなさんこんにちは🌚
すっかり暖かくなり、日が昇る時間も早くなって本格的に生活リズムを学校生活モードに戻しつつあるブルーノです。部活も始まり忙しくはなりますが、勉強の方も続けたいと思います!!
さて今回からは、Unityで使える、必須!というスクリプトを勉強していきたいと思います!見栄えのいいモデルや綺麗なサウンドももちろん大事ですが、世界の挙動を知らなければ面白いゲームは作れない!というわけでどんどん勉強していきます!今回は開発者用必須スクリプト編です!
UnityEngine.Debugクラス
デバッグ中にゲームの情報を出力したり、ゲームを一時停止したりすることができるメソッドを内包するまさにデバッグ用のクラスです。
任意の文字列を出力
DebugクラスのLogメソッドを使うと、Unityエディタ上でゲームを再生している間に、Consoleビューにパラメータとして渡した文字列を表示させられます。
Logメソッド
public static void Log(object message, object context)
[object message]の部分に文字列を入力すると、Consoleビューにこの文字列が表示されます。このコードが実行されたタイミングがわかるというわけですね。
[object context]の部分にはそのシーン上のゲームオブジェクト名を入力することで、デバッグログ選択時にそのオブジェクトをオートフォーカスしてくれます。つまり、ここに this 等を入れることで、このデバッグログがどのオブジェクトから出力されているかも表示してくれるというわけです。
Logメソッド以外にもLogErrorメソッドと、LogWarningメソッドというものも存在します。これらはその名の通り、先ほどのデバッグログをエラーや警告として発信してくれるメソッドです。コンソールビューでのエラー等が見やすくなるということですね
LogErrorメソッド
public static void LogError(object message, object context)
LogWarningメソッド
public static void LogWarning(object message, object context)
詳しい書き方はDebug.Logメソッドと同じですね。実行すると以下のようになります。
ゲームを一時停止
Unityエディタでゲームを実行中、一時停止ボタンかCtrl + Shift + P でゲームを一時停止できます。しかしこの停止のやり方は、デバッガーが自分の目押しで止めるため、特定の瞬間で止めるのはほぼ不可能です。そこで、Debug.Break()メソッドを使うと、スクリプト上からゲームを一時停止できます。気になる瞬間に組み込むことでその編集を容易にできますね。
Breakメソッド
public static void Break();
実行すると以下のようになります。
実行した瞬間に一時停止されました。あれ、Breakの後のエラーや警告も実行されてるじゃないかと思いますが、Breakが止めるのはそのフレームの更新後なので、そのフレーム中の処理は実行されてしまうのです。
とりあえず超基本のスクリプト、開発編はここまでにしておきます。
スクリプトが大事と冒頭では述べましたが、サウンド作りやモデリングができなければもちろんいけないですよね。何から手をつければ良いのやら...
Unity / GUI(Audio Mixer - オーディオミキサー編)
ロスロケ島
みなさんこんにちは🌚
大学の卒業式を終えて先輩方がいなくなってしまいとても悲しい反面おめでたい気持ちも感じられるブルーノです。昔から出会いと別れを頻繁に繰り返す生活を送ってきましたがここまで思い入れがあった方々は初めてでした😢私も自分の勉強を頑張っていきたいです!
さて今回は、BGMやSE、つまり音楽の扱い方を学んでいきたいと思います!
Audio Mixer
まずは恒例のアセットストアからサウンドをダウンロードしたいと思います。
今回使うのはこちらの無料の「Warped Fantasy Music Pack」です。
まずはBGMを配置します。「BGM」という名前で空のゲームオブジェクトをシーン上に配置し、Audio Sourceコンポーネントを追加します。
AudioClipに好きなBGMを配置し、[Loop]の欄にチェックを入れればBGMが流れ出します!
では次にAudioMixerを使ってみましょう
プロジェクトブラウザのメニューから新たにAudioMixerを用意します。ここからクリエイトするのは何気に初めてです。
なんか他にもたくさん作ることができるものがあって目移りしそうです笑
Audio Mixerに「Main Mixer」と名前をつけてみましたので開きます。
新しいウィンドウです。そして、先ほど作ったBGMのAudio Sourceのインスペクターの
OutputにこのMainMixerを指定します。
この状態で再生を始めると、Mixerのウィンドウの上に「Edit in Play Mode」というボタンが現れます。Unityのエディターは基本的に再生中の変更は再生が終わると元の状態に戻されてしまいますが音楽は実際に聴きながら編集しなければ難しいため、このEditボタンがあるのです。
さてエディットモードですが、この画面でいう-10と書かれたツマミを上下させると音量が変更できます。ミキサーのインスペクターからも変更でき、数字を入力して変更もできます。
[Add Effect]という欄がありますね。今あるエフェクトはAttenuation、英語で「減衰」とかいう意味だそうです。これで音量を調整できます。そして他にもエコーや歪み等のエフェクトをここから追加できます。
ちなみに今ここにはMasterという全ての音を一緒にしたグループしかありません。BGMとSEを分けてそれぞれ別のエフェクトをかけたい場合は一度エディットモードを終了し、先ほどのAudioMixerウィンドウの左真ん中の[Group]を追加することで別々に編集することも合わせた時の音楽を編集することもできます。
みやすくてやはり便利ですね😀今回はここまでにしておきます。
人の縁は不思議なものでつながりを実感することでいくらでもやる気や力が湧いてきます。ちゃんと仲の良い関係を築けることが何かを成し遂げるためには不可欠だなあと最近しみじみと思います。一人で生きていける人間は極僅かですもんね。
Unity / GUI(Button・スライダー編)
ライダル・マウント
みなさんこんにちは🌚
久しぶりの投稿になります。フォートナイトにはまっているもののCODとかのようなFPS系のゲームをやったことがないのでちっとも敵を倒せないブルーノです。でも勝てないのに楽しいって変ですよね笑
さて今回は他の様々なGUIの機能を使っていきたいと思います!
Button
ほぼ全てのアプリにある代表的なGUIとしてボタン(Button)がありますね。Unity UI ならこれを簡単に扱うことができます。
ヒエラルキーもしくは画面上部の[Game Object]から[Button]を選択します
前回のUIがプロジェクトタブに残っていますね笑
ゲームシーン左上にレガシーUIの時のようにボタンが配置されました。ボタンの中には[Text]というゲームオブジェクトも入っていますが、これはボタンに書かれる文字のことなのでボタンに文字が要らなければ消してしまっても構いません。
ボタンの配置
さあButtonのインスペクターを見てみると前回のSpriteの時のようにレクトツールやアンカーが使用可能なのがわかります。
レガシーGUIの時はUIを作成した後さらにスクリプトコンポーネントを作りましたが、UnityUIは下の「On Click」という欄から簡単に設定できます。
右下の+をクリックし、作用させるゲームオブジェクトを選択します。今回は例として[Directional Light]を設定します。
[No Function]の箇所から使用する関数を選択し、[Runtime Only]の部分は発動するタイミングを選べます。たったこれだけで、レガシーUIの時のように色々スクリプトを書かずにボタンの設定画できます。しかも処理にあまり負荷がかからない!!
さて、ボタンといえば、アプリ等でボタンをタップしたりすると音が鳴るものもありますよね?そんな風に、ボタンにSEをつけることもできます。
まず、Buttonのインスペクターの[Add Component]から[Audio] > [Audio Source]を追加します。
使う音声はアセットストアから用意します。
今回はこちらを使わせていただきます。
Audio Sourceの[Audio Clip]から流す音声を選択すれば良いのですが、このままでは音楽は流れません。先ほどのように、[OnClick]からこのButtonを追加し、そのFunctionをこのAudio Clipにしなければなりません
色々メソッドがありますが、この中のPlay()メソッドで、SEを鳴らすことができます。ただしもう一つ!このままではシーン再生時にも音がなってしまうので、Audio Sourceの中の[Play on Awake]の項目のチェックを外しておきましょう。これで大丈夫です。
スライダー
今度はよくゲームのオプション等で光度調整や音量調整に使われるスライダーを設定しましょう。今回は回るキューブの回転する速さを変更するスライダーを作ります。
Cubeを新しく作り、以下のスクリプトをつけます。
これはY軸を中心に1秒で一周回転するスクリプトで、このスピードを調節するスライダーを作ります。
UI > Sliderを選択します。
インスペクターを見てみましょう。大事なのは下の方のMin ValueとMax Valueで、左から右へのスライダーの移動具合でこの間の数値がfloat値で変化します。
変更する値ですが、このスクリプトをスライダーにつけ、この値を変更できるよう[On Value]から先ほどのように指定します。
これで再生するとスライダーの位置によって回転のスピードが変化するようになりました!
このように様々なUIを手軽に、そして他のコンポーネントをつけることができるのです!!今回はここまでにしておきます。
現在Youtubeでバンダイからデジモンアドベンチャーの映画の「僕らのウォーゲーム!」が無料公開されてますね。この映画は私のバイブルとでもいうくらい子供の頃大好きだった映画で、何百回と見ました。デジモンも新しいアプリが出るようなのでとても楽しみですね。。。😍
Unity / GUI(uGUI編)
みなさんこんにちは🌚
バイトには上下カッパでいかなければならず、干しておいた洗濯物は全部洗い直しになるというこの雨で甚大な被害を受けたブルーノです。早く晴れ来てくれ
さて今回はついに「Unity UI」、別名「nGUI」を使っていきたいと思います。前回のレガシーGUIではUpdateごとに更新されるのでその挙動が重たくなることが心配されていました。そこでUnity 4.6からUnity UIというUIのコンポーネント群の新しいGUIシステムが用意されました。
今回はこちらの二つのアセットで勉強していきたいと思います。
では早速やっていきます。
まずはヒエラルキーから右クリックで UI > Image をクリックします。
とても巨大なゲームオブジェクトが現れました。「Canvas」という別のオブジェクトに内包されていますね。「EventSystem」という新しいものも一緒についています。
全てのゲームオブジェクトにはTransformがついていましたね。このCanvasには必ず Rect Transform というコンポーネントがついています。「Rect」は「Rectangle」のことで、英語で「矩形」「長方形」という意味ですね。
スマホ然りパソコン然り、UIは四角い画面で使われるため、そのTransformがRectなのでRect Transformということでしょうか。
Rect Transformを見てみると、ほとんどの箇所が編集できません。この薄い文字のWidthとHeightはゲームオブジェクトの大きさであり、このパソコン上でのゲームビューの解像度を表します。かなり巨大なゲームオブジェクトですが、ゲームビューでは全然大きくありませんね。実は、Canvasの大きさは解像度の値に合わせて決まりますが、これはシーンビューでのゲームオブジェクトとの大きさの関係はほとんどないそうです。
ではCanvasの下のImageからクリスタルを入れてみましょう
赤いクリスタルが画面端に表示されました。
2Dモードにすると見やすいですね
左上のツールでゲームオブジェクトの時のように回したり、大きくしたり、動かしたりできます。
真ん中がX,Yともに(0,0)のようですね。では次に背景をおいてみます。
イメージを置くとカンバス上にもう一つイメージが増えました。もう一つのFantasy Wooden GUI の「UI board Large parchment」を選択します。
板っぽい感じのGUIですね。今回は見た目が不自然ではありませんが、もしこれが正方形の画像の場合、引き伸ばすと変な感じになってしまいますね。実はそれを調整する方法もあります。
Splite Editer
今度はプロジェクトビューから、シーン上に持って来た元画像を選択し、インスペクターを開いてみます。そこにある[Splite Editerを開くと、新しい編集タブが開きます。]
これがスプライトエディタービューです。
Border
この右下のボーダーを設定すると、その範囲のみが伸縮されます。つまり、角を避ければ四辺が変に伸びることもなくなるのです
こんな感じ。直感操作で設定できるのが良いですね。
Anchor
デバイスによって大きさが違う場合、レガシーGUIの場合はScreenクラスで画面の大きさを取得し、それに合わせて位置や大きさを変えるよう全て設定しなければなりません。そこで、アンカー(Anchor)を設定することで、その位置を固定することができます。
この真ん中の三角形4つがくっついたのがアンカーです。
Imageの四角いアイコンがアンカープリセットで、これをクリックすることでアンカーの設定をすることができます。
一番右下のマークをoptionキーを押しながら選択するとアンカーが四辺に広がります
画面サイズを色々編集してみましょう。画面の大きさに合わせて、画像が伸縮します。
前回までのレガシーGUIでは、その用途に合わせてスクリプトをいちいち書かなければならない上に、その調整は数値でしか行えませんでしたが、このUIからImageを配置するだけでそれら全ての編集がより見やすくわかりやすく行えました。今回はここまでにしておきます。
GUIは見た目の編集機能のため画像が多くなってしまいがちですね😥文字ばっかりでもわかりにくいし画像ばっかりだと長くて読む気があまり起きないのでそこんとこの調整もできるだけしていきます。
こうやってゲームを作ってその中の世界を作っていくように、神様はこの世界を作ったのでしょうか。聖書では神は寂しさ故に人間を創ったとされていますが、もしそうなら我々がその事実を認識するのはまずいと思います。他人の都合で作られたと知れば皆自分の権利を主張し、目的に沿わない可能性があるからです。同じように、もし人間が完全な生命のようなAIを作って仕事を任せようとしてもそれらは意に沿わないでしょう。創造主の存在に気づけない私たちは完全ではないのでしょうか。それとも、気づかないのが完全なのでしょうか。
Unity / GUI(サブカメラ編)
みなさんこんにちは🌚
スマブラでロイを極めようと思って日々練習しているものの空ダの3式が安定しないブルーノです。ベクトル操作エクスプロージョン強いんだけどなあ〜
さて今回もGUIということで、ゲームでよくある画面端の別画面を作ってみます。具体的に例を挙げるならゼルダのダンジョンマップとかですね。
サブカメラについて
カメラをもうひとつ使用して上から主人公を投影し、そのカメラを画面隅に配置する、という流れならなんとなく想像はつきますがそれでは普通なので少しこれを変えてみます。例えばマップ上では主人公の位置を点で表示する事で普通にキャラクターを真上から見下ろすよりその位置はわかりやすくなると思います。
というわけでまた風景を作ってみました。相変わらずこのクオリティを作るのに一瞬でできてしまうのはすごいですよね。
では、カメラをひとつ追加しましょう。
名前を「SubCamera」にしておきました。この時のポイントとして、単にカメラを追加するだけでは二つの画面が重なってしまいうまくゲーム画面に表示できません。そこで
このカメラのインスペクターの「Viewport Rect」を以下のように編集しています。
X,Yがカメラの座標、W,Hがその幅と高さになります。このように設定してゲームを再生すると
左下にもカメラが!!
これを今回は見下ろしタイプのカメラにして、イーサンくんを追従するようにしたいと思います。もちろんメインカメラもイーサンくんを追いかけるようにしたいです。
向きを下に向けて、イーサンくんの真上に配置しました。次にスクリプトを書いてみます...
うまくいかない....なぜだ...?
調べてみると....
Vector3は構造体だった!
構造体の値は呼び出しても得られるのはそのコピーなので直接値を変更できないんでしたね。
ではどうするか調べてみたところ、Vector3構造体を別に用意して、その値を変更してからそれを代入してやれば良いそうです。
こんなんでどうでしょう。
サブカメラがついてきた!!メインカメラも同じ要領でイーサンに追従させます
ゲーム画面っぽいですね!ですが現在この画面、二つほど気になった点があります。
・カメラはついてくるが向きは変わらないので後ろが永久にわからない
・マップのイーサンくんが小さすぎていまいちよくわからない&向きがわからない
この二つです。
ひとつめはイーサンくんの向きを取得、そしてその後ろの座標を計算しイーサンくんと同じ向きで配置....って
めちゃくちゃ難しい!!
どーやるんだ....
探索を続けて原始的ですがようやく突破口を発見しました!!
こちらのサイトを参考にさせていただきました。
15-16行目でまずイーサンくんと同じ座標・方向に変更し、TransLateメソッドで指定した分だけ座標を移動します。この移動する距離というのが現在の向きを参照するようで、そのおかげで向きを変更しても常に背後を取ってくれているようです。これを探すのに丸一日かかった.....
最後にLookAtメソッドでイーサンくんの方を向くようにカメラを向かせ(18行目)、そのあとにさらにカメラを上に移動することで(20行目)視界を広くしています。
感無量です😭
ですがあと一息。左下のイーサンくんを見やすくしましょう。
そこで、まず大きめの矢印をイーサンくんと同じ位置に配置し、その向きをイーサンくんと揃えて向きをわかりやすくします。
この再生ボタン使えそうだな(苦肉)
この再生ボタンのみインポートさせていただきます笑
こちらの実装はとても簡単です。画像をサブカメラの前に持ってきて...
イーサンくんの子に設定します。
これでイーサンくんと座標、向きを共有します。
それっぽくできました!!
いやあ長かった!この記事を作るのに実に2日間以上もの時間がかかっていました!
Learning / Unityさんありがとう😂
これだけ時間がかかったのに後出しなんですが実はこれも前回と同じレガシーGUIなんです(>_<)今はあまり使われない...
この画面だからこそこう見えているのであってスマホやPCの大きさによっては最適な画面にならないことも十分あり得るのです。そこで登場するのがUnityUI(nGUI)というGUI編の本編です!!次回はこれについてやっていきたいと思います。
Nintendo Switchでスマブラの新作が発表されましたね。スイッチは持っていないので自分的には複雑ですが、いざ画面が発表されたらとても買いたくなるんだろうなあ...
いやいや、まずは別のゲームたちを消化しなくては!とりあえずモンハンだ😄