DxLibで敵がプレイヤーを追いかける処理を作りたい。
でも、「どうやって実装すればいいのか分からない」そんな風に感じていませんか。
実は、DxLibで追尾処理を実装する方法は、角度計算と移動処理を組み合わせることで実現できます。
DxLibの簡単なAPIを使えば、初心者でも追尾システムを作ることができるでしょう。
この記事では、DxLibでの追尾処理の考え方と実装例を、コピペで動くサンプルコードとともに詳しく解説します。
✨ この記事でわかること
- 追尾処理の基本的な考え方と実装方法(所要30分)
- DxLibを使った角度計算と移動処理(所要1時間)
- 追尾速度の制御と滑らかな移動の実装(所要1時間)
- DxLib追尾処理でよくあるエラー5選と解決方法
- 実用的な追尾システム完成までの3ステップ(合計3時間)

最初は直線的に追尾する実装から始めて、徐々に滑らかな動きを追加するのがコツです。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
追尾処理とは?基礎知識から理解する
![]()
追尾処理とは、敵キャラがプレイヤーの位置を認識し、その方向に向かって移動する処理のこと。
シューティングゲームでは基本的な機能です。
追尾処理を実装するには、角度計算と移動処理が重要になります。
プレイヤーと敵の位置から方向ベクトルを計算し、その方向に移動させます。
移動速度を制御することで、自然な追尾動作を実現できるでしょう。
追尾処理は、敵AIの基本的な機能の一つです。
適切に実装することで、プレイヤーに緊張感を与えるゲームプレイを提供できます。
また、追尾処理を応用することで、より複雑なAI行動を実装することも可能です。
追尾処理に必要な要素
✅ 追尾処理に必要な要素
- 位置の取得:プレイヤーと敵の座標を取得する処理(所要時間:15分)
- 方向ベクトルの計算:2点間の方向を計算する処理(所要時間:30分)
- 移動処理:計算した方向に移動する処理(所要時間:30分)
- 速度制御:追尾速度を調整する処理(所要時間:30分)
位置の取得は、追尾処理の最初のステップです。
プレイヤーと敵の現在位置を取得することで、追尾の方向を決定できます。
方向ベクトルの計算は、2点間の方向を求める処理です。
プレイヤーの位置から敵の位置を引くことで、方向ベクトルが得られます。
移動処理は、計算した方向ベクトルを使って敵を移動させる処理。
速度制御は、追尾の速度を調整する処理です。
速度を調整することで、難易度やゲームバランスを調整できます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
DxLibを使った追尾処理の実装方法
![]()
DxLibを使った追尾処理を実装する方法を解説します。
ここでは、コピペで動くサンプルコードを紹介します。
実装手順:基本的な追尾システムを作る
ステップ1:敵の構造体を定義(所要10分)
まず、敵キャラを管理するための構造体を作成します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include "DxLib.h" #include struct Enemy { float x, y; // 敵の座標 float speed; // 移動速度 }; Enemy enemy; enemy.x = 100.0f; enemy.y = 100.0f; enemy.speed = 2.0f; float playerX = 320.0f; float playerY = 240.0f; |
|
1 |
構造体を使うことで、敵の情報を整理して管理できます。
x, yは敵の現在位置、speedは追尾速度です。
初期位置と速度を設定することで、追尾処理の準備が整います。
ステップ2:追尾処理の実装(所要30分)
以下のコードで、敵がプレイヤーを追尾する処理を実装できます。
|
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 44 45 |
void UpdateEnemy() { // プレイヤーへの方向ベクトルを計算 float dx = playerX - enemy.x; float dy = playerY - enemy.y; // 距離を計算 float distance = sqrtf(dx * dx + dy * dy); // 正規化(単位ベクトルにする) if (distance > 0) { dx /= distance; dy /= distance; // 敵を移動 enemy.x += dx * enemy.speed; enemy.y += dy * enemy.speed; } } void DrawEnemy() { DrawCircle(enemy.x, enemy.y, 15, GetColor(255, 0, 0), TRUE); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { if (DxLib_Init() == -1) return -1; while (ProcessMessage() == 0) { ClearDrawScreen(); // プレイヤーの位置をマウスで制御(テスト用) GetMousePoint(&playerX, &playerY); UpdateEnemy(); DrawEnemy(); // プレイヤーも描画 DrawCircle(playerX, playerY, 10, GetColor(0, 255, 0), TRUE); ScreenFlip(); } DxLib_End(); return 0; } |
配置場所:メインのソースファイルに記述
確認方法:マウスを動かすと、赤い円(敵)が緑の円(プレイヤー)を追尾すればOK
方向ベクトルの計算では、プレイヤーの位置から敵の位置を引きます。
距離を計算し、正規化することで単位ベクトルが得られます。
単位ベクトルに速度を掛けることで、敵を移動させます。
距離が0の場合のゼロ除算を避けるため、if文でチェックしています。
⚠️ よくあるエラー
- 敵が動かない → UpdateEnemy関数が毎フレーム呼ばれているか確認
- 敵が速すぎる/遅すぎる → enemy.speedの値を調整する(目安:1.0f〜3.0f)
- ゼロ除算エラー → distanceが0の場合は処理をスキップ(if (distance > 0)のチェックを必ず入れる)
より高度な追尾処理の実装
基本的な追尾処理に加えて、より自然な動きを実現する方法を紹介します。
例えば、距離に応じて速度を変える処理を追加できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
void UpdateEnemyAdvanced() { float dx = playerX - enemy.x; float dy = playerY - enemy.y; float distance = sqrtf(dx * dx + dy * dy); if (distance > 0) { // 距離が遠いほど速く、近いほど遅くする float speedMultiplier = distance / 100.0f; speedMultiplier = (speedMultiplier > 1.0f) ? 1.0f : speedMultiplier; dx /= distance; dy /= distance; enemy.x += dx * enemy.speed * speedMultiplier; enemy.y += dy * enemy.speed * speedMultiplier; } } |
この実装では、距離に応じて速度を調整します。
遠い時は速く、近い時は遅く移動するため、より自然な動きになります。
また、一定距離で停止する処理を追加することも可能です。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
追尾処理の最適化と応用
![]()
追尾処理の最適化と応用について解説します。
より効率的で高度な追尾システムを実装できるでしょう。
フレームレートに依存しない移動
現在の実装では、フレームレートに依存して移動速度が変わってしまいます。
フレームレートに依存しない移動を実装することで、どの環境でも一定の速度で移動できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void UpdateEnemyFrameIndependent() { float dx = playerX - enemy.x; float dy = playerY - enemy.y; float distance = sqrtf(dx * dx + dy * dy); if (distance > 0) { dx /= distance; dy /= distance; // フレーム時間を考慮した移動 float deltaTime = 1.0f / 60.0f; // 60FPSを想定 enemy.x += dx * enemy.speed * deltaTime; enemy.y += dy * enemy.speed * deltaTime; } } |
deltaTimeを使うことで、フレームレートに関係なく一定の速度で移動できます。
実際のフレームレートを取得する場合は、GetNowCount()などの関数を使います。
複数敵の追尾処理
複数の敵を追尾させる場合、配列を使って管理します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
struct Enemy { float x, y; float speed; }; Enemy enemies[10]; // 最大10体の敵 void UpdateAllEnemies() { for (int i = 0; i < 10; i++) { float dx = playerX - enemies[i].x; float dy = playerY - enemies[i].y; float distance = sqrtf(dx * dx + dy * dy); if (distance > 0) { dx /= distance; dy /= distance; enemies[i].x += dx * enemies[i].speed; enemies[i].y += dy * enemies[i].speed; } } } |
配列を使って複数の敵を管理することで、大量の敵を追尾させることができます。
各敵は独立してプレイヤーを追尾します。
一定距離で停止する処理
敵がプレイヤーに近づきすぎないようにする処理を追加できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
void UpdateEnemyWithStop() { float dx = playerX - enemy.x; float dy = playerY - enemy.y; float distance = sqrtf(dx * dx + dy * dy); const float stopDistance = 50.0f; // 停止距離 if (distance > stopDistance) { dx /= distance; dy /= distance; enemy.x += dx * enemy.speed; enemy.y += dy * enemy.speed; } } |
一定距離以内になると、敵は停止します。
これにより、敵がプレイヤーに張り付くのを防げます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
DxLib追尾処理でよくある失敗5選と解決方法
![]()
DxLibで追尾処理を実装する際、初心者が陥りやすい失敗があります。
ここでは、5つのよくある失敗と解決方法を紹介します。
失敗1:ゼロ除算エラーが発生する
❌ よくある失敗
- プレイヤーと敵の距離が0の時にエラーが発生する
- 正規化処理でゼロ除算が起きる
- ゲームがクラッシュする
- if文のチェックを忘れる
ゼロ除算エラーは、プレイヤーと敵が同じ位置にいる時に発生します。
距離が0の場合、正規化処理でゼロ除算が発生してしまいます。
✅ 正しいアプローチ
- 距離が0より大きい場合のみ処理を実行する
- if (distance > 0) のチェックを必ず入れる
- 最小距離を設定して完全に重ならないようにする
- 距離が非常に小さい場合の処理を追加する
失敗2:追尾速度が速すぎる/遅すぎる
追尾速度が適切でないと、ゲームバランスが崩れます。
速度の調整方法を理解することが重要です。
解決方法:
- speedの値を調整する(例:1.0f〜3.0f、デフォルトは2.0f)
- 距離に応じて速度を変える(近い時は遅く、遠い時は速く)
- フレームレートに依存しない時間ベースの移動を使用する
- ゲームテストを行い、適切な速度を見つける
失敗3:敵がプレイヤーを通り越してしまう
敵がプレイヤーを通り越してしまう場合、速度が速すぎる可能性があります。
距離をチェックして、プレイヤーに近づきすぎないようにする処理を追加しましょう。
⚠️ 解決方法
- 移動前に距離をチェックする
- 一定距離で停止する処理を追加する
- 移動量が距離を超えないようにする
- 速度を適切に調整する
失敗4:フレームレートに依存して速度が変わる
フレームレートが変わると、移動速度も変わってしまいます。
時間ベースの移動を実装することで解決できます。
解決方法:
- deltaTimeを使った時間ベースの移動を実装する
- GetNowCount()などで実際のフレーム時間を取得する
- 固定フレームレートを想定した実装にする
- テスト環境と本番環境でフレームレートの違いを考慮する
失敗5:複数敵の処理が重い
複数の敵を追尾させる場合、処理が重くなる可能性があります。
最適化を行うことで、処理速度を改善できます。
⚠️ 解決方法
- 距離の計算でsqrtfを使わず、距離の2乗で比較する
- 画面外の敵は処理をスキップする
- 必要な敵のみを処理する
- 処理を分散させて負荷を軽減する
初心者がよくやる勘違い
初心者がよくやる勘違いとして、角度計算を使わずに移動しようとすることがあります。
角度を使わずに方向ベクトルを使うことで、より簡単に実装できます。
また、毎フレームUpdateEnemy関数を呼ぶことを忘れる場合もあります。
ゲームループ内で必ず呼び出すことが重要です。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
実用的な追尾システム完成までの3ステップ
![]()
- STEP1基本的な追尾処理(所要1時間)
プレイヤーの位置に向かって敵が移動する処理を実装する。
方向ベクトルの計算と正規化を学ぶ。
学べること:方向ベクトルの計算、正規化、基本的な移動処理
成果物:敵がプレイヤーを追尾するシステム
- STEP2速度制御の追加(所要1時間)
追尾速度を調整し、自然な動きを実現する。
距離に応じた速度調整を追加する。
学べること:速度の制御、距離に応じた処理、フレームレートに依存しない移動
成果物:速度が調整された追尾システム
- STEP3最適化と追加機能(所要1時間)
一定距離で停止、複数敵の管理などの機能を追加する。
処理の最適化を行う。
学べること:条件分岐、配列管理、処理の最適化
成果物:実用的な追尾システム
合計3時間で、実用的な追尾システムが完成します。
実装時のチェックリスト
✅ 実装時のチェックリスト
- 方向ベクトルの計算が正しく実装されているか
- ゼロ除算のチェックが入っているか
- 速度が適切に設定されているか
- 毎フレームUpdateEnemy関数が呼ばれているか
- 敵がプレイヤーを正しく追尾しているか
- 複数敵の場合は配列で管理できているか
- フレームレートに依存しない移動になっているか
- ゲームテストで問題がないか
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
まとめ
![]()
DxLibで敵が自機を追う動きを作る方法は、角度計算と移動処理を組み合わせることで実現できます。
DxLibの簡単なAPIを使えば、初心者でも追尾システムを作ることができるでしょう。
✅ 記事の要点まとめ
- 追尾処理の基本:方向ベクトルの計算と正規化、位置の取得、移動処理、速度制御
- DxLib実装:敵の構造体定義、方向ベクトル計算、正規化、移動処理、マウス追尾の実装例
- 高度な実装:距離に応じた速度調整、フレームレートに依存しない移動、複数敵の管理、一定距離で停止する処理
- よくある失敗5選:ゼロ除算、速度制御、通り越し、フレームレート依存、複数敵の処理が重い
- 実用的なシステム:3ステップで完成(合計3時間)
今日から始める3ステップ:
- STEP1:敵の構造体を定義する(所要10分)
- STEP2:方向ベクトル計算と追尾処理を実装する(所要30分)
- STEP3:速度制御を追加する(所要30分)
あなたのペースで、少しずつ進めていけば大丈夫です。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる



コメント