壁
Coddyの「Unityゲーム:3Dスネーク」コースのレッスン 4/14。
盤面のマスは x 軸と z 軸のそれぞれで -7 から 7 までなので、x と z の両方が -7 から 7 の間にあるとき、そのマスは盤面上にあります。盤面の中心は 0 なので、1つのテストで両側を判定できます。Mathf.Abs(x) > 7 は、どちらかの端を越えると true になります。
頭が移動しようとしているマスを、そこへ移動する前にテストします。そうすれば、ヘビが壁にぶつかっても、盤面の最後のマスにとどまり、境界の内側に入り込むことはありません。0 から 7 まで番号が付いたチェス盤上のルークも、同じ方法で判定します。
Vector3 target = transform.position + move;
if (target.x < 0 || target.x > 7 || target.z < 0 || target.z > 7)
{
return; // 盤外に出るため、ルークはその場にとどまる
}
transform.position = target;壁にぶつかるとゲームが終了し、ヘビは二度と動きません。Update() が最初にテストする bool を使えば、これを実現できます。先頭の return によって、キーの処理もタイマーの処理もスキップされます。
チャレンジ
簡単- 追加する
public int edge = 7;(盤面のセルは-edgeからedgeまで)とpublic bool alive = true;。 Step()で、directionを設定した後、頭が次に入ろうとしているセルであるnextを求めます。盤面の外ならDie()を呼び出して、移動せずに return します。それ以外の場合は、頭をnextに移動します。aliveを false に設定するvoid Die()を記述します。- ヘビが生きていない場合に return するよう、
Update()の先頭に処理を追加します。これにより、死んだヘビは方向転換も移動もしません。
Play を押し、壁に向かって進んでから、Check を押します。
自分で試してみよう
using UnityEngine;
using UnityEngine.InputSystem;
public class Snake : MonoBehaviour
{
public float tick = 0.15f; // 2回の移動の間隔(秒)
private float timer;
private Vector3 direction = Vector3.right; // 直前の移動で頭が進んだ方向
private Vector3 nextDirection = Vector3.right; // 次の移動で適用される方向転換
void Update()
{
Keyboard keyboard = Keyboard.current;
if (keyboard != null)
{
if (keyboard.upArrowKey.wasPressedThisFrame || keyboard.wKey.wasPressedThisFrame) Turn(Vector3.forward);
if (keyboard.downArrowKey.wasPressedThisFrame || keyboard.sKey.wasPressedThisFrame) Turn(Vector3.back);
if (keyboard.leftArrowKey.wasPressedThisFrame || keyboard.aKey.wasPressedThisFrame) Turn(Vector3.left);
if (keyboard.rightArrowKey.wasPressedThisFrame || keyboard.dKey.wasPressedThisFrame) Turn(Vector3.right);
}
timer += Time.deltaTime;
if (timer >= tick)
{
timer -= tick;
Step();
}
}
void Turn(Vector3 newDirection)
{
if (newDirection != -direction)
{
nextDirection = newDirection;
}
}
void Step()
{
direction = nextDirection;
transform.position += direction;
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。