【Cocos Creator 3.8】FleeBehavior(逃走AI)の実装:アタッチするだけで「HPが減ったらプレイヤーから全力で逃げる」動きを実現する汎用スクリプト
このコンポーネントは、敵キャラなどにアタッチするだけで「HPが一定値を下回ったらプレイヤーから逃げる」挙動を実現する汎用逃走AIです。
プレイヤーのノード参照と、移動速度・逃走開始HPなどをインスペクタから設定するだけで動作し、他のカスタムスクリプトには一切依存しません。
コンポーネントの設計方針
本コンポーネント FleeBehavior は、以下の要件を満たすように設計します。
- HPを内部で管理(外部のHP管理スクリプトに依存しない)。
- HPが「最大HPに対する割合」または「絶対値」で閾値を下回ったら逃走モードに入る。
- 逃走時は「プレイヤーノードの位置」と「自分の位置」から方向ベクトルを計算し、プレイヤーの逆方向へ一定速度で移動する。
- プレイヤーの参照は
@property(Node)でインスペクタから指定する。 - 物理挙動に依存しない(
RigidBodyなど不要)。Transform の位置を直接変更するシンプルな実装。 - 他のスクリプトへの依存を一切持たない。「HPを減らす」操作も、デバッグ用にインスペクタからテストできるようにする。
また、防御的な実装として、以下を行います。
- プレイヤーノードが設定されていない場合は警告ログを出して逃走処理をスキップ。
- 最大HPが0以下など、明らかに不正な設定値の場合は警告を出し、内部で安全なデフォルト値に補正。
インスペクタで設定可能なプロパティ設計
以下のプロパティを用意します。
playerNode: Node | null
逃走対象(プレイヤー)となるノードへの参照。
インスペクタでシーン上のプレイヤーノードをドラッグ&ドロップして設定します。
未設定の場合は警告を出し、逃走処理は行いません。maxHp: number
このキャラクターの最大HP。初期HPはこの値で初期化されます。
例: 100
0以下が設定された場合は警告を出し、内部的に1に補正します。currentHp: number
現在HP。
通常はゲーム中に他のスクリプトから変更される想定ですが、本コンポーネントは単体で完結させるため、インスペクタから直接変更して挙動確認できるように公開します。
onLoad時にmaxHpで初期化されます。useHpRatioThreshold: boolean
逃走開始条件を「割合」で見るか「絶対値」で見るかを切り替えるフラグ。true: HP割合で判定(例: 0.3 → 30%未満で逃走)。false: HP絶対値で判定(例: 30 → HPが30未満で逃走)。
fleeHpRatioThreshold: number
useHpRatioThreshold = trueのときに使用。
「最大HPに対する割合」で逃走を開始するしきい値。
例: 0.3 → HPが最大HPの30%未満になったら逃走開始。
0〜1の範囲で設定します。fleeHpThreshold: number
useHpRatioThreshold = falseのときに使用。
HPがこの値を下回ったら逃走開始。
例: 30 → HPが30未満になったら逃走開始。fleeSpeed: number
逃走時の移動速度(1秒あたりのワールド単位)。
例: 300(2Dゲームなら 100〜500 程度が目安)。stopFleeDistance: number
プレイヤーとの距離がこの値以上になったら、逃走をやめる距離(安全距離)。
例: 800
0以下の場合は「距離による停止なし」とみなします。enableDebugLog: boolean
逃走開始・停止などの状態変化をログ出力するかどうか。
デバッグ用で、本番ではオフにする想定。simulateDamagePerSecond: number
デバッグ用の「毎秒自動で減少させるHP量」。
例: 10 → 1秒ごとに10ダメージを受けるように減少。
0の場合は自動ダメージなし。
これにより、本コンポーネント単体でHP減少〜逃走挙動を確認可能です。
TypeScriptコードの実装
以下が完成した FleeBehavior.ts の全コードです。
import { _decorator, Component, Node, Vec3, math, CCFloat } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('FleeBehavior')
export class FleeBehavior extends Component {
@property({
type: Node,
tooltip: '逃走対象となるプレイヤーノード。\nここで指定したノードの位置から離れる方向へ移動します。'
})
public playerNode: Node | null = null;
@property({
tooltip: '最大HP。この値で現在HPが初期化されます。\n0以下は無効として1に補正されます。'
})
public maxHp: number = 100;
@property({
tooltip: '現在HP。onLoad時にmaxHpで初期化されます。\nデバッグ時はインスペクタから直接変更して挙動確認できます。'
})
public currentHp: number = 100;
@property({
tooltip: '逃走開始条件をHP割合で判定するかどうか。\ntrue: fleeHpRatioThresholdを使用\nfalse: fleeHpThresholdを使用'
})
public useHpRatioThreshold: boolean = true;
@property({
type: CCFloat,
tooltip: 'HP割合での逃走開始しきい値。\n0.3 の場合、最大HPの30%未満で逃走開始。\nuseHpRatioThresholdがtrueのときのみ使用されます。'
})
public fleeHpRatioThreshold: number = 0.3;
@property({
tooltip: 'HP絶対値での逃走開始しきい値。\nHPがこの値を下回ると逃走開始。\nuseHpRatioThresholdがfalseのときのみ使用されます。'
})
public fleeHpThreshold: number = 30;
@property({
type: CCFloat,
tooltip: '逃走時の移動速度(1秒あたりのワールド単位)。'
})
public fleeSpeed: number = 300;
@property({
type: CCFloat,
tooltip: 'プレイヤーとの距離がこの値以上になったら逃走を停止する安全距離。\n0以下の場合は距離による停止判定を行いません。'
})
public stopFleeDistance: number = 800;
@property({
tooltip: 'trueにすると、逃走開始・停止などの状態変化をログ出力します。'
})
public enableDebugLog: boolean = false;
@property({
type: CCFloat,
tooltip: 'デバッグ用:毎秒自動的に減少させるHP量。\n0の場合は自動ダメージなし。\nゲーム内でダメージ処理がない場合でも、本コンポーネント単体で挙動確認できます。'
})
public simulateDamagePerSecond: number = 0;
// 内部状態管理用
private _isFleeing: boolean = false;
private _accumulatedTimeForDamage: number = 0;
onLoad() {
// maxHp のバリデーションと補正
if (this.maxHp
主要な処理のポイント解説
onLoadmaxHpが0以下の場合に1へ補正し、currentHpをmaxHpで初期化。playerNodeが未設定の場合に警告ログを出力。
update(deltaTime)
毎フレーム呼ばれ、以下を行います。_updateSimulatedDamage:simulateDamagePerSecondに応じて自動的にHPを減少させる(デバッグ用)。_updateFleeState:HP条件に応じて_isFleeingフラグを更新。_isFleeingがtrueの場合、_moveAwayFromPlayerでプレイヤーの逆方向に移動。
_shouldFleeByHp()useHpRatioThresholdがtrueのとき:currentHp / maxHp < fleeHpRatioThresholdで判定。falseのとき:currentHp < fleeHpThresholdで判定。
_moveAwayFromPlayer(deltaTime)playerNode.worldPositionとthis.node.worldPositionから「プレイヤー→自分」方向ベクトルを計算。- 正規化して逃走方向とし、
fleeSpeed * deltaTimeだけ移動。 stopFleeDistanceが設定されていれば、プレイヤーとの距離がそれ以上になったときに逃走を停止。
simulateDamagePerSecond- ゲームの他部分に依存せず、本コンポーネント単体で「HPが減る → 逃走開始」の流れを確認するための仕組み。
- 本番では0にしておき、必要であれば他スクリプトから
applyDamage()を呼び出す運用も可能。
使用手順と動作確認
ここでは、Cocos Creator 3.8.7 のエディタ上で FleeBehavior を実際に使って動作確認する手順を説明します。
1. スクリプトファイルの作成
- Assets パネルで空いているフォルダ(例:
assets/scripts)を右クリックします。 Create → TypeScriptを選択し、ファイル名をFleeBehavior.tsとします。- 作成された
FleeBehavior.tsをダブルクリックしてエディタで開き、既存のテンプレートコードをすべて削除して、前述の TypeScript コードを丸ごと貼り付けて保存します。
2. テスト用シーンの準備
プレイヤーと敵キャラ用のノードを用意します。
- Hierarchy パネルで右クリック →
Create → 2D Object → Spriteを選択し、ノード名をPlayerに変更します。- Sprite フレームは何でも構いません(デフォルトでもOK)。
- 位置は
(0, 0, 0)付近に配置しておきます。
- 同様に、Hierarchy パネルで右クリック →
Create → 2D Object → Spriteを選択し、ノード名をEnemyに変更します。- こちらにも適当な Sprite フレームを設定します。
- 位置はプレイヤーから少し離れた場所(例:
(300, 0, 0))に配置しておきます。
3. Enemy に FleeBehavior をアタッチ
- Hierarchy で
Enemyノードを選択します。 - Inspector パネルの下部にある
Add Componentボタンをクリックします。 Custom Componentカテゴリ内にあるFleeBehaviorを選択して追加します。
4. インスペクタでプロパティを設定
Enemy ノードを選択した状態で、Inspector に表示される FleeBehavior の各プロパティを以下のように設定してみましょう。
Player Node: Hierarchy からPlayerノードをドラッグ&ドロップして割り当てます。Max Hp:100Current Hp: 自動で100が入っていればOK(編集不要)。Use Hp Ratio Threshold:true(オン)Flee Hp Ratio Threshold:0.3(HP30%未満で逃走開始)Flee Hp Threshold:30(今回は割合判定なので無視されます)Flee Speed:300Stop Flee Distance:800Enable Debug Log:true(ログを見たい場合)Simulate Damage Per Second:20(1秒ごとに20ダメージを受ける想定)
5. シミュレーションで動作確認
- エディタ右上の
▶︎ Playボタンを押してゲームを実行します(または Preview ウィンドウで実行)。 - 開始直後は HP が満タン(100)なので、
Enemyは静止しているはずです。 - 数秒経過すると、
Simulate Damage Per Second = 20により HP が減少していき、HPが 30% を下回るタイミング(今回の設定では HP < 30)で_isFleeingがtrueになり、Enemyがプレイヤーから離れる方向へ移動し始めます。 Stop Flee Distance = 800により、プレイヤーから十分離れると逃走を停止します。Enable Debug Log = trueにしている場合、Console に「逃走開始」「逃走停止」「自動ダメージ」などのログが表示されるので、状態変化を確認できます。
6. 手動でHPを減らしてテストしたい場合
自動ダメージではなく、インスペクタから手動でHPを減らして挙動を確認することもできます。
Simulate Damage Per Secondを0に設定して自動ダメージを無効化します。- ゲームを実行した状態で、
Enemyノードを選択し、Current Hpの値を手動で変更します。- 例: 100 → 60 → 40 → 20 と減らしていく。
- HPがしきい値(割合 or 絶対値)を下回ったタイミングで逃走が開始されるのを確認できます。
7. 絶対値しきい値でのテスト(オプション)
割合ではなく絶対値しきい値で逃走させたい場合は、以下のように設定を変えて挙動を確認できます。
Use Hp Ratio Thresholdをfalseに変更。Flee Hp Thresholdを50に設定(例)。- ゲーム実行後、
Current Hpを 100 → 60 → 40 と手動で変更すると、HPが50を下回ったタイミングで逃走が開始されることを確認できます。
まとめ
この FleeBehavior コンポーネントは、
- プレイヤーノードの参照
- HP関連パラメータ(最大HP、逃走開始しきい値)
- 移動速度や安全距離
- デバッグ用の自動ダメージ量
といった設定をインスペクタから行うだけで、
- HPが一定以下になるとプレイヤーから逃げる
- プレイヤーから十分離れたら逃走をやめる
という逃走AIを簡単に実現できます。
ポイントは、
- HP管理を内部に持たせることで、他のHP管理スクリプトに依存しない「完全に独立したコンポーネント」として設計していること。
simulateDamagePerSecondやapplyDamage()を用意することで、「単体で挙動確認しやすい」「他プロジェクトにも使い回しやすい」構造になっていること。- Transform の直接移動のみで完結しており、RigidBody 等の物理コンポーネントを必須にしていないため、2D/3D問わず幅広いシーンで利用できること。
このように、1つのノードにアタッチするだけで完結する汎用コンポーネントを積み重ねていくことで、ゲームごとの共通処理をライブラリ化しやすくなり、Cocos Creator での開発効率を大きく高めることができます。
本コンポーネントをベースに、
- 逃走中はアニメーションを切り替える
- 一定時間だけ逃走してから自動的に消える
- HPが回復したら追跡モードに戻る
といった拡張も容易に行えるので、ぜひプロジェクトに合わせてカスタマイズしてみてください。




