繰り返し使う処理をまとめようとして右クリックメニューを開くと、FunctionとMacroが並んでいます。どちらで作ればいいのか、迷いやすいところです。
どちらも「処理をまとめる道具」に見えますが、 動作原理がまったく違います 。Functionは呼び出されるサブルーチン、Macroはコンパイル時にその場へ書き写されるコピーの型です。この違いから「Delayが使えるか」「実行ピンを分岐できるか」という決定的な差が生まれます。
この記事では、FunctionとMacroの違いと使い分けを動作原理から解説します。最後に、アクションゲームの「スキルのクールダウン」を2つの道具で組む実践も紹介します。
この記事でわかること
- Functionは呼ばれ、Macroは書き写される という動作原理の違い
- Delayの可否 と 実行ピンの分岐 という2つの決定的な差
- 選び方の原則: 基本はFunction、例外だけMacro
- 実践:スキルの クールダウン をFunctionとMacroの分担で組む
Functionの基本:呼び出される「関数」
Functionはプログラミングの「関数」そのものです。入力を受け取り、処理して、結果を返します。呼び出し元から 呼ばれて、終わったら戻る サブルーチンとして動く仕組みです。

| 特徴 | 詳細 |
|---|---|
| 実行フロー | 入口(実行ピン)1つ・出口(Return)1つ。開始から終了まで一気に実行される |
| 遅延実行ノード | Delay や Timeline は 使用不可 |
| ローカル変数 | Function内で定義できる(→ Blueprint変数入門) |
| 再帰呼び出し | 可能 |
| Pure Function | 実行ピンなしの「純粋な計算」ノードを作れる |
| デバッグ | 実行フローが明確で追いやすい |
たとえば「ターゲットが射程内か」を判定する処理は、Functionの典型です。
Function: IsWithinRange(Pure・入力: TargetLocation, Range → 出力: Boolean)
→ 自分の位置とTargetLocationの距離を計算 → Range以下かを返す
状態を変えず、値を計算して返すだけの処理です。こうした処理はPure Functionにすると、実行ピンなしのすっきりしたノードとして呼び出せます。
Macroの基本:書き写される「スタンプ」
Macroは関数ではなく、 ノードのまとまりを登録しておくスタンプ です。呼び出すたびに実体が実行されるのではなく、 コンパイル時に中身のノードが呼び出し元へそのまま展開(コピー)されます 。
| 特徴 | 詳細 |
|---|---|
| 実行フロー | 入口も出口も 複数持てる(実行ピンを分岐して返せる) |
| 遅延実行ノード | Delay などを 使用できる |
| ローカル変数 | 定義 不可(値は入力ピンかワイヤーで受け渡す) |
| 再帰呼び出し | 不可(展開が無限に続いてしまうため) |
| 展開 | 使った場所すべてにノードがコピーされ、グラフが太りやすい |
| デバッグ | 展開されたノードを追うことになり、Functionよりやや複雑 |
Macroにしかできないことの筆頭が、 実行ピンの分岐 です。

Branch ノードがTrue/Falseの2つの出口を持つように、「条件次第で違う流れへ抜ける」ノードは、Macroでしか自作できません。標準ノードの DoOnce や Gate、For Each Loop も、エンジンが用意したMacroです。
もう1つの専売特許が Delayなどの遅延ノード 。Functionは「一気に実行して戻る」約束で動い ているため、途中で時間を待てません。

比較表:決定的な違いはどこか
違いは「呼び出される」か「書き写される」かに集約されます。

| 項目 | Function | Macro |
|---|---|---|
| 動作原理 | 呼び出される(サブルーチン) | 書き写される(インライン展開) |
| 実行ピン | 入1・出1のみ | 複数の入口・出口を持てる |
| 遅延ノード(Delay等) | 使用不可 | 使用可能 |
| 再帰呼び出し | 可能 | 不可 |
| ローカル変数 | 定義可能 | 定義不可 |
| グラフへの影響 | 呼び出しノード1個で済む | 使った場所すべてに展開されて太る |
| デバッグ | 容易 | やや複雑 |
使い分けの原則:基本はFunction、例外だけMacro
迷ったときの原則はシンプルで、 デフォルトはFunction、Macroは「Functionにできないこと」が必要なときだけ です。
- Functionを使う: 純粋な計算・状態チェック、実行ピンの分岐が要らない処理、デバッグしやすさを優先したい複雑なロジック、再帰
- Macroを使う: 実行ピンを分岐して返したいとき、
Delayなどの遅延ノードを含めたいとき
やりがちな失敗は3つ。①Function内にDelayを置こうとする(コンパイルエラーになります。MacroかEvent Graphへ)、②Macroの多用(展開コピーでグラフとコンパイル時間が膨らみます)、③Macroでの再帰(無限展開でエラーになります)。
実践:スキルのクールダウンを2つの道具で組む
使い分けを体で覚えるため に、両方の道具を1つのギミックで使ってみましょう。題材は スキルのクールダウン ——アクションの必殺技、シューティングのボム、RPGの呪文詠唱。「ボタンを連打しても、一定時間に1回しか発動しない」仕組みは、どのジャンルにも登場します。

