今回はプレイヤーの移動に伴うスクロールとカメラの移動を実装してみます。
その前にいくつか下準備をしておきます。
オブジェクトをプレハブ化する
今、<Hierarchy>ウィンドウにいくつかのオブジェクトが並んでいますが、これはプログラミングでいうところのインスタンスのようなものです。
本来クラスがあって、それをインスタンス化してゲーム内にオブジェクトを配置するのがよいはずなので、これらをプレハブ(クラスのようなもの)化しておきます。
<Hierarhy>ウィンドウからそれぞれを<Project>ウィンドウにドラッグ&ドロップします。
<Project>ウィンドウにオブジェクトと同名のアイテムができます。これがプレハブです。以降はこのプレハブをインスタンス化することで、ゲーム内にオブジェクトを配置していきます。
ついでに、<Project>ウィンドウ、[Create][Folder]でそれぞれを種類ごとに分類しておきます。ここでは図のように整理しました。
床を配置する
一回<Hierarchy>ウィンドウからFloorを削除します。
<Project>でFloorプレハブを選び、Transformを下記のように設定しなおします。
Position(x, y, z) = 3, -1.5, 0
Scale(x, y, z) = 10, 1, 5
<Project>からFloorプレハブを、<Hierarchy>あるいは<Scene>にドラッグ&ドロップすると、床がインスタンス化されて表示されます。これを繰り返して、ゲームステージっぽく配置します。
ここでは図のようにしてみました。
プレイヤーを横移動させる
コードを下記のように書き換えます。
// Update is called once per frame
void Update () {
// 右に自動移動する
Vector3 currentVelocity = this.rigidbody.velocity;
currentVelocity.x = 5.0f;
this.rigidbody.velocity = currentVelocity;
// マウスをクリックするとジャンプする
※略
プレイヤーに合わせてカメラを移動させる
ここまでのステップでゲームを再生すると、プレイヤーが画面の右端にすぐに消えてしまいます。これはカメラがプレイヤーを追いかけていないからです。
カメラを制御してプレイヤーを追いかけるようにします。
※他にもプレイヤーが床の側面に張り付いてしまう問題がありますが、これは後で修正します。
“CameraControl”という名前のスクリプトを新規作成し、”Main Camera”プレハブに適用します。コードは下記の通りです。
public class CameraControl : MonoBehaviour {
private GameObject player = null;
// Use this for initialization
void Start () {
// プレイヤーを探しておく
player = GameObject.FindGameObjectWithTag("Player");
}
// Update is called once per frame
void Update () {
this.transform.position = new Vector3(player.transform.position.x,
player.transform.position.y + 1.0f,
this.transform.position.z);
}
}
コード内でタグを頼りに各オブジェクトを探すので、Playerプレハブに”Player”タグを、Main Cameraに”MainCamera”タグを、それぞれ適用しておきます。※参照『二段ジャンプの実装』
ここでゲームシーンを再生してみます。(Web Player版)
確かにカメラがプレイヤーについてきますが、上下にめまぐるしく動いてなんだか落ち着きません。そこで、最後に接地した床を基準にY座標を決めるように処理を変更します。
PlayerControl.cs
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Floor")
{
// ジャンプ回数をリセットする
restJumps = 2;
// 回転角度をリセットする
this.rigidbody.angularVelocity = Vector3.zero;
this.rigidbody.transform.eulerAngles = Vector3.zero;
// カメラ位置の基準フロアをセットする
GameObject mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
mainCamera.GetComponent<CameraControl>().SetCurrentFloor(collision.gameObject);
}
}
CameraControl.cs
public class CameraControl : MonoBehaviour {
private GameObject player = null;
private GameObject currentFloor = null;
// 略
// Update is called once per frame
void Update () {
float diffY = currentFloor.transform.position.y + 2.5f - this.transform.position.y;
float deltaY = diffY / 10;
this.transform.position = new Vector3(player.transform.position.x,
this.transform.position.y + deltaY,
this.transform.position.z);
}
public void SetCurrentFloor(GameObject targetFloor)
{
currentFloor = targetFloor;
}
}
ゲームを再生すると、床の高さに合わせてスムーズに上下にスクロールする様子が確認できるはずです。最初のタイプとどちらが適切かは、ゲームの内容などにもよりますが今回はこれで行くことにします。
mainCamera.GetComponent().SetCurrentFloor(collision.gameObject);
ここでエラー出るんですが・・・
Assets/Scripts/PlayerControl.cs(77,36): error CS0411: The type arguments for method `UnityEngine.GameObject.GetComponent()’ cannot be inferred from the usage. Try specifying the type arguments explicitly
Unity のバージョンは4.03です
コメントありがとうございます。
すみません、記載をミスっていました。
正しくは下記のコードになります。
mainCamera.GetComponent<CameraControl>().SetCurrentFloor(collision.gameObject);
※本文は修正しました。
ありがとうございました!