kazumalab tech log

流行りとリラックマと嵐が大好きです。技術的ログ。

カメラワークをUnityで実装する Part1 <ゼルダの伝説シリーズ>

かずまです。

Switchが発売され、スプラトゥーンの試射会も行われ、
ようやく落ち着いた感じがします。

あいかわらずSwitchは台数が少ないみたいで、品薄みたいですね。
ちなみに沖縄のゲオは数台ありました。

今日日曜日も入荷するとか...


さて、今日からシリーズで書いていきたいと思います。

テーマ

今回のシリーズは今流行りの「ゼルダの伝説」を取り上げていきます。
もちろん、開発の方です。

僕はゲームの中で一番と言っていいほどゼルダが大好きなのですが、
何と言ってもゲーム性と操作性、全てに置いて素晴らしいですね。

僕もゼルダの開発に携わりたい、というのが一生の夢ですが、もしかするとゲーム開発が手軽になった今、自分でも近いものが実装できるのでは?
と思ったわけです。(無謀)

今回のお題

"プレイヤーを写すカメラの動き"です。
これはゲームに置いて結構重要なのではないでしょうか。

考察

まずは実際に見てみます。
もちろん僕は実際にプレーもしました。

れいなカメラワークですね。
プレイヤーが中心でその周りをカメラが移動していますね。
常にプレイヤーに向いている感じ。
あとは上下の限界を決めてますね。

実装部分

今回実装する部分の詳細は以下になります。

スティックを倒した時にカメラの回転と高さの変更

天井が低い場所に行った場合のカメラの位置を下げる

カメラワークのリセット

3つになります。
ほんとは移動の常に倒した方向に移動するところとかまで行きたかったけど仕方なく、次回です。

プログラミング & ゲーミング

やりつつ、コード書きつつと言った形でやってみました。

f:id:kazumalab:20170326075502g:plain

こんな感じです。

実装

はじめ、カメラを子オブジェクトにして、それを回転させればできそう!と思って作ってたのですが、高さを変更する時とかバグったため、それは諦めました。

ただし、構造は同じです。
f:id:kazumalab:20170326080057p:plain

カメラに空の親オブジェクトをくっつけて、その親は常にPlayerの座標に位置するというものです。

上のスクリプトをMain Cameraにアタッチします。
そのあとPlayer.csを作成します。
これはPlayerのゲームオブジェクトにくっつけます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour {


	public float HeightToRoof = 0f;
	// Use this for initialization
	void Start () {
	}
	
	// Update is called once per frame
	void Update () {
		HeightToRoof = getHeadHeight ();
	}


	public float getHeadHeight () {
		RaycastHit hit;

		if (Physics.Raycast (transform.position, Vector3.up, out hit)) {
			print ("Found an object - distance: " + hit.distance);
			return transform.position.y + hit.distance;
		}
		return 100f;
	}

これでInspectorのところでターゲットとなるPlayerと、親を入れてあげればOK!

解説

CameraではLookAtを使ってPlayerの方向を向かせています。
これはまぁこれでいいかと思います。

回転部分

回転部分は三角関数を使って計算しています。
入力はGetAxisを使ってますが、場合に合わせて変更してください。

参考はこちら
r-dimension.xsrv.jp

とある角度a(float)に対してのSinはy座標、Cosはx座標となるので半径をrとするととある座標pは

x = r \bullet cos(a)
y = r \bullet sin(a)

これで座標pのx,yが求まりますね。
Cameraは子オブジェクトなのでこの座標をローカル座標に入れて上げることで円形を書いて回転します。

上下の位置を変更する場合は、Verticalの値をそのまま高さにかけてあげます。

自動カメラ下げ

Player.csではRaycastを書いたと思います。
体から上方向にRayを飛ばして、天井との高さを返しています。
あとはカメラのグローバル座標をその高さにするだけです。

リセット

スペースを押せばリセットされるようになっています。
ここの値は強制...してますです。

まとめ

さて、今回はUnityでカメラワークを実装してきました。
本家の方はどうなってるんでしょうね、気になりますが、それなりに上手く行ったと思います。

たぶん、これだとターゲットの部分を変更すると自動的にターゲット変更できるかも...
あと

www.asset.techmatome.com

dtweenとかと組み合わせるといいですね。

次回はプレイヤーの移動に関しての記事を書こうとおもいます。