前の記事でカメラを回転させるときに、カメラを縦横に動かして柱の角から覗けるようにします。
FirstPersonControllerクラスではカメラの移動はUpdateCameraPosition()で行うので、ここにカメラを見て横と縦の移動を加えます。
newCameraPosition.y = /* ... */ + cameraHeight + leanPosY;
// ---
newCameraPosition.x = leanPosX;
m_Camera.transform.localPosition = newCameraPosition;
}
newCameraPosition.yに値を入れて高さを変えるところが2つあるので、両方に変数を足します。cameraHeightは前にプレイヤーをしゃがませるために足したものです。
そして、ブロックの最後のカメラの位置を変える直前で横方向の移動を足します。これらの変数の値は普段は0にしておきます。
// 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 (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;
}
}
カメラの回転と横、縦の移動が同じタイミングで終わるように、それぞれに目的の値を決めて、1フレームごとに動かすのは、それぞれ同じ値で割った値にしています。
戻るときにだけかける値を作って、傾けるときと戻るときのスピードを変えられるようにしました。
しゃがみながらリーンすることもできます。