前回は、Unity 6で地面となるGroundを作成し、ColliderとRigidbodyを使ってPlayerが地面の上に立てる状態を作りました。
今回は、そのGroundの周囲に壁を作成し、Playerがゲームエリアの外へ出ないようにします。
壁にはUnityのCubeを使用します。
Cubeには最初からBox Colliderが設定されているため、Playerが壁にぶつかる基本的な当たり判定を簡単に作ることができます。
また、前回の記事で触れたように、現在のPlayerMovementではtransform.Translate()を使ってPlayerを移動しています。
今回は壁との当たり判定をより自然に扱えるように、PlayerMovementもRigidbodyを使った移動方法へ変更します。
前回のGround・Collider・Rigidbodyの設定についてはこちらの記事で解説しています。
Unity 6で地面と当たり判定を作る方法|ColliderとRigidbodyを初心者向けに解説
今回作るゲームエリア
今回はGroundの周囲を4つの壁で囲みます。
作成する壁は、
- Wall_North
- Wall_South
- Wall_East
- Wall_West
の4つです。
Playerはこの壁の内側をW・A・S・Dキーで移動します。
壁にはBox Colliderが設定されているため、Playerが壁まで移動すると、それ以上ゲームエリアの外へ進めない状態を目指します。
まだ本格的なステージではありませんが、ゲームとして移動できる範囲を作る最初のステップになります。
壁を管理するためのWallsを作成する
ゲームを作っていくと、Hierarchy内のGameObjectがどんどん増えていきます。
今回だけでも4つの壁を作成するため、そのままHierarchyへ並べても動作上は問題ありませんが、少しずつ管理しにくくなります。
そこで、壁をまとめるための空のGameObjectを作成します。
名前は、
Walls
にします。
今後作成する4つの壁は、すべてWallsの子GameObjectとして配置します。
Hierarchyを整理しておくと、どのGameObjectが何のために存在しているのか分かりやすくなります。
最初の壁をCubeで作成する
まず1つ目の壁を作成します。
UnityのHierarchyから3D Objectの
Cube
を作成します。
作成したCubeの名前を、
Wall_North
に変更します。
今回はGroundの北側となる位置に配置します。
Groundは前回ScaleをX=3、Z=3に設定したため、かなり広い地面になっています。
Wall_NorthのTransformは、例えば次のように設定します。
Position X = 0
Position Y = 1
Position Z = 14.5
Scale X = 30
Scale Y = 2
Scale Z = 1
これでGroundの端に横長の壁を配置できます。

CubeにはBox Colliderが付いている
今回壁として使用しているCubeには、作成した時点で
Box Collider
が設定されています。
そのため、壁に新しくColliderを追加する必要はありません。
HierarchyでWall_Northを選択してInspectorを見ると、Box Colliderを確認できます。

前回Playerでも確認したように、ColliderはGameObjectの当たり判定を作るために使用します。
今回はPlayerのBox Colliderと壁のBox Colliderが接触することで、Playerが壁を通り抜けない状態を作ります。
残りの壁を複製する
1つずつ新しいCubeを作成しても構いませんが、同じようなGameObjectを作る場合は複製すると便利です。
Wall_Northを選択して複製し、
Wall_South
Wall_East
Wall_West
を作成します。
それぞれのTransformは次のように設定します。
Wall_North
Position = X 0 / Y 1 / Z 14.5
Scale = X 30 / Y 2 / Z 1
Wall_South
Position = X 0 / Y 1 / Z -14.5
Scale = X 30 / Y 2 / Z 1
Wall_East
Position = X 14.5 / Y 1 / Z 0
Scale = X 1 / Y 2 / Z 30
Wall_West
Position = X -14.5 / Y 1 / Z 0
Scale = X 1 / Y 2 / Z 30
4つの壁を配置すると、Groundの周囲がCubeで囲まれます。

数値は今回のテスト用なので、今後ゲームのステージを作っていくときには自由に変更できます。
壁をWallsの中に整理する
4つの壁を作成したら、Hierarchyでそれぞれの壁を
Walls
へドラッグします。
Hierarchyが、
Walls
├─ Wall_North
├─ Wall_South
├─ Wall_East
└─ Wall_West
のような状態になればOKです。
このように親GameObjectを使ってまとめておくと、Hierarchyが見やすくなります。
また、Wallsをまとめて非表示にしたり、将来的にまとめて移動したりするときにも便利です。
PlayerMovementをRigidbody向けに変更する
前回まで使用していたPlayerMovementでは、
transform.Translate()
を使ってPlayerのTransformを直接変更していました。
基本的な移動を確認するだけなら分かりやすい方法ですが、現在のPlayerにはRigidbodyが追加されています。
壁や地面などの物理的な衝突を扱う場合は、Rigidbodyを使ってPlayerを移動させる方が適しています。
そこで今回はPlayerMovementを少し変更します。
使用するコードは次のようになります。
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class PlayerMovement : MonoBehaviour
{
[SerializeField] private float moveSpeed = 5f;
private Rigidbody rb;
private Vector3 moveInput;
private void Awake()
{
rb = GetComponent<Rigidbody>();
}
private void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
moveInput = new Vector3(horizontal, 0f, vertical).normalized;
}
private void FixedUpdate()
{
Vector3 nextPosition =
rb.position + moveInput * moveSpeed * Time.fixedDeltaTime;
rb.MovePosition(nextPosition);
}
}

