なぜか自分の中でVTuberのブームが一度も来ません
どうもラブヘイトです
今回は視点操作をマウスで実現したい
PCゲームでマウス視点操なんて当たり前体操なので実装できるようにしていきます
◆現状
今のUnityちゃんはボタンで視点を動かしています
tubakihimelovehate.hatenablog.com
しかし、これでは横軸にしかカメラを動かすことができません
縦軸も対応したいので、
何はともあれやってみよう
Quaternionとか出ませんように...笑
◆マウス視点移動イメージ
実現したい視点移動はもちろんこれですね笑
これは図にするとキャラクターを中心軸として動いている感じがします
◆Unityで配置
図1の通りにUnityで配置するとこんな感じです
空のオブジェクトはこれから「Aimオブジェクト」と呼びます(エイムの意味が違うのは知ってますがわかりやすいので笑)
Aimオブジェクトはわかりやすさのため今はキューブにしてます
完成したらScriptだけの GameObjectに変えましょう!
◆上下視点移動に対応する
マウス視点移動にする前にまだ上下の視点移動が実装されていないので実装しました
前の記事で使った公式と同じようにして縦軸移動を試しましたが、結果ダメでした
思えば縦は360度回転する必要はなかったのです
なのでAimオブジェクトを上下させてそちらにLookAt()する方法に変えました
Aimオブジェクトにアタッチするコード
public class AimController : MonoBehaviour {
public GameObject player;
private Vector3 offset;
private Vector3 setPosition;
private Vector3 moveOffsetY;
//半径
private float r=5;
private float deg = 0;
void Start () {
offset = transform.position + player.transform.position;
moveOffsetY = new Vector3(0,0.3f,0);
}
void LateUpdate () {
//横視点移動
if(Input.GetKey(KeyCode.T)){
deg += 3f;
}else if(Input.GetKey(KeyCode.U)){
deg -=3f;
}
//縦視点移動
if(Input.GetKey(KeyCode.B)){
offset += moveOffsetY;
}
if(Input.GetKey(KeyCode.N)){
offset -= moveOffsetY;
}
setPosition.x = player.transform.position.x -r* Mathf.Cos(Mathf.Deg2Rad*deg);
setPosition.y = player.transform.position.y - offset.y;
setPosition.z = player.transform.position.z -r* Mathf.Sin(Mathf.Deg2Rad*deg);
transform.position = setPosition;
カメラにアタッチするコード
上のコードとそんなに変わりません。計算部分を逆にするだけです
setPosition.x = player.transform.position.x +r* Mathf.Cos(Mathf.Deg2Rad*deg);
setPosition.y = player.transform.position.y + offset.y;
setPosition.z = player.transform.position.z +r* Mathf.Sin(Mathf.Deg2Rad*deg);
transform.position = setPosition;
transform.LookAt(aimObject.transform);
◆マウス視点移動対応
縦の視点移動はoffsetに一定値をプラマイするだけ
どっちも縦と同じでよくね?って思うかもしれませんが、これだとUnityちゃんが画面外に出てしまう可能性があります(FPSなら大丈夫ですが)。なので横視点移動は今まで通りUnityちゃんの中心点から求めていきます
ここからマウスに対応していくには
Input.GetAxis関数でマウス移動した値を取得して計算します
最終的にこんな感じになりました↓
public class AimController : MonoBehaviour {
public GameObject player;
private Vector3 offset;
private Vector3 setPosition;
//ここをfloatに変えました
private float moveOffsetY;
//半径
private float r=5;
private float deg = 0;
//横移動量
float horizontal;
//縦移動量
float vertical;
void Start () {
offset = transform.position + player.transform.position;
}
void LateUpdate () {
//*3fのところを変数にしたら感動設定できる
horizontal = Input.GetAxis("Mouse X")*3f;
vertical = Input.GetAxis("Mouse Y");
//プラマイ変更で移動反転
if(horizontal != 0){
deg -= horizontal;
}
if(vertical != 0){
moveOffsetY -= vertical;
}
setPosition.x = player.transform.position.x -r* Mathf.Cos(Mathf.Deg2Rad*deg);
setPosition.y = player.transform.position.y - moveOffsetY;
setPosition.z = player.transform.position.z -r* Mathf.Sin(Mathf.Deg2Rad*deg);
transform.position = setPosition;
}
}
カメラのY軸は動かさないようにしました
public class CameraConrroller : MonoBehaviour {
public GameObject player;
public GameObject aimObject;
private Vector3 offset;
private Vector3 setPosition;
//半径
private float r=5;
private float deg = 0;
float horizontal;
float vertical;
void Start () {
offset = transform.position - player.transform.position;
transform.position += offset;
}
void LateUpdate () {
//*3fのところを変数にしたら感動設定できる
//*AimControllerと一緒の値にすること
horizontal = Input.GetAxis("Mouse X")*3f;
vertical = Input.GetAxis("Mouse Y");
if(horizontal != 0){
deg -= horizontal;
}
setPosition.x = player.transform.position.x +r* Mathf.Cos(Mathf.Deg2Rad*deg);
setPosition.y = player.transform.position.y + offset.y;
setPosition.z = player.transform.position.z +r* Mathf.Sin(Mathf.Deg2Rad*deg);
transform.position = setPosition;
transform.LookAt(aimObject.transform);
}
}
まさかこんなに簡単なコードになるとは笑
しかも感度と反転にも対応!
では実際に動きを見ていきましょう
いい感じだぁあああ!
感度を調節すればもっと良くなると思います
これで最後に「Aimオブジェクト」をAimCntrollerスクリプトだけのオブジェクトにします
◆比較
fortniteのキャラクターは視点の方に体も向いています
これはUnityちゃんにもAimオブジェクトの方へLookAt()してもらえば実現しますが、問題は縦です笑
この状態でAimオブジェクトを上にあげたら・・・
面白いことになるのは目に見えていますね笑
fortniteは縦視点移動の時は首から上を動かしています
これは今すぐにはできないので今回はキャラクターの向きについてはまた後日改めて投稿しますのでよろしくお願いします
◆おまけ
せっかく視点移動をPCゲームみたいにしたのに、移動方法がいまだに十字キーだったので変更しました
void FixedUpdate()
{
/*
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
*/
if(Input.GetKey(KeyCode.W))v=1;
//if(Input.GetKey(KeyCode.S))v=-1;
if(Input.GetKey(KeyCode.A))h=-1;
if(Input.GetKey(KeyCode.D))h=1;
Vector3 velocity = new Vector3(0, 0, v);
velocity = transform.TransformDirection(velocity);
float speedCache = speed *pulusSpeed* Time.fixedDeltaTime;
transform.localPosition += velocity * speedCache;
transform.Rotate(0, h * rotateSpeed * Time.fixedDeltaTime, 0);
ダッシュを「Eキー」にしたかったのですが、W,E,Dと隣接しているキーを3つ以上押すと3つ目は反応しないみたいです
今日はここまで