前回までのユニゲー(Unity でGame 制作)は…
ということで、続きです(=゚ω゚)。
Playerオブジェクトをそれなりに動かせるようにはなりましたが、まだまだ足りません。
なのでさらに改良を加えていきます。
具体的には上下の視点の操作(Playerオブジェクトは追従しない)、カメラとプレイヤーの距離の変更(見下ろし型視点とFPS視点の切り替えまたはマウススクロールでDolly)、歩行によるカメラのブレ(上下動)あたりもつけたいところです。
[PlayerFollowCamera.cs]
~~~省略
void LateUpdate()
{
// マウスの横方向の動きに追従
hRotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * turnSpeed, 0);
// マウスの縦方向の動きに追従
vRotation *= Quaternion.Euler(Input.GetAxis("Mouse Y") * turnSpeed, 0, 0);
// カメラの回転を合成
transform.rotation = hRotation * vRotation;
// カメラの位置(transform.position)の更新
transform.position = player.position + cameraPosition - transform.rotation * Vector3.forward * distance;
}
~~~省略
こんな感じに変更。さっそくPlayで動きを確認。
クリック時のみPlayerの向きを反映してましたけど、そのまま追従に変更。 うーん、あれだ。制限をかけないとぐるんぐるんしますね。 あと、上下の回転は反転が選択できるようにしたほうがいいかな。
色々と試行錯誤の結果こんな感じになりました。
[PlayerFollowCamera.cs]
using UnityEngine;
public class PlayerFollowCamera : MonoBehaviour
{
[SerializeField] private Transform player = null;// 追従対象
[SerializeField] private Vector3 cameraPosition = new Vector3(0, 1.8f, 0);//カメラポジション
[SerializeField] private float distance = 3.0f;// 追従対象からの距離
[SerializeField] private float pitch = 24.0f;// カメラX軸回転
[SerializeField] public float yaw = 0.0f;//カメラY軸回転
[SerializeField] private bool pitchInverse = false;// X軸反転
[SerializeField] private float mouseSensitivity = 10.0f;// 回転速度
void Start()
{
// 角度の初期化
transform.rotation = Quaternion.Euler(pitch, yaw, 0);
// 位置の初期化
transform.position = player.position + cameraPosition - transform.rotation * Vector3.forward * distance;
}
void LateUpdate()
{
// マウスの横方向の動き
float xRot = Input.GetAxis("Mouse X");
// マウスの縦方向の動き Y軸反転判定付き
float yRot = (pitchInverse)? Input.GetAxis("Mouse Y") : Input.GetAxis("Mouse Y") * -1.0f;
// カメラの向きを取得
Vector3 angles = transform.rotation.eulerAngles;
//Y軸回転(水平方向)を設定
yaw += xRot * mouseSensitivity;
yaw -= (yaw>360f)? 360f : 0;
yaw += (yaw<0)? 360f : 0;
//X軸回転(上下方向)を設定
pitch = (angles.x + 180f) % 360f - 180f;
pitch -= yRot * mouseSensitivity;
pitch = Mathf.Clamp(pitch, -90f, 90f);
// カメラの向きの更新
transform.rotation = Quaternion.Euler(pitch, yaw, 0);
// カメラの位置の更新
transform.position = player.position + cameraPosition - transform.rotation * Vector3.forward * distance;
}
}
[Player.cs]
using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField] private Vector3 velocity;//移動ベクトル
[SerializeField] private float moveSpeed = 1.25f;//移動速度、歩幅
[SerializeField] private PlayerFollowCamera pfCamera = null;//追従カメラ
void Update()
{
// キー入力判定
velocity = Vector3.zero;
if (Input.GetKey(KeyCode.W))
velocity.z += 1;
if (Input.GetKey(KeyCode.A))
velocity.x -= 1;
if (Input.GetKey(KeyCode.S))
velocity.z -= 1;
if (Input.GetKey(KeyCode.D))
velocity.x += 1;
// 移動ベクトルを秒単位でmoveSpeedだけ進むように制限
velocity = velocity.normalized * moveSpeed * Time.deltaTime;
// プレイヤー回転の更新
transform.rotation = Quaternion.Euler(0, pfCamera.yaw, 0);
// プレイヤー位置の更新
transform.position += transform.rotation * velocity;
}
}
マウス移動でPleyerの方向転換。上下回転制限つき。
[PlayerFollowCamera.cs]
~~~省略
[SerializeField] private float distanceMax = 3.0f;// 追従対象からの距離上限<=追加
~~~中略
void LateUpdate()
{
// カメラの向きを取得
Vector3 angles = transform.rotation.eulerAngles;
// Y軸回転(水平方向)を設定
float xRot = Input.GetAxis("Mouse X");
yaw += xRot * mouseSensitivity;
yaw -= (yaw>360f)? 360f : 0;
yaw += (yaw<0)? 360f : 0;
// X軸回転(上下方向)を設定
float yRot = (pitchInverse)? Input.GetAxis("Mouse Y") : Input.GetAxis("Mouse Y") * -1.0f;
pitch = (angles.x + 180f) % 360f - 180f;
pitch -= yRot * mouseSensitivity;
pitch = Mathf.Clamp(pitch, -90f, 90f);
// 追従対象からの距離を設定<=追加
distance -= Input.GetAxis("Mouse ScrollWheel") * mouseSensitivity;
distance = Mathf.Clamp(distance, 0, distanceMax);
// カメラの向きの更新
transform.rotation = Quaternion.Euler(pitch, yaw, 0);
// カメラの位置の更新
transform.position = player.position + cameraPosition - transform.rotation * Vector3.forward * distance;
}
~~~省略
マイスホイールでPlayerオブジェクトとの距離を変更(FPS視点、三人称視点切り替え)
さらに上下動(歩行時の揺れ的なもの)を追加。
[PlayerFollowCamera.cs]
~~~省略
[SerializeField] private float bobbing = 0.0f;// 上下動
[SerializeField] private float bobSpeed = 0.05f;// 揺れの速さ
[SerializeField] private float bobAmount = 0.015f;// 振幅
~~~中略
// 上下動を設定
float waveslice = 0.0f;
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
// 停止中(キー入力なし)?
if (Mathf.Abs(horizontal)==0 && Mathf.Abs(vertical)==0)
{
bobbing = 0;
} else {
waveslice = Mathf.Sin(bobbing);
bobbing = bobbing + bobSpeed;
if (bobbing > Mathf.PI * 2)
{
bobbing = bobbing - (Mathf.PI * 2);
}
}
Vector3 camPos = cameraPosition;
if (waveslice != 0)
{
float translateChange = waveslice * bobAmount;
float totalAxis = Mathf.Abs(horizontal) + Mathf.Abs(vertical);
totalAxis = Mathf.Clamp(totalAxis, 0.0f, 1.0f);
translateChange = totalAxis * translateChange;
camPos.y = cameraPosition.y + translateChange;
} else {
camPos.y = cameraPosition.y;
}
// カメラの向きの更新
transform.rotation = Quaternion.Euler(pitch, yaw, 0);
// カメラの位置の更新
transform.position = player.position + camPos - transform.rotation * Vector3.forward * distance;
}
}
各項目の数値は今後要調整だけど、とりあえずの動きはこんなかんじでしょうかね(=゚ω゚)ノ