はじめに
ゲーム画面で、点を結んだ折れ線や曲線を描きたいことがあります。例えば、プレイヤーから敵への弾道表示、ロープの物理表現、電線のしなり、ミニマップ上の移動ルート—これらはすべて「線」で表現できます。そこで活躍するのが Line2D です。
この記事では、Line2D の基本的な描画から、プロパティのカスタマイズ、add_point() / remove_point() メソッドを使った動的な線の生成まで、実践的なテクニックを解説します。
Line2Dとは?
Line2D は、複数の点を結んで折れ線や曲線を描画するノードです。シンプルな API で柔軟な線描画ができ、ゲームの視覚表現やデバッグ用のパスの可視化まで幅広く活用できます。
例えるなら、方眼紙の上で定規を使わずフリーハンドで線を引く—複数のポイントが自動的に結ばれて滑らかな(または角張った)線になります。
継承ツリー:
Line2D → Node2D → Node → Object
このノードを使うべき場面
使うべき場面
- 弾道表示:射撃ゲームで銃の射撃角度や弾道をプレビュー
- ロープ・チェーン表現:つり橋や懸垂線、ロープの物理表現
- 電線・パイプ:建物や機械のディテール表現
- パス・ルート表示:ミニマップやナビゲーション経路の可視化
- HP バー等のカスタム UI:曲線のプログレスバー(Rect2D とは異なる表現)
使わない場面
- 図形の塗りつぶし:中身を塗る場合は Polygon2D を使用
- 複雑な描画:複雑な図形は Polygon2D や ShaderMaterial を検討
主なプロパティと機能
| プロパティ | 型 | 説明 |
|---|---|---|
points |
PackedVector2Array | 線を構成するポイント座標の配列。add_point() で追加 |
width |
float | 線の太さ(ピクセル単位) |
default_color |
Color | 線の色 |
texture |
Texture2D | 線に貼るテクスチャ(例:電線のような模様) |
texture_mode |
TextureMode | テクスチャの貼り方(NONE, TILE, WORLD) |
joint_mode |
LineJointMode | 線のコーナー表示(SHARP=尖った、BEVEL=面取り、ROUND=丸い) |
end_cap_mode |
LineCapMode | 線の両端の形状(NONE、ROUND、SQUARE) |
antialiased |
bool | アンチエイリアス有効化(より滑らかに見える) |
基本的な使用例1:点を追加して線を描画
extends Node2D
@onready var line = $Line2D
func _ready():
# 線のプロパティを設定
line.width = 5.0
line.default_color = Color.WHITE
line.joint_mode = Line2D.LINE_JOINT_MODE_ROUND
line.end_cap_mode = Line2D.LINE_CAP_MODE_ROUND
# 点を追加して線を描画
line.add_point(Vector2(0, 0))
line.add_point(Vector2(100, 50))
line.add_point(Vector2(200, 100))
line.add_point(Vector2(300, 50))
line.add_point(Vector2(400, 200))
動的な線の生成例2:マウスドラッグで線を描画
extends Node2D
@onready var line = $Line2D
var is_drawing = false
func _ready():
line.width = 3.0
line.default_color = Color.CYAN
line.antialiased = true
func _input(event):
if event is InputEventMouseButton:
if event.pressed:
# 描画開始
is_drawing = true
line.clear_points()
line.add_point(event.position)
else:
# 描画終了
is_drawing = false
func _process(delta):
if is_drawing:
var mouse_pos = get_global_mouse_position()
# 最後の点と異なる場合のみ追加(性能最適化)
if line.points[-1].distance_to(mouse_pos) > 5:
line.add_point(mouse_pos)

