高低差システムは、SRPGの戦略性を高めます。
高さ情報を実装すれば、命中率や射程に影響を与えられます。
この記事では、実装方法を詳しく解説します。
✨ この記事でわかること
- 高さ情報のデータ構造
- 命中率補正の実装
- 射程計算への影響
- 移動コストへの影響
- 実装例とコード

高低差システムは、まず高さ情報のデータ構造から始めましょう。各タイルに高さを持たせます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
高さ情報のデータ構造

SRPGで高低差を表現するためには、まず「マップの各マスがどれくらいの高さなのか」をゲーム側が正しく把握できる必要があります。
この高さ情報があることで、「高い場所から攻撃すると有利」「段差が大きい場所には登れない」といった、立体的な戦略が成立します。
ここでは初心者でも理解しやすいように、各タイルに高さの数値を持たせるシンプルなデータ構造から解説します。
高さ情報の基本的な考え方
考え方はとても単純で、マップを構成する各タイルに「高さ(elevation)」という整数値を持たせます。
高さ0を基準とし、そこから上に行くほど数値をプラス、下に行くほどマイナスにすることで、高低差を数値として扱います。
例えば、同じ平地同士であれば高低差は0ですが、平地(0)から丘(1)へ移動すると高低差は+1になります。
この「数値の差」を使って、移動制限や命中率補正などを計算します。
高さ情報の実装例(C#)
以下は、Unityでタイルごとに高さ情報を持たせるためのシンプルな実装例です。
まずは「タイルのデータ」と「高さを取得・計算する仕組み」に分けて考えると理解しやすくなります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
using UnityEngine; [System.Serializable] public class ElevationTileData : TileData { public int elevation = 0; // 高さ(0が基準) public bool isClimbable = true; // 登れるかどうか } public class ElevationSystem : MonoBehaviour { public GridSystem gridSystem; // 指定したマスの高さを取得 public int GetElevation(Vector2Int gridPos) { ElevationTileData tile = gridSystem.GetTile(gridPos) as ElevationTileData; return tile != null ? tile.elevation : 0; } // 2つのマスの高低差を計算 public int GetElevationDifference(Vector2Int from, Vector2Int to) { int fromElevation = GetElevation(from); int toElevation = GetElevation(to); return toElevation - fromElevation; } // 登れるかどうかを判定 public bool CanClimb(Vector2Int from, Vector2Int to) { int elevationDiff = GetElevationDifference(from, to); // 1段差までなら登れる return elevationDiff <= 1; } } |
このコードでは、各タイルが持つ高さ情報を取得し、隣接するマスとの高低差を計算できるようになっています。
「GetElevationDifference」を使えば、「今いる場所からどれくらい高い(または低い)マスなのか」を簡単に判定できます。
高さ設定の具体例
実際のSRPGをイメージしながら、高さの数値を決めていくと理解しやすくなります。
以下は、初心者向けにおすすめできる基本的な設定例です。
✅ 高さの設定例
- 平地:高さ0(基準となる高さ)
- 丘:高さ1(1段高い場所)
- 山:高さ2(さらに高い場所)
- 谷:高さ-1(1段低い場所)
このように数値で高さを管理しておくと、「高さ2の山から高さ0の平地を攻撃している」「高さ-1の谷から丘に登ろうとしている」といった状況を、コード上で明確に判定できます。
まずはこのシンプルな仕組みを作り、その後に命中率や移動コストへ影響を広げていくと、無理なく高低差システムを実装できます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
命中率補正の実装

命中率補正は、高低差に応じて命中率が変化します。
実装方法を紹介します。
命中率計算システム
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class ElevationAccuracySystem : MonoBehaviour { public ElevationSystem elevationSystem; public float CalculateAccuracyWithElevation(Unit attacker, Unit defender) { // 基本命中率 float baseAccuracy = attacker.accuracy - defender.evasion; // 高低差による補正 Vector2Int attackerPos = attacker.position; Vector2Int defenderPos = defender.position; int elevationDiff = elevationSystem.GetElevationDifference(attackerPos, defenderPos); // 高い位置から低い位置への攻撃:命中率+10% if (elevationDiff < 0) { baseAccuracy += 10f; } // 低い位置から高い位置への攻撃:命中率-10% else if (elevationDiff > 0) { baseAccuracy -= 10f; } // 0〜100%の範囲に制限 return Mathf.Clamp(baseAccuracy, 0f, 100f); } } |
このコードで、命中率補正が実装できます。
高低差に応じて、命中率が変化します。

命中率補正は、±10%が標準です。高すぎると高低差が強すぎ、低すぎると意味がありません。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
射程計算への影響

射程計算は、高低差で射程が変化します。
実装方法を紹介します。
射程計算システム
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public class ElevationRangeSystem : MonoBehaviour { public ElevationSystem elevationSystem; public bool IsInRange(Unit attacker, Unit defender, int baseRange) { Vector2Int attackerPos = attacker.position; Vector2Int defenderPos = defender.position; // 水平距離 float horizontalDistance = Vector2Int.Distance(attackerPos, defenderPos); // 高低差 int elevationDiff = Mathf.Abs(elevationSystem.GetElevationDifference(attackerPos, defenderPos)); // 射程 = 基本射程 - 高低差によるペナルティ int effectiveRange = baseRange - elevationDiff; return horizontalDistance <= effectiveRange; } public int GetEffectiveRange(Unit attacker, Unit defender, int baseRange) { Vector2Int attackerPos = attacker.position; Vector2Int defenderPos = defender.position; int elevationDiff = Mathf.Abs(elevationSystem.GetElevationDifference(attackerPos, defenderPos)); return Mathf.Max(baseRange - elevationDiff, 1); } } |
このコードで、射程計算が実装できます。
高低差に応じて、射程が減少します。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
移動コストへの影響

移動コストは、高低差で変化します。
実装方法を紹介します。
移動コスト計算システム
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
public class ElevationMovementSystem : MonoBehaviour { public ElevationSystem elevationSystem; public int CalculateMovementCost(Vector2Int from, Vector2Int to, int baseCost) { int elevationDiff = elevationSystem.GetElevationDifference(from, to); // 登る場合:移動コスト+1 if (elevationDiff > 0) { return baseCost + 1; } // 下る場合:移動コスト-1(最低1) else if (elevationDiff < 0) { return Mathf.Max(baseCost - 1, 1); } // 同じ高さ:基本コスト else { return baseCost; } } public bool CanMoveTo(Unit unit, Vector2Int targetPos) { Vector2Int currentPos = unit.position; // 登れるかチェック if (!elevationSystem.CanClimb(currentPos, targetPos)) { return false; } // 移動コストを計算 int moveCost = CalculateMovementCost(currentPos, targetPos, 1); // 移動範囲内かチェック return moveCost <= unit.moveRange; } } |
このコードで、移動コスト計算が実装できます。
高低差に応じて、移動コストが変化します。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
実装例:完全な高低差システム

ここまでで、高さ情報・命中率補正・射程計算・移動コストといった個別の仕組みを実装してきました。
しかし実際のゲームでは、これらをバラバラに使うのではなく、ひとつの「高低差システム」としてまとめて扱う必要があります。
ここでは、これまでに作成した各システムを統合し、実際のSRPGでそのまま使える形にした実装例を紹介します。
完全な高低差システムの役割
このクラスの役割はとてもシンプルです。
「攻撃できるか」「命中率はいくつか」「そのマスへ移動できるか」といったゲーム進行で頻繁に使う判定処理を一本化します。
個別の計算ロジックはそれぞれの専用クラスに任せ、ここでは全体をつなぐ窓口として機能させます。
統合クラスの実装例(C#)
以下が、これまで作成した高低差関連システムをまとめたクラスの例です。
コード量は少ないですが、実際のゲームでは非常に重要な役割を担います。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using UnityEngine; public class CompleteElevationSystem : MonoBehaviour { [Header("システム")] public ElevationSystem elevationSystem; public ElevationAccuracySystem accuracySystem; public ElevationRangeSystem rangeSystem; public ElevationMovementSystem movementSystem; // 攻撃可能かどうかを判定 public bool CanAttack(Unit attacker, Unit defender) { // 射程チェック if (!rangeSystem.IsInRange(attacker, defender, attacker.weapon.range)) { return false; } return true; } // 高低差を考慮した命中率を取得 public float GetAttackAccuracy(Unit attacker, Unit defender) { return accuracySystem.CalculateAccuracyWithElevation(attacker, defender); } // 指定したマスへ移動できるかを判定 public bool CanMove(Unit unit, Vector2Int targetPos) { return movementSystem.CanMoveTo(unit, targetPos); } } |
このクラスを用意しておくことで、バトル処理側では
- 「この敵に攻撃できるか?」
- 「命中率はいくつか?」
- 「このマスへ移動可能か?」
といった判定を、1行のメソッド呼び出しで済ませられるようになります。
高さ情報・命中率補正・射程計算・移動コストといった処理が、ここでひとつの高低差システムとして統合されています。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
よくある質問(FAQ)

最後に、高低差システムを実装する際によく出てくる疑問と、その考え方をまとめました。
数値の目安として参考にしてください。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
まとめ

高低差システムは、まず高さ情報のデータ構造から始めましょう。
各タイルに高さを持たせれば、戦略性が高まります。
✅ 今日から始める3ステップ
- ステップ1:高さ情報のデータ構造を実装する(所要2時間)
- ステップ2:命中率補正を実装する(所要2時間)
- ステップ3:移動コスト計算を実装する(所要2時間)
本格的にUnityを学びたい方は、Unity入門の森で実践的なスキルを身につけましょう。
あなたのペースで、少しずつ進めていけば大丈夫です。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる



コメント