うにty生活

UnityChanを生活させたい

カメラ追従+カメラ操作したい #4

#2022/1に更新

三日坊主にならなくてよかった!どうもラブヘイトです
普段は三日坊主なこと多いけど、やっぱりUnityは楽しいから続けられる!

というわけで今回は今まで初期位置で固定だったカメラを追従させたり、
Unitychanの周りをカメラで回ってみたりしていきます

カメラ追従

カメラ追従は何かの記事で「一番手っ取り早いのはキャラクターにカメラをアタッチするだけだよ」、と・・・

早速やってみましたf:id:tubakihimeLoveHate:20180530144055g:plain

んーーこれはちょっと笑
確かに追従しているけど後ろからずっとつけているみたいで変態チックですね

これじゃあ一生UnityChanの顔が見えないじゃないか・・・
ということで調べたらなんとUnityの学習ページに追従のやり方が書いてありました

unity3d.com


英語でしたが日本語訳があって助かりました
そしてきちんと追従しているし、カメラをアタッチしないほうが後々いろいろ変更ができそう!

でもやっぱりいろんな方向からUnityChanを見たいですよね


UnityChanを中心にカメラを操作する

数学はあまり得意ではないですが、試行錯誤の結果作成することができました
今回は、
中心点(x1,z2)座標から円周上の点(x2,z2)を求める式を使います
f:id:tubakihimeLoveHate:20180530152008j:plain

yの値は変化しないため今回はx軸とz軸だけ考えていきます

x2 = x1 + r * cosθ
z2 = z1 + r * sinθ

この式をUnityに当てはめた場合

・(x1,z1) = Unitychanの座標x,z
・r   = カメラとプレイヤーの差 つまりoffset
・θが変化量となります


ただ私はここから時間がかかってしまいました。
offsetをそのまま使っていたことと「度」とラジアンの区別がついていなかったことが原因です。

offsetから半径を求めるには
r(2乗) = x(2乗) +z(2乗)
r(2乗)を関数 Mathf.Sqrt(r)で半径rがわかります

高校生で習いましたね笑
なんでこんなことに気がつかなかったのだろう・・・

やっと半径が求められたところですが、Updateで毎回計算しているのはパソコンが忙しそうなので
rは自分で決めてしまいました笑

//半径
private float r=5;

次にMathf.Sqrt関数を探しているうちに度をラジアンに直さなければ使えないことに気がつきまして
Mathf.Deg2Radを使用しました
これは変数なので (Mathf.Deg2Rad*度) でラジアンの値が求まります


では実際にできたコードがこちらです
引き続きカメラにアタッチするスクリプトに記述していきます

public GameObject player;

private Vector3 offset; 
private Vector3 setPosition;


//半径
private float r=5;
//度
private float deg = 0;
	

// Use this for initialization
void Start () {
	offset = transform.position - player.transform.position;
}
	
// Update is called once per frame
void LateUpdate () {
	if(Input.GetKey(KeyCode.U)){
		deg += 3f;

	}else if(Input.GetKey(KeyCode.T)){
		deg -=3f;

	}

//カメラ座標x計算
setPosition.x = player.transform.position.x +r*  Mathf.Cos(Mathf.Deg2Rad*deg);
//カメラ座標yは計算
setPosition.y = player.transform.position.y + offset.y;
//カメラ座標z計算
setPosition.z = player.transform.position.z +r* Mathf.Sin(Mathf.Deg2Rad*deg);

transform.position = setPosition;
//指定したオブジェクトの方向を向く
transform.LookAt(player.transform);

}
}


気をつけなくてはいけない点
Updateではなく、LateUpdateを使っているというところです
他のUpdate関数が全て終わった後に初めて実行されます
そのため順序がプレイヤー移動→カメラ移動となり、移動したのにカメラが付いていかないということがなくなります


できたのがこちら
f:id:tubakihimeLoveHate:20180530161934g:plain
回るようになった〜〜!

ですが自分はまだ納得できていません
TPS視点はカメラの中央ではなく若干下にキャラクターが写っている方が操作しやすいです(カメラが近づけばこの気持ちがわかるはずです)

Lookat関数では指定したオブジェクトの中心を向くため必ずキャラクターが中心になってしまいます。

そこでUnitychanオブジェクトの子に空のGameObjectを作成し、UnityChanの頭の上くらいに置いてこのオブジェクトにLookatするように設定しました
f:id:tubakihimeLoveHate:20180530161954p:plain


f:id:tubakihimeLoveHate:20180530161947g:plain
いい感じです♪


盛りだくさんの記事になってしまいましたがなんとか追従+キャラクターを中心としたカメラ移動ができるようになりました


今回はてな表記で書いてみましたが、自分的にはコードに色が付いてないのは見づらいので見たまま編集に戻します笑


ではまた