分担は次のとおりです。 「撃てるかの判定」は計算なのでFunction、「3秒待って再解禁」は時間を待つのでMacro が担当します。
再現条件
キャラクターBlueprintに、判定に使う変数を用意します。 初期値まで合わせてください 。
| 変数名 | 型 | 初期値 | 役割 |
|---|---|---|---|
CurrentMana | Float | 50.0 | 現在のマナ |
SkillCost | Float | 25.0 | スキル1回の消費マナ |
bIsStunned | Bool | false | スタン中か |
入力は、テスト用に Left Mouse Button などのキーイベントで受けます(実際のゲームではEnhanced Inputの IA_Skill に置き換えてください → Enhanced Input入門)。
- Function側:
CanUseSkill(Pure):CurrentMana >= SkillCostかつNOT bIsStunnedのときだけTrueを返すPure Functionを作ります。時間を待たない純粋なチェックなので、Functionの領分です
Function: CanUseSkill(Pure・出力: bResult / Boolean)
→ (CurrentMana >= SkillCost) ─┐
→ (NOT bIsStunned) ─┴→ AND Boolean → Return(bResult)
- Macro側:
CooldownMacro: 新規Macroを作り、Inputに実行ピンとTime(Float)、Outputに実行ピン(Then)を用意して、中身を次のように組みます
Macro: Cooldown
In → DoOnce
Completed → Sequence
Then 0 → Out: Then ← 今回の発動を通す
Then 1 → Delay(Duration: Time)→ DoOnce の Reset ← Time秒後に再解禁
DoOnce の Completed は実行ピンが1本なので、そこから Out と Delay の両方へ直接は繋げません(Blueprintの実行出力ピンは1つの行き先にしか繋がりません)。あいだに Sequence ノード を挟み、Then 0 で発動を通し、Then 1 でクールダウンのタイマーを回します。

DoOnce が「1回通したら施錠する鍵」、Delay が「3秒後に鍵を開けに来る係」です。この中身には Delayが必要なので、Functionでは作れません 。Functionの中でDelayノードを検索してみてください。候補に出てこない(またはエラーになる)はずです。
- 組み合わせて発動処理に:
入力イベント → Branch(Condition: CanUseSkill) → True → Cooldown(Time: 3.0) → 弾をSpawnと繋げば完成です
Playしてボタンを連打してみてください。何度押しても弾は3秒に1発だけで、3秒経つとまた1発だけ通ります。押しっぱなしで10秒待てば、出る弾は0秒・3秒・6秒・9秒の 4発 だけ。この回数で答え合わせができます。もし連打のたびに弾が出てしまうなら、DelayのピンがResetではなくThen側に繋がっていないかを疑ってください。
役割分担を体感するには、bIsStunned を true にしてPlayしてみてください。クールダウンが明けていても弾は出ません。「撃てるかの判定」(Function)と「連射を止める流量制御」(Macro)が別々の部品だと、この一手で分かります。
ポイントは2つです。
- 役割で道具を選ぶ: 「計算・判定」はFunction、「時間や流れの制御」はMacro。1つのギミックの中でも、部品ごとに適材適所で分担させるのが上手な設計です
- このCooldown Macroは今後ずっと使い回せる: ダッシュ、被弾無敵、メッセージ連続表示の防止——「連打・連発を防ぎたい」場面すべてで再利用できます。汎用Macroとして育てていきましょう
おまけ:先に知っておくと良いこと
- Collapse Nodesと混同しない: ノード群を右クリック→「Collapse Nodes」で折り畳む機能は、見た目の整理専用で 再利用はできません 。再利用したいならFunctionかMacroに(折り畳みメニューから「Collapse to Function / Macro」への変換もできます)
- 複数のBlueprintで使い回すなら: FunctionはBlueprint Function Library、MacroはMacro Libraryというアセットにまとめると、プロジェクト全体から呼べるようになります。汎用のCooldown Macroはここに置く価値があります
- Macroに中間値を置きたくなったら: MacroにはLocal Variablesがありません。複雑な中間計算が必要になった時点で、その部分だけFunctionに切り出すのが正解です
まとめ
| 道具 | 動作原理 | 最大の強み |
|---|---|---|
| Function | 呼び出される(サブルーチン) | 実行フローの明確さ・デバッグの容易さ・ローカル変数 |
| Macro | 書き写される(インライン展開) | 実行ピンの分岐・Delayなどの遅延ノード |
合言葉は 「基本はFunction、時間と分岐だけMacro」 。この原則で処理をまとめていけば、Blueprintは読みやすく、壊れにくくなります。
処理をまとめる次の一歩は、グラフ全体の整頓です。Blueprintグラフを整理する10のテクニックへ進みましょう。また「毎フレームのTickをやめてイベント駆動で組む」設計はEvent Tickをやめる設計で扱います。
今日作ったCooldown Macroは、あなたのゲームでは何に使えるでしょうか。ダッシュ、必殺技、扉の連打防止と、使い道はいくらでもあります。