本文へスキップ
ゲームUI設計

スキル射程と発動確定を迷わせない戦闘UI設計ガイド

射程円、予測ライン、確定前の注意表示を使って、攻撃や回復スキルの失敗感を減らすための設計を整理します。

公開日: 2026-07-12#Unity#戦闘UI#スキル設計#UI設計#Beginner
+
*
+
ココ先生・喜ぶ
ココ先生
ゲーム開発の案内役
この記事では スキル射程と発動確定を迷わせない戦闘UI設計ガイド を、読んで終わりにせず、射程円を地面に描き、マウスの照準が届くかを色で見せてから発動します。
+
*
+
はじめちゃん・笑う
はじめちゃん
ゲームエンジン学習中
スキル射程と発動確定を迷わせない戦闘UI設計ガイド を読む前に、まずUnity のどこを見ればよいかを確認したいです。
ココ先生
射程円を地面に描き、マウスの照準が届くかを色で見せてから発動します。
はじめちゃん
円の内側だけをクリックした時に発動するようにするのですね。
ココ先生
Line Renderer、地面へのRaycast、距離判定、クリック発動の順で作ります。
射程円とターゲット確定表示を中心にした戦闘UIのヒーロー画像
完成イメージ

射程円を描く

Line RendererでPlayerの足元を中心にした射程円を地面へ描きます。

照準を動かす

Raycastでマウスが指すGroundの位置へTarget Markerを動かします。

届く場所だけ発動

距離がcastRange以内なら緑にし、左クリックでCastAtを呼びます。

導入

スキル射程と発動確定を迷わせない戦闘UI設計ガイドでは、ボタンで数字を変えるのではなく、地面へ射程円を描き、マウス位置が届くかを色で示してから発動を確定します。完成イメージの円、照準、発動ラインを順番に作ります。

これから作るもの

  1. 3Dシーンに Player GameObject と Plane を置きます。Plane の Layer を Ground にします。
  2. Player の子に空の GameObject を作り、RangeLine と名付けて Line Renderer を追加します。幅は 0.08、Material は発光色にします。
  3. Cylinder を薄くして TargetMarker と名付け、Player とは別の GameObject にします。届く場所は緑、届かない場所は赤で表示します。
  4. AbilityRangeIndicator スクリプトを新規作成し、Player に付けます。Inspector で Range Line と Target Marker をドラッグします。

ステップ1: 射程円を地面へ描く

Line Renderer は点を順番につなぐ部品です。円周上の点を64個作ると、Playerの足元を中心にした射程円になります。

using UnityEngine;

public class AbilityRangeIndicator : MonoBehaviour
{
    [SerializeField] private LineRenderer rangeLine;       // 地面に描く射程円
    [SerializeField] private Transform targetMarker;       // マウス位置を示すマーカー
    [SerializeField] private float castRange = 8f;         // スキルが届く最大距離
    [SerializeField] private int circleSegments = 64;      // 円をなめらかに見せる頂点数

    private Camera mainCamera;
    private Vector3 casterPosition;

    private void Awake()
    {
        mainCamera = Camera.main;
        casterPosition = transform.position;
        DrawRangeCircle();
    }

    private void DrawRangeCircle()
    {
        rangeLine.positionCount = circleSegments + 1;
        for (var i = 0; i <= circleSegments; i++)
        {
            var angle = i * Mathf.PI * 2f / circleSegments;
            var offset = new Vector3(Mathf.Cos(angle), 0.02f, Mathf.Sin(angle)) * castRange;
            rangeLine.SetPosition(i, casterPosition + offset);
        }
    }
}

ステップ2: マウスが指す地面を見つける

画面のマウス位置から地面へ見えない線を飛ばします。線が Plane に当たった場所を照準の位置にします。これは懐中電灯で地面を照らすイメージです。

private bool TryMoveMarkerToMouse(out bool isInRange)
{
    isInRange = false;
    var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
    if (!Physics.Raycast(ray, out var hit, 200f, LayerMask.GetMask("Ground"))) return false;

    var flatTarget = hit.point;
    flatTarget.y = casterPosition.y + 0.04f;
    targetMarker.position = flatTarget;

    var distance = Vector3.Distance(casterPosition, flatTarget);
    isInRange = distance <= castRange;
    return true;
}

ステップ3: 射程内かどうかを色で伝える

Playerから照準までの距離が castRange 以下なら緑、外なら赤にします。数字を読まなくても、発動できる場所がすぐ分かります。

private void UpdateMarkerColor(bool isInRange)
{
    var renderer = targetMarker.GetComponent<Renderer>();
    renderer.material.color = isInRange
        ? new Color(0.25f, 1f, 0.7f, 0.9f)   // 届く場所は緑
        : new Color(1f, 0.25f, 0.25f, 0.9f); // 届かない場所は赤
}

ステップ4: 左クリックで発動を確定する

