【Unity実践】#12 プロトタイプ編 ~ ギミックの作成 part1 ~【Boxゲーム】
今回の内容
今回から3回に分けて、ギミック(ドラゴン)の作成を進めます。
まずはドラゴンの見た目の作成から、炎を吐くところまでを作成していきます。
※初めての方はこちらから
⇒ 【第1回記事】この連載について
シーンの追加
新たにシーンを追加します。
GameScene1 を複製して、GameScene3 を作成しましょう。
(プロジェクトビューで GameScene1 を選択して Ctrl + D で複製できます。)
忘れないうちに、Build Setting からシーンを追加しておきましょう。
前回も GameScene1, 2 を追加しましたが、ここに追加しておかないとシーンの切り替えに失敗します。
中段の床および箱の大きさと位置を以下に設定してください。
床
ドラゴンの追加
ドラゴンを追加していきますが、まだアセットは使わないので、Cube と Sphere で以下のようなオブジェクトを作ります。
Cube だけだとどちらが正面かわからないので、Sphere を置いて正面がわかるようにします。
作成手順は以下です。
① Create Empty で空オブジェクトを配置して、名前を Dragon にする
② Cube を ①の Dragon の子オブジェクトにする
③ Sphere を ①の Dragon の子オブジェクトにする
④ Dragon, Cube, Sphere の Transform を調整する
⑤ Sphere に Red_Material を設定する
やってみると気が付くかもしれませんが、ここで大事なことが一点あり、
ドラゴンの正面をローカル座標のZ軸方向としていることに注意してください。
この理由ですが、
Unity では「tranform.forward」でオブジェクトの正面方向のベクトルを取得できるのですが、
その正面と言うのはオブジェクトのZ軸方向と対応しています。
後にスクリプトを書く際に扱いやすいように、この向きを意識してオブジェクトを構成しています。
ほとんどのストアアセットでもZ軸方向が正面となるようにモデルが作成されているので、覚えておくと良さそうです。
最後に、⑤ですが、わかりやすいように Sphere を赤くします。
以前作成した Red_Material をドラッグして Sphere に設定します。
冒頭の画像の様なオブジェクトができていれば完成です。
ドラゴンと言いつつも、この段階では何だかわからないですが・・気にせず進めましょう。
炎の追加
次にドラゴンが吐き出す炎を追加します。
これは最終的には炎のエフェクトを使用しますが、現段階では Cube を引き延ばして赤くしたもので代用します。
先ほどと同様に、Dragon の子オブジェクトとして Cube を追加し、名前を Fire とします。
Sphere と同様に、Fire にも Red_Material を適用しましょう。
これで冒頭の画像と同様のデザインとなるはずです。
最後に、Fire は特定の条件の時に表示する形とするので、デフォルトでは非表示としておきます。
インスペクタービューで名前の横のチェックを外せば完了です。
ドラゴンに炎を吐かせる
まずは対象(プレイヤー)を検知するためのコライダーを設定します。
Dragon に BoxCollider を追加して、以下の設定とします。
以下画像のようなコライダー配置となっていて、ドラゴンの視界を表現しているようなイメージです。
※厳密にやるなら半円系にした方が良いですが、ここでは簡単のため長方形としました。
このあとはスクリプトを使って、設定したコライダーの中にプレイヤーがいれば炎を吐く処理を作成します。
新規でスクリプト「DragonScript」を作成し、以下を記述しましょう。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DragonScript : MonoBehaviour { public GameObject Fire; void Start() { } void Update() { } private void OnTriggerStay(Collider other) { if (other.isTrigger) return; if(other.tag == "Player") { // ターゲット位置 Vector3 targetPos = other.bounds.center; // プレイヤー以外のレイヤマスク int layerMask = ~(1 << other.gameObject.layer); // プレイヤー以外を対象にLinecastして、ヒットするかチェック // ヒットしなければ、炎を吐く if (!Physics.Linecast(transform.position, targetPos, layerMask, QueryTriggerInteraction.Ignore)) { if (!Fire.activeSelf) { Fire.SetActive(true); Invoke("DisableFire", 1.0f); } } } } void DisableFire() { Fire.SetActive(false); } }
そんなに長くはないですが、ここまでの連載では見慣れないコードがあるので以下解説します。
21行目
実体をもつ対象のみを検知するようにしたいので、対象のコライダーがトリガーなら無視するようにしています。
26行目
対象オブジェクトの位置を取得しているだけですが、transform.position で取得すると足元の位置を取得してしまったりします。
対象の中心位置を取得したい時は、(Colliderオブジェクト).bounds.centerで取得できます。
29, 33行目
関連しているので2つの行をまとめて説明します。
先に下の33行目ですが、検知した対象(プレイヤー)の位置まで Linecast(光線)を飛ばして、間に障害物が無いかを調べています。
注意する点として、障害物にはプレイヤーは含まれない、と言う点に気を付ける必要があります。
そこででてくるのが29行目の処理で、プレイヤーのレイヤー以外を対象にしたレイヤーマスクを作成し、
これを Linecast の引数に渡すことで、プレイヤー以外を対象にヒットする光線を生成しています。
35-39行目, 44-47行目
炎を吐いたり、吐きやめたりの処理を実装しています。
35-39行目はさきほどの33行目の判定によって実行されるブロックで、
・炎(Fire)を表示する
・1秒後に炎を非表示にする(メソッドを呼び出す)
この2つの処理を行っています。
そして非表示の際に呼び出されるメソッドが、44-47行目になります。
ここはプロトタイプ段階ではちょっと雑な処理となっているので、アセット編で修正予定です。
=============================
スクリプトの解説はこれくらいにして、続きを実装します。
Dragonオブジェクトに DragonScriptをアタッチしましょう。
続けてヒエラルキービューで、Dragon の DragonScript > Fire に Fireオブジェクトを設定します。
ここまでできたら一度シーンを再生してみましょう。
箱が無くなると、ドラゴンが炎を吐いている事が確認できればOKです。
今回の実装は一旦ここまでとします。
おわりに
次回以降は、
・プレイヤーが炎に触れたらゲームオーバーにする
・ドラゴンをギミックで倒せるように
・プレイヤーがドラゴンに触れたらゲームオーバーにする
・ドラゴンが対象の方向を向くように
これらの処理を実装していきます!
連載目次リンク
関連する連載リンク
© Unity Technologies Japan/UCL