もっと使いこなす:カスタマイズできるパラメータ
| パラメータ | 推奨値・用途 | 解説 |
|---|---|---|
width |
1 ~ 20 | 細い線は1〜3、太い線は5〜20。GUI 線は細く、視認重視は太く |
joint_mode |
ROUND / BEVEL | ROUND は柔らかい印象、BEVEL は角張った印象 |
end_cap_mode |
ROUND / SQUARE | ROUND は丸い終端(自然)、SQUARE は四角い終端(明確) |
texture_mode |
TILE / WORLD | TILE=線に沿ってテクスチャ繰り返し、WORLD=ワールド座標に合わせる |
antialiased |
true | ギザギザ防止。やや処理が重くなるが、見た目が向上 |
Line2D メソッド リファレンス
| メソッド | 説明 |
|---|---|
add_point(point, index = -1) |
点を追加。index を指定するとその位置に挿入 |
remove_point(i) |
指定インデックスの点を削除 |
clear_points() |
すべての点を削除(線が消える) |
get_point_count() |
点の個数を取得 |
set_point_position(i, pos) |
指定インデックスの点の位置を更新 |
get_point_position(i) |
指定インデックスの点の位置を取得 |

実践例:弾道予測線の表示
extends Node2D
@onready var trajectory_line = $Line2D
var start_pos: Vector2
var target_pos: Vector2
var gravity: float = 980.0
func _ready():
trajectory_line.width = 2.0
trajectory_line.default_color = Color.YELLOW
trajectory_line.joint_mode = Line2D.LINE_JOINT_MODE_BEVEL
func _process(delta):
start_pos = global_position
target_pos = get_global_mouse_position()
# マウス位置への弾道を計算して表示
draw_trajectory(start_pos, target_pos)
func draw_trajectory(from: Vector2, to: Vector2):
trajectory_line.clear_points()
var distance = from.distance_to(to)
var angle = from.angle_to_point(to)
# 初速度を仮定
var initial_velocity = 500.0
var v_x = initial_velocity * cos(angle)
var v_y = initial_velocity * sin(angle)
var time_step = 0.05
var total_time = 2.0
for t in range(0, int(total_time / time_step)):
var time = t * time_step
var x = from.x + v_x * time
var y = from.y + v_y * time + 0.5 * gravity * time * time
trajectory_line.add_point(Vector2(x, y))
# 画面外に出たら終了
if Vector2(x, y).distance_to(from) > 1000:
break
まとめ
Line2D は、シンプルながら強力な線描画ノードです。add_point() / remove_point() で動的に線を生成・変形でき、joint_mode や end_cap_mode で見た目を細かく調整できます。弾道、ロープ、パス表示など、多彩なゲーム表現を実現します。
- 動的な線生成:add_point() で点を追加・remove_point() で削除、線を自由に操作
- 見た目のカスタマイズ:width、color、joint_mode、end_cap_mode で多彩な線表現が可能
- 実践活用:弾道、ロープ、電線、ミニマップルート など幅広い用途
次回は「CanvasLayer」をお届けします。HUD やミニマップ、フェード暗幕など、カメラに依存しない独立レイヤーの描画方法を解説します!
シリーズ:Godot 4 ノード解説
- 001: Node2D
- 002: Sprite2D
- 003: CollisionShape2D
- 004: CharacterBody2D
- 005: RigidBody2D
- 006: Area2D
- 007: Control
- 008: Button
- 009: Label
- 010: TextEdit
- 011: ItemList
- 012: TabContainer
- 013: Timer
- 014: Tween
- 015: Camera2D
- 016: ParallaxBackground
- 017: TileMap(旧)
- 018: Path2D
- 019: PathFollow2D
- 020: RemoteTransform2D
- 021: Marker2D
- 022: Node
- 023: Resource
- 024: Script
- 025: Signal
- 026: Input
- 027: Physics2DServer
- 028: VisibleOnScreenNotifier2D
- 029: RayCast2D
- 030: ShapeCast2D
- 031: PinJoint2D
- 032: DistanceJoint2D
- 033: HingeJoint2D
- 034: SliderJoint2D
- 035: ConeTwistJoint2D
- 036: Generic6DOFJoint2D
- 037: Polygon2D
- 038: ColorRect
- 039: NinePatchRect
- 040: TextureRect
- 041: StaticBody2D
- 042: TileMapLayer
- 043: AnimationPlayer
- 044: AnimationTree
- 045: AudioStreamPlayer
- 046: AudioStreamPlayer2D
- 047: GPUParticles2D
- 048: CPUParticles2D
- 049: Line2D
- 050: CanvasLayer
この記事はGodot 4.xをもとに執筆しています。


コメント