さて、シーンの基礎ができたところで、次はプレイヤーのゲームオブジェクト(廃墟を照らすランタン)を作っていきましょう。
プレイヤーのゲームオブジェクトの作成
まずはプレイヤーのゲームオブジェクトを作成します。ヒエラルキーで右クリック→「空のオブジェクトを作成」を選択し、空のゲームオブジェクトを作ったら
- 名前を「Player」に変更
- タグ、レイヤーをそれぞれ「Player」に変更(←重要!)
してください。なお、タグとレイヤーの設定を忘れたりミスったりすると、あとでエラーが出たり動作がおかしくなるので注意してくださいね。
そうしたら、そのPlayerゲームオブジェクトの子として「ポイントライト」を作り(ヒエラルキーで右クリック→「ライト」→「ポイントライト」)、このライトを非アクティブ状態にしておいてください(インスペクターのゲームオブジェクト名の左のチェックボックスをOFFにする)。
プレイヤーに必要なコンポーネントの設定
次にPlayerゲームオブジェクトに必要なコンポーネントをアタッチしていきます。下の画像のように各コンポーネントをアタッチして設定を行いましょう。
変更する項目が多いですが漏れなく設定するようにしてください。
プレイヤーのC#スクリプト(PlayerController.cs)
そうしたら、次はランタンをマウスで動かせるようにC#スクリプトを書いていきます。プロジェクトの「Scripts」フォルダ内の適当なところに新しいC#スクリプトを作成し、名前を「PlayerController」に変更したら次のスクリプトを書いてください。
using System.Collections; using UnityEngine; [RequireComponent(typeof(Rigidbody2D))] public class PlayerController : MonoBehaviour { public enum Mouse { LEFT, RIGHT, MIDDLE, } [SerializeField] BoxCollider2D mouseTrigger = null; [SerializeField] CircleCollider2D lightTrigger = null; [SerializeField] GameObject lightObj = null; [System.NonSerialized] public bool inputEnabled = true; [System.NonSerialized] public bool onCursor = false; bool lightEnabled = false; bool isDead = false; Vector2 defaultTriggerRangeScale; Rigidbody2D rigidBody2D; GameManager gameManager; void Start() { rigidBody2D = GetComponent<Rigidbody2D>(); gameManager = GameObject.FindGameObjectWithTag("GameController").GetComponent<GameManager>(); //念のため、シーン開始時は光の当たり判定を無効化しておく lightTrigger.enabled = false; } void Update() { if (onCursor && inputEnabled) { if (Input.GetMouseButtonDown((int)Mouse.LEFT)) { SwitchMode(); } Cursor.visible = false; } } void FixedUpdate() { if (onCursor) { Move(); } } void Move() { //スクリーン座標(=画面上のマウスの座標)をワールド座標(=ゲーム内座標)に変換 Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); //そのままだとカメラと同じZ座標になってしまうので位置を調整 mousePosition.z = 0; //移動範囲をカメラの範囲内に制限 Vector3 minPosition = Camera.main.ViewportToWorldPoint(new Vector3(0, 0, 0)); Vector3 maxPosition = Camera.main.ViewportToWorldPoint(new Vector3(1, 1, 0)); mousePosition.x = Mathf.Clamp(mousePosition.x, minPosition.x, maxPosition.x); mousePosition.y = Mathf.Clamp(mousePosition.y, minPosition.y, maxPosition.y); rigidBody2D.MovePosition(mousePosition); } void SwitchMode() { if (lightEnabled) { lightEnabled = false; } else { lightEnabled = true; } lightObj.SetActive(lightEnabled); lightTrigger.enabled = lightEnabled; } public void DestroyPlayer() { inputEnabled = false; onCursor = false; Cursor.visible = true; Destroy(gameObject); } public void Dead() { //複数回呼ばれるのを防止 if (isDead) { return; } else { isDead = true; } inputEnabled = false; onCursor = false; Cursor.visible = true; //↓後でコメントを外す //gameManager.GameOver(); Destroy(gameObject); } //トリガーに何かが入ったときに呼ばれるメソッド void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.CompareTag("Enemy")) { Dead(); } else if (collision.gameObject.CompareTag("Goal")) { //↓後でコメントを外す //gameManager.Clear(); } } //当たり判定にマウスが入った時に呼ばれるメソッド void OnMouseEnter() { if (!onCursor && inputEnabled) { onCursor = true; mouseTrigger.enabled = false; } } }
今回のC#スクリプトの仕様
今回のスクリプトは次のような内容になっています。やや長めのスクリプトですが、特に難しいことはやっていないので、よく読んでもらえればどこでなにをやっているかが分かると思います。
- マウスがPlayerオブジェクトに乗ったことを検知するためにボックスコライダーを使用する。
- 他のゲームオブジェクト(敵やゴール)に接触したことを検知するためにサークルコライダーを使用する。
- マウスがPlayerオブジェクトに乗ったとき、Playerオブジェクトがマウスを追従するようにする。
- 左クリックでライトの点灯・消灯(子オブジェクトのポイントライトの有効化・無効化)を行う。ライト点灯中のみ、サークルコライダーをONにする。
- 点灯中に敵がサークルコライダーに入るとゲームオーバー、ゴールがサークルコライダーに入るとクリア。
C#スクリプトの処理の流れ
一応、処理の流れを書いておくと次のような感じになっています。
- マウスがマウス検知用のトリガーに入ったら(OnMouseEnterメソッド)
- ランタンをマウスの位置に移動させるようにする(Moveメソッド)
- その状態で左クリックを検知したらライトをつけたり消したりする(SwitchModeメソッド)。このとき、オブジェクト検出用のトリガーもONにしたりOFFにしたりする
- オブジェクト検出用のトリガーに敵やゴールのゲームオブジェクトが入ったら(OnTriggerEnterメソッド)、ゲームオーバーにしたりクリアにしたりする
スクリプトのアタッチ&設定
スクリプトを書いたらPlayerオブジェクトにアタッチして、コライダーやポイントライトを登録しましょう(下図)。
これでひとまずランタンを動かせるようになりました。実際にテストプレイして確かめてみましょう。
次のページ→シーンを真っ暗な暗闇にする方法