FPSキャラのカメラを横に傾ける #1、FPSキャラのカメラを横に傾ける #2でFPSコントローラーのカメラを動かすと、壁を貫通して向こう側が見えてしまいます。
傾けていて壁に当たると自動でキャンセルするようにしてみます。まず、頭のカメラにコライダーとスクリプトを付けて、コライダーはIs Triggerにチェックをいれました。
スクリプトではカメラが壁に侵入したときに、FirstPersonControllerの静的メンバ変数をtrueにして、出たときにfalseにします。
using UnityEngine;
public class FPSCameraScript : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Untagged")
{
Debug.Log(other.tag);
UnityStandardAssets.Characters.FirstPerson.FirstPersonController.headEnterWall = true;
}
}
private void OnTriggerExit(Collider other)
{
if (other.tag == "Untagged") UnityStandardAssets.Characters.FirstPerson.FirstPersonController.headEnterWall = false;
}
}
この変数はFirstPersonControllerクラスで定義しておきます。
public static bool headEnterWall;
bool previousHeadEnterWall;
// Update()
bool eD = Input.GetKeyDown(KeyCode.E);
bool eU = Input.GetKeyUp(KeyCode.E);
bool eG = Input.GetKey(KeyCode.E);
bool qD = Input.GetKeyDown(KeyCode.Q);
bool qU = Input.GetKeyUp(KeyCode.Q);
bool qG = Input.GetKey(KeyCode.Q);
if (headEnterWall)
{
if (previousHeadEnterWall)
{
eD = false;
eU = false;
eG = false;
qD = false;
qU = false;
qG = false;
}
else
{
if (eG) eU = true;
if (qG) qU = true;
eD = false;
eG = false;
qD = false;
qG = false;
}
}
else
{
}
previousHeadEnterWall = headEnterWall; // 値を保存
// 以下は前の記事と同じです
// 何もしていない
if (lean == 0)
{
// 右へ
if (!eU && eD && !(!qU && qD))
{
lean = 3;
}
// 左へ
if (qD && !qU)
{
lean = 1;
}
}
// 左へ移動
else if (lean == 1)
{
// 回転
m_MouseLook.leanAmount += maxAbsLeanRot / leanSpeed * Time.deltaTime * 10f;
// 横移動
leanPosX -= maxAbsLeanPosX / leanSpeed * Time.deltaTime * 10f;
// 縦移動
leanPosY -= maxAbsLeanPosY / leanSpeed * Time.deltaTime * 10f;
/*
if (m_MouseLook.leanAmount >= 0)
{
m_MouseLook.leanAmount += 30f * Time.deltaTime;
}
else {
m_MouseLook.leanAmount += 80f * Time.deltaTime;
}*/
// 回転を止める
if (m_MouseLook.leanAmount > maxAbsLeanRot)
{
m_MouseLook.leanAmount = maxAbsLeanRot;
}
// 移動を止める
if (leanPosX < -maxAbsLeanPosX)
{
leanPosX = -maxAbsLeanPosX;
}
if (leanPosY < -maxAbsLeanPosY)
{
leanPosY = -maxAbsLeanPosY;
}
// 右へ
if (!eU && eD)
{
lean = 3;
}
// 左から戻るへ
if (qU && !(!eU && eD))
{
// 右へ
if (eG)
{
lean = 3;
}
else if (m_MouseLook.leanAmount >= 0)
{
lean = 2;
}
// 右から戻るへ
else if (m_MouseLook.leanAmount < 0)
{
lean = 4;
}
}
}
// 左から戻る
else if (lean == 2)
{
m_MouseLook.leanAmount -= maxAbsLeanRot / leanSpeed * Time.deltaTime * 10f * BackswingRatio;
leanPosX += maxAbsLeanPosX / leanSpeed * Time.deltaTime * 10f * BackswingRatio;
leanPosY += maxAbsLeanPosY / leanSpeed * Time.deltaTime * 10f * BackswingRatio;
if (m_MouseLook.leanAmount < 0f)
{
m_MouseLook.leanAmount = 0f;
// lean = 0;
}
if (leanPosX > 0f)
{
leanPosX = 0f;
}
if (leanPosY > 0f)
{
leanPosY = 0f;
}
if (m_MouseLook.leanAmount <= 0f && leanPosX >= 0f && leanPosY >= 0f)
{
lean = 0;
}
// 右へ
if (!eU && eD)
{
lean = 3;
}
// 左へ
if (!qU && qD && !(!eU && eD))
{
lean = 1;
}
}
// 右へ移動
else if (lean == 3)
{
m_MouseLook.leanAmount -= maxAbsLeanRot / leanSpeed * Time.deltaTime * 10f;
leanPosX += maxAbsLeanPosX / leanSpeed * Time.deltaTime * 10f;
leanPosY -= maxAbsLeanPosY / leanSpeed * Time.deltaTime * 10f;
/*
if (m_MouseLook.leanAmount <= 0f)
{
m_MouseLook.leanAmount -= 30f * Time.deltaTime;
}
else
{
m_MouseLook.leanAmount -= 80f * Time.deltaTime;
}*/
// 傾きを止める
if (m_MouseLook.leanAmount < -maxAbsLeanRot)
{
m_MouseLook.leanAmount = -maxAbsLeanRot;
}
// 移動を止める
if (leanPosX > maxAbsLeanPosX)
{
leanPosX = maxAbsLeanPosX;
}
// 移動を止める
if (leanPosY < -maxAbsLeanPosY)
{
leanPosY = -maxAbsLeanPosY;
}
// 左へ
if (qD && !qU)
{
lean = 1;
}
// 右から戻るへ
if (eU && !(!qU && qD))
{
lean = 4;
// 左へ
if (qG)
{
lean = 1;
}
// 右から戻るへ
else if (m_MouseLook.leanAmount <= 0)
{
lean = 4;
}
// 左から戻るへ
else if (m_MouseLook.leanAmount < 0)
{
lean = 2;
}
}
}
// 右から戻る
else if (lean == 4)
{
m_MouseLook.leanAmount += maxAbsLeanRot / leanSpeed * Time.deltaTime * 10f * BackswingRatio;
leanPosX -= maxAbsLeanPosX / leanSpeed * Time.deltaTime * 10f * BackswingRatio;
leanPosY += maxAbsLeanPosY / leanSpeed * Time.deltaTime * 10f * BackswingRatio;
if (m_MouseLook.leanAmount > 0f)
{
m_MouseLook.leanAmount = 0f;
//lean = 0;
}
if (leanPosX < 0f)
{
leanPosX = 0f;
}
if (leanPosY > 0f)
{
leanPosY = 0f;
}
if (m_MouseLook.leanAmount >= 0f && leanPosX <= 0 && leanPosY >= 0f)
{
lean = 0;
}
if (!qU && qD)
{
lean = 1;
}
if (!eU && eD && !(!qU && qD))
{
lean = 3;
}
}
まずキー入力を調べた後に、上で切り替える変数がtrueで、かつその変数の前のフレームでの値もtrueのときは、入力を全てfalseにします。
if (previousHeadEnterWall)
{
eD = false;
eU = false;
eG = false;
qD = false;
qU = false;
qG = false;
}
前のフレームでfalseのときは、壁に侵入した瞬間のフレームなので、キーが入力されていれば、GetKeyUpをtrueにして他はfalseにします。
else
{
if (eG) eU = true;
if (qG) qU = true;
eD = false;
eG = false;
qD = false;
qG = false;
}
そして、今の値を保存して次のフレームで使います。
previousHeadEnterWall = headEnterWall;
それ以降は上の記事と同じです。
これでカメラを傾けているときに壁に当たると、傾けるのをやめるようになりました。