Update では毎フレーム照準を動かし、左クリックした瞬間だけ CastAt を呼びます。射程外では発動しないため、完成イメージの『ここには届かない』状態も確認できます。

private void Update()
{
    if (!TryMoveMarkerToMouse(out var isInRange)) return;
    UpdateMarkerColor(isInRange);

    if (Input.GetMouseButtonDown(0) && isInRange)
    {
        CastAt(targetMarker.position);
    }
}

完成版

以下を AbilityRangeIndicator.cs として保存します。Planeに Ground Layer が付いていること、Range LineとTarget MarkerがInspectorへ入っていることを確認してからPlayしてください。

using UnityEngine;

public class AbilityRangeIndicator : MonoBehaviour
{
    [SerializeField] private LineRenderer rangeLine;       // 地面に描く射程円
    [SerializeField] private Transform targetMarker;       // マウス位置を示すマーカー
    [SerializeField] private float castRange = 8f;         // スキルが届く最大距離
    [SerializeField] private int circleSegments = 64;      // 円をなめらかに見せる頂点数

    private Camera mainCamera;
    private Vector3 casterPosition;

    private void Awake()
    {
        mainCamera = Camera.main;
        casterPosition = transform.position;
        DrawRangeCircle();
    }

    private void DrawRangeCircle()
    {
        rangeLine.positionCount = circleSegments + 1;
        for (var i = 0; i <= circleSegments; i++)
        {
            var angle = i * Mathf.PI * 2f / circleSegments;
            var offset = new Vector3(Mathf.Cos(angle), 0.02f, Mathf.Sin(angle)) * castRange;
            rangeLine.SetPosition(i, casterPosition + offset);
        }
    }
}

    private void Update()
    {
        if (!TryMoveMarkerToMouse(out var isInRange)) return;
        UpdateMarkerColor(isInRange);

        if (Input.GetMouseButtonDown(0) && isInRange)
        {
            CastAt(targetMarker.position);
        }
    }

    private bool TryMoveMarkerToMouse(out bool isInRange)
    {
        isInRange = false;
        var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
        if (!Physics.Raycast(ray, out var hit, 200f, LayerMask.GetMask("Ground"))) return false;
    
        var flatTarget = hit.point;
        flatTarget.y = casterPosition.y + 0.04f;
        targetMarker.position = flatTarget;
    
        var distance = Vector3.Distance(casterPosition, flatTarget);
        isInRange = distance <= castRange;
        return true;
    }

    private void UpdateMarkerColor(bool isInRange)
    {
        var renderer = targetMarker.GetComponent<Renderer>();
        renderer.material.color = isInRange
            ? new Color(0.25f, 1f, 0.7f, 0.9f)   // 届く場所は緑
            : new Color(1f, 0.25f, 0.25f, 0.9f); // 届かない場所は赤
    }

    private void CastAt(Vector3 point)
    {
        Debug.DrawLine(casterPosition, point, Color.cyan, 0.5f);
        Debug.Log($"スキルを発動: {point}");
    }
}

動作確認

  1. Play を押します。Playerの足元に水色の円が出ます。
  2. マウスを円の内側へ動かします。照準が緑になります。
  3. 円の外側へ動かします。照準が赤になります。
  4. 緑の照準で左クリックします。Consoleに発動位置が出て、Debug LineでPlayerから照準へ線が引かれます。

まとめ

射程UIは、射程円を描く、地面の位置を取る、距離で色を変える、クリックで発動する、の4つで作れます。次は CastAt の中でPrefabを生成すれば、実際の弾や範囲攻撃へ広げられます。

はじめちゃん
射程外をクリックしても発動しないのは、どこで決めますか?
ココ先生
Playerから照準までの距離がcastRange以内かを確認してからCastAtを呼びます。
はじめちゃん
流れは「準備状態を表示」から始めて、「Next Buttonで進める」で操作を入れる、と覚えればよいですか?
ココ先生
その通りです。その後に「操作中を確認」で途中状態を見て、「結果表示で結果を見る」で結果を確認します。順番を固定すると、失敗した場所も見つけやすくなります。
はじめちゃん
つまり、いきなり完成システムにせず、状態名、表示、値の変化を小さくそろえるのですね。
ココ先生
はい。最後は「スキル射程と発動確定を迷わせない戦闘UI設計ガイドをわかりやすく考える」の考え方で、難しい処理をプレイヤーに伝わる短い合図へ置き換えられるか確認しましょう。
この記事のまとめを案内するガイドキャラクター

この記事のまとめ

射程円、予測ライン、確定前の注意表示を使って、攻撃や回復スキルの失敗感を減らすための設計を整理します。

大きな違いを生むのは、派手な性能よりも 毎日触れる環境を無理なく整えること です。見やすい画面と使いやすい道具がそろうと、学習や次の一歩を決めやすくなります。