保存したらUnityへ戻り、Consoleにエラーが表示されていないことを確認します。
Rigidbody.MovePositionとは?
今回のコードでは、
rb.MovePosition()
を使っています。
これはRigidbodyを使用してGameObjectの位置を移動させる方法です。
前回のコードでは、
transform.Translate()
によってTransformを直接変更していました。
今回はPlayerにRigidbodyがあるため、そのRigidbodyを使って移動させます。
また、物理演算に関係する移動処理は、
FixedUpdate()
の中で実行しています。
初心者の段階ですべてを覚える必要はありませんが、
Update = 主に入力を確認する
FixedUpdate = Rigidbodyを使った物理処理を行う
というイメージで覚えておくと分かりやすいです。
PlayerのRigidbody設定を確認する
PlayerMovementを変更したら、PlayerのRigidbody設定も確認します。
前回設定した、
Use Gravity = ON
Freeze Rotation X = ON
Freeze Rotation Z = ON
の状態になっていることを確認します。
Y方向のRotationは今回は固定しません。
Move Speedについては前回と同じく、
5
程度から試します。
動きが速すぎたり遅すぎたりする場合は、Inspectorから自由に変更できます。

Playモードで壁との当たり判定を確認する
設定が終わったらUnity上部のPlayボタンを押します。
Gameビューをクリックして、W・A・S・DキーでPlayerを動かします。
そのままPlayerをいずれかの壁まで移動させてください。
Playerが壁に接触したところで止まり、それ以上外側へ進まなければ成功です。

別の方向の壁にも移動し、4方向すべてでPlayerがゲームエリアの外へ出ないことを確認します。
壁を見た目だけ配置するのではなく、実際にPlayerを操作してColliderが機能していることを確認することが重要です。
壁を通り抜けてしまう場合
Playerが壁を通り抜けてしまう場合は、いくつかの設定を確認します。
まずPlayerに、
Box Collider
Rigidbody
が設定されていることを確認します。
次に壁に、
Box Collider
が付いていることを確認します。
また、PlayerMovementが以前のtransform.Translate()のままになっていないかも確認してください。
今回の記事では、RigidbodyのMovePosition()を使ったコードに変更しています。
さらに、Playerを非常に高速で移動させると、物理演算の設定によっては衝突を正しく検出できない場合があります。
まずはMove Speedを5程度にしてテストすることをおすすめします。
Colliderだけで壁を作れる理由
今回の壁にはRigidbodyを追加していません。
壁はゲーム中に物理演算で動かす必要がなく、その場に固定しておきたいGameObjectだからです。
そのため今回は、
壁 = Box Collider
Player = Box Collider + Rigidbody
という構成になっています。
Player側にRigidbodyがあり、壁側にはColliderがあることで衝突を扱うことができます。
この考え方は今後、建物や障害物などを作成するときにも利用できます。
ゲームエリアらしくなってきた
これまでのSceneにはPlayerとGroundしかありませんでした。
今回4つの壁を追加したことで、
Playerが移動できる場所
と
Playerが移動できない場所
ができました。
非常にシンプルな構成ですが、ゲームのステージとして必要な考え方が少しずつ増えてきています。
今後は、このゲームエリアの中にアイテムや障害物などを追加することで、さらにゲームらしいSceneにしていきます。
今回のまとめ
今回はUnity 6でCubeを使って4つの壁を作成し、Playerがゲームエリアの外へ出ないようにしました。
Cubeには最初からBox Colliderが設定されているため、壁の当たり判定として利用できます。
また、前回まで使用していたPlayerMovementも修正し、transform.Translate()ではなくRigidbodyのMovePosition()を使ってPlayerを移動させるようにしました。
これによって、Ground・Player・壁のColliderを使った基本的なゲームエリアを作ることができました。
Hierarchyでは複数の壁をWallsの中にまとめ、GameObjectを整理する方法についても確認しました。
次回は障害物をゲームエリアに配置する
ゲームエリアの外周が完成したので、次はエリアの中にもGameObjectを配置していきます。
次回はCubeなどを使って簡単な障害物を作成します。
Playerが障害物を避けながら移動できるようにし、Colliderを使った当たり判定についてさらに確認していきます。
さらに、Materialを使ってGroundや壁、障害物の見た目も少しずつ分かりやすくしていきます。

