ドアを開閉中にドアがプレイヤーに当たると、キー入力がなくても自動でプレイヤーを後ろに移動させます。
ドアの開閉中はプレイヤーの移動や回転をロックしているので、ドアが引っかかると一旦ドアの開閉をやめてプレイヤーを移動させてもう一度開閉させないといけないので面倒です。それでもまだ引っかかる場合もあります。
プレイヤーを自動でバックさせるために、まずドアとの衝突を調べます。前の記事でプレイヤーの頭に付けたコライダーを使います。
private void OnTriggerStay(Collider other)
{
if (state == 2 && other.tag == "Door1" && !sc_fps.doorHit)
{
StopCoroutine("StepBack");
StartCoroutine("StepBack");
}
}
private IEnumerator StepBack()
{
sc_fps.doorHit = true;
yield return new WaitForSeconds(0.3f);
sc_fps.doorHit = false;
}
/*
private void OnTriggerExit(Collider other)
{
if (other.tag == "Door1")
{
sc_fps.doorHit = false;
}
}
*/
頭に付けたスクリプトで衝突を判定して、体のスクリプトに知らせます。そして、体のスクリプトでプレイヤーを後ろに移動させます。衝突しているかどうかを知らせるのにbool型の変数を使いますが、衝突した後にOnTriggerExitですぐに値を戻すと、値の切り替わりが早すぎて画面がガタガタと揺れてしまうようです。
値がtrueになった後少し時間が立ってからfalseに戻すようにすると、ぐらつきにくくなりました。
FirstPersonControllerでは、GetInput()の中でキー入力によってプレイヤーを移動させます。
プレイヤーの前後の移動がverticalに入っているので、後からこれを上書きすると、キー入力に関係なくキャラクターを移動できます。
// 移動をロック
if (fixCam)
{
horizontal = 0f;
vertical = 0f;
}
// 開閉中ドアに当たっている時
if (doorHit)
{
vertical = -1f;
speedmul = 0.3f;
}
else speedmul = 1f;
// ---
// 移動速度を変える
speed *= speedmul;
開閉中のドアに当たっている時は、verticalを-1にしてバックさせています。この時は移動速度も遅くします。
移動を0で上書きすれば、キー入力があってもプレイヤーを動かさないようにできます。