ゲーム化!tomo_manaのブログ

ゲーム化!tomo-manaのブログ

Unityでゲームを作る方法について紹介しています

Unity学習#5 (Unity 2019.4.1f1) 障害物と当たり判定

今回は障害物の作成と当たり判定に挑戦しました。
かなりてごずりました。


今回の作業にあたって、全体的に以下のサイトを参考にしました。先駆者が居てくれることに感謝です。
qiita.com

キャラクターをグリッドに合わせる

Player をX=0, Y=0に配置すると、TileMapと座標がずれていることに気が付きます。X=0, Y=0はグリッドの線上、TileMapはグリッド間に配置されるので、ずれて見えます。Playerの初期位置をX=0.5, Y=0.5にして、TileMapに合わせました。
f:id:tomo_mana:20200704225432p:plain

層を分ける

層を定義する

障害物を設置する前に、歩けるエリアと歩けないエリアを分けます。
層はSorting Layersで定義します。
1) Unity画面上部にある Layers▼ > Edit Layers を選択
f:id:tomo_mana:20200704225505p:plain
2) InspectorウィンドウにTags, Sorting Layers, Layersが表示される
3) Sorting Layers を選択する
4) +ボタンでLayerを追加する
 最初はLayer = Default だけが存在します。
5) サイトに従って、walk(歩行可能), character(歩行者), obstacle(歩行不可) を追加しました。
f:id:tomo_mana:20200704225529p:plain
 新しく追加されたレイヤは行の下に追加されます。
 下の行にあるレイヤほど後から描画=画面では上に描画されます。

層を設定する

1) Hierarchy からオブジェクトを選択
2) Inspector > Sprite Renderer > Additional Settings > Sorting Layer を選択
3) 先ほど追加したレイヤを選択

障害物

障害物の設定には、境界線(Collider)と質感(Rigidbody)を設定します。
当たり判定になぜ「質感」を設定するのか?ですが、Unityの当たり判定は、RPGなどの比較的単純な当たり判定ではなく、落下運動や放物線などの高度な衝突計算に特化しています。
RPGの単純な当たり判定を期待していると、ありえない動作に戸惑うことになります。これは行き詰ってみないと感じられない経験でした。

境界線の設定

境界線の設定には、Collider 2D を使用します。
キャラクター には「Box Collider 2D」、TileMapの障害物レイヤには「Tilemap Collider 2D」を設定します。

キャラクターの境界線

1) Hierarchy からキャラクター(私の場合はPlayer)を選択。
2) Inspector の一番下にある、Add Component ボタンから、以下を選択します。
 Add Component > Physics 2D > Box Collidor 2D
3) パラメータは以下のように設定します。
f:id:tomo_mana:20200704225216p:plain

パラメータ 設定 説明
is Trigger チェック無し (Default) is Trigger を設定すると、障害物を通り抜けます。(参考)Collider 2Dの衝突・侵入判定について - 適当おじさんの適当ブログ
Used By Effector チェック無し (Default)
Used By Composite チェック無し (Default)
Auto Tiling チェック無し (Default)
Offset X=0, Y=0 (Default)
Size X=0.8, Y=0.8 Sizeは、キャラクターサイズを1×1とした時の境界線のサイズです。デフォルトではX, Yとも1.28となっていますが、これだと細い通路を通れなくなるため、1より少し小さい値にしました。
Edge Radius 0 当たり判定の角を丸める時に使います
障害物の境界線

Inspector の一番下にある、Add Component ボタンから、以下を選択します。
1) Hierarchy から Tilemap(障害物レイヤ)を選択。
2) Inspector の一番下にある、Add Component ボタンから、以下を選択します。
 Add Component > Tilemap > Tilemap Collidor 2D
 パラメータはデフォルトのままです。
f:id:tomo_mana:20200704225234p:plain

オブジェクトに質感を付与する

オブジェクトの質感は、Rigidbody 2D で設定します。これはキャラクターも障害物の共通です。
Unityのマニュアルには、「Rigidbody 2D」は Transform をオーバーライドする、と書いてあります。これはRigidbody 2D が当たり判定を行う時、対象(Transform)の座標(Position, Rotation)を変更する、という意味に捉えれば良いのではと思います。これが当たり判定に関するUnityの便利なところであり、RPGのような単純な当たり判定には高度すぎて逆に不利に働く部分でもあります。

キャラクターの質感

1) Hierarchy からキャラクター(私の場合はPlayer)を選択。
2) Inspector の一番下にある、Add Component ボタンから、以下を選択します。
 Add Component > Physics 2D > Rigidbody 2D
3) パラメータは以下のように設定します。
f:id:tomo_mana:20210102172842p:plain

パラメータ 設定 説明
Body Type Dynamic Kinematic(運動学的)、Static(静的) は、衝突した時のTransformへの再計算(障害物に当たった時に、そこから先に進めなくする)をしません
Simulated チェック有り (Default) チェックが入っていないと衝突計算をしません
Use Auto Mass チェック無し (Default)
Mass 1
Linear Drag 0
Angular Drag 0
Gravity Scale 0 Gravity は 2D の場合はY方向にかかる重力で、0以外を設定すると画面の下に落ちていきます(横スクロール型アクションゲームで使用します)
Collision Detection Continuous フレームレートと衝突計算レートの差を縫ってオブジェクトが障害物をすり抜けるのを防ぎます(研究不足です)
Sleeping Mode Start Awake 衝突計算監視を起動時に読み込む Start Awake を設定します
Interpolate None 衝突計算をした時の軌道を補完するかどうかの設定ですが、RPGは単純計算で良いので None を設定します
Constraints.Freeze Position.X チェック無し チェックすると衝突時の座標再計算(障害物に押し戻される)ができなくなります
Constraints.Freeze Position.X チェック無し チェックすると衝突時の座標再計算(障害物に押し戻される)ができなくなります
Constraints.Freeze Rotation.Z チェック有り 2DではZは無効です
障害物の質感

Inspector の一番下にある、Add Component ボタンから、以下を選択します。
1) Hierarchy から Tilemap(障害物レイヤ)を選択。
2) Inspector の一番下にある、Add Component ボタンから、以下を選択します。
 Add Component > Physics 2D > Rigidbody 2D (キャラクターの時と同じです)
3) パラメータは以下のように設定します。
f:id:tomo_mana:20200704225302p:plain

パラメータ 設定 説明
Body Type Static Static(静的)は、無限に重いもの(つまり衝突で動かされないもの)を表します
Simulated チェック有り (Default) チェックが入っていないと衝突計算をしません

設定後

当たり判定は、画面のように緑枠で表示され、直感的です。
f:id:tomo_mana:20200704232732p:plain
障害物レイヤは、以下のようになっています。
f:id:tomo_mana:20200704232824p:plain

次回やること

キャラクターのアニメーション
町、ダンジョンへの移動