「いまスキルを使えるかを調べる」と「発動したら3秒間は連打を止める」。どちらもひとまとまりにしたい処理ですが、前者は答えを返す仕事、後者は実行の流れを通したり止めたりする仕事です。
Blueprintの Function(関数) と Macro(マクロ) は、こうした処理を名前の付いた部品にまとめる道具です。今回はスキルを題材に、条件の判定をFunctionへ、クールダウンをMacroへ分けます。
マナを50から25、次に0へ減らしながら、「連打では増えない」「待てば次が使える」「マナが足りなければ使えない」を確かめていきましょう。
この記事でわかること
- Functionが返す値と、Macroの実行ピンの違い
- Pure Functionと、Delayを使う場所
- 判定と連打防止を分けて組み立てる方法
- 押しっぱなし・クールダウン・マナ不足を区別して確認する手順
Function:処理を呼び、結果を受け取る
Functionは、ひとまとまりの処理を名前で呼び出すためのものです。例えば「マナが25以上あるか」を調べて、使えるならtrue、足りなければfalseを返せます。このtrue/falseを扱う型が Boolean です。
関数へ渡す値を 入力、処理して返す値を 戻り値 と呼びます。関数を呼び出した側は、その答えを次の処理に使います。関数の中身を修正すれば、同じ関数を使っている場所へ変更を反映できます。
Functionには、HPを減らすような変更処理もまとめられます。必ず値を返す必要もありません。今回は、その使い方の一つとして「条件を調べて答える関数」を作ります。
白い実行線と、値を渡す線
Blueprintの白い三角ピンは、いつ処理を実行するか をつなぐ入口・出口です。色の付いた値のピンは、数値やtrue/falseなどを渡します。
通常のFunction呼び出しには、白い実行入力と出力が1つずつあります。一方、数値などの入力・出力は複数作れます。「出口が1つ」とは、返せる値が1個という意味ではありません。
関数の中には、条件ごとに複数のReturn Nodeを置いても構いません。どのReturnから終えても、呼び出し側の白い出口は同じです(→ 変数と戻り値の使い分け)。
Pure Functionは、値が必要なときに計算する

Pure Function は、白い実行ピンを持たず、必要な値を返す形の関数です。関数のDetailsで「Pure」をオンにすると、呼び出し側がこの見た目になります。
例えば「マナが足りるか」を返すPure FunctionをBranchのConditionへつなぐと、Branchが条件を調べるときに答えが使われます。Branchは、trueならTrue、falseならFalseへ実行を分けるノードです。
Pureには、計算や状態の確認をまとめます。マナを減らす、アイテムを追加するといった変更処理は、白い実行線のある処理へ分けます。 値が必要になるたびに計算されるため、Pureにしただけで結果が保存されたり、計算が一度きりになったりするわけではありません。
Macro:実行の流れを部品にする
Macroは、ノードのまとまりを1個のノードとして使うためのものです。Functionと同じように、元の定義を直して利用箇所へ反映できます。違いは、白い実行の入口・出口も、自 分で増やせる ことです。
例えば「通してよいときの出口」と「拒否したときの出口」を持つ部品にできます。普段使うDoOnceやFor Each Loopも、標準のマクロとして用意されています。
内部の仕組みは、スタンプを押すイメージです。Compileすると、使った場所へMacroの中身が展開されます。実行するたびに新しくコピーするという意味ではありません。

時間を待つ処理は、置ける場所が違う
Delay は、指定した秒数を待ってから、その先の処理を再開するノードです。ゲーム全体を止めるポーズとは違い、その実行の続きだけを待たせます。
Functionは呼ばれた処理を終えて戻るため、途中にDelayを挟めません。今回のようにActor系BlueprintのEvent Graphで使うMacroなら、Delayを含めた流れをまとめられます。

ただし、Delay入りのMacroをFunctionへ置いても、Function内で待てるようにはなりません。中に入れるノードだけでなく、そのMacroをどこで使うか も合わせて考 えます。
使い分けを整理する
| 比べること | Function | Macro |
|---|---|---|
| 値の入力・出力 | 複数作れる | 複数作れる |
| 白い実行ピン | 通常は入1・出1。Pureの呼び出しはなし | 入口・出口を複数作れる |
| Delayを含む処理 | 関数内には置けない | Event Graphで使う今回のMacroには置ける |
| 名前付きのLocal Variables | 関数内に作れる | 関数と同じ作成欄はない |
| 別のActorに処理を頼む | 参照を使って相手の関数を呼べる | 関数のように相手をTargetにして呼ぶ道具ではない |
比較の要点は、戻したいものが「計算した値」なのか、まとめたいものが「実行の流れ」なのかです。Macroにも値の計算は書けますが、どちらでも書ける処理なら、意図を読み取りやすい形を選びます。

まずFunctionを考え、必要な流れをMacroへ
迷ったら、まずFunctionで「何をする処理か」を名前にします。CalculateDamageならダメージを求める、CanUseSkillなら使えるかを答える、と役割を小さくすると扱いやすく なります。
そのうえで、複数の実行出口や、Delayを含んだ流れをまとめたくなったらMacroを検討します。時間を待つだけならEvent Graphへ直接組んでもよく、必ずMacroにする必要はありません。今回は、連打防止をひとまとまりにして使う練習としてMacroを作ります。
実践:判定と3秒のクールダウンを組み合わせる
クールダウン は、スキルを使った後、次に使えるまでの待ち時間です。今回はFキーを押すとスキルが発動し、マナを25消費します。発動から3秒間は、何度押しても追加で発動しない形にします。
まずは、発動したことと残りマナをPrint Stringで表示します。弾やエフェクトを加える前に、判定と待ち時間が働くかを確かめるためです。

① キャラクターへ値を用意する
Third PersonのBlueprintプロジェクトを用意し、Variantを選べる版ではNoneにします。プレイに使う BP_ThirdPersonCharacter を開き、Variablesへ次を作ります。Compile後に既定値を設定します。
| 変数名 | 型 | 既定値 | 用途 |
|---|---|---|---|
CurrentMana | Float | 50.0 | 現在のマナ |
SkillCost | Float | 25.0 | 1回の消費マナ |
bIsStunned | Boolean | false | 行動できない状態か |
Floatは小数を扱う型です。今回は50、25という整数の値で試しますが、マナの回復量などに小数を使えるようにFloatで揃えます。
② Functionで「使える条件」を返す
Functionsの「+」から CanUseSkill を作り、DetailsのPureをオンにします。OutputsへBooleanの bResult を追加します。入力ピンは追加せず、このキャラクターの変数を読んで判定します。
条件は「マナが足りる」かつ「スタン中ではない」です。次のようにつなぎます。
- Floatの
>=に、A=Get CurrentMana、B=Get SkillCostを入れる。 NOT BooleanへGet bIsStunnedを入れる。NOTはtrue/falseを反転するので、スタン中でないときにtrueになる。- 2つの結果を
AND Booleanへ入れ、結果をReturn NodeのbResultへつなぐ。ANDは両方trueのときだけtrueになる。 - 関数内の入口からReturn Nodeへ白い実行線をつなぎ、Compileする。

Pureでも、作成中の関数グラフには入口とReturnがあります。白い実行ピンがなくなるのは、この関数を 呼び出すノード の見た目です。
CanUseSkillは「使えるか」を答えるだけで、マナは減らしません。実際の消費は、発動できた場合にだけ後で行います。
③ Macroで3秒間の連打を止める
同じBlueprintのMacrosの「+」から Cooldown を作ります。Detailsで次の入出力を追加します。
| 側 | 名前 | 型 |
|---|---|---|
| Inputs | In | Exec |
| Inputs | Time | Float |
| Outputs | Then | Exec |
Execは、白い実行ピンを作るための型です。Macroの中にはInputsとOutputsという入口・出口のノードがあり、今設定したピンが現れます。
中へ DoOnce、Sequence、Delay を置きます。DoOnceのStart Closedはオフにし、次の順でつなぎます。
- InputsのIn → DoOnceの通常の実行入力。
- DoOnceのCompleted → Sequenceの実行入力。
- SequenceのThen 0 → OutputsのThen。今回の発動を外へ通す。
- SequenceのThen 1 → Delayの実行入力。DurationへInputsのTimeをつなぐ。
- DelayのCompleted → 同じDoOnceのReset入力。
DoOnce は、最初の1回だけ通し、Resetへ実行が来るまで次を通さないノードです。Sequence は、Then 0、Then 1の順に処理を進めます。1本 の実行出力を2つへ直接分岐できないため、ここでSequenceを使います。
最初の入力は発動を通し、その直後に待機を始めます。Delayが終わると同じDoOnceが再び通せる状態に戻ります。Resetという名前の別ノードを作るのではなく、線を元のDoOnceへ戻す ところが要点です。
接続を2枚に分けて見ます。どちらも同じMacroの一部なので、2枚目のためにDoOnceやSequenceを追加しないでください。

もう一方の枝は、次の発動を許可するための待ち時間です。

クールダウン中に届いた入力は、後でまとめて実行する予約にはなりません。DoOnceで止まり、3秒後には「次の入力を受け付けられる状態」になるだけです。
④ Fキーから判定と発動へつなぐ
Event GraphにFキーのイベントを作ります。今回使うのは Pressed です。押した瞬間に1回だけ処理が来ます。Fキーの入力が取れていることを先にPrint Stringで確認してから、次の接続へ進むと切り分けやすくなります 。
- FのPressed → Branchの実行入力。
- My BlueprintからCanUseSkillをドラッグして呼び出しノードを置き、そのbResult → BranchのCondition。
- BranchのTrue → CooldownのIn。Timeは3.0にする。False側は何もしない。
- CooldownのThen → Set CurrentMana。値にはFloatの減算で
CurrentMana - SkillCostを入れる。 - Set CurrentManaの後にPrint Stringを置き、更新後のCurrentManaを表示する。

表示は Append のAに SKILL / Mana: 、BにCurrentManaをStringへ変換した値を入れ、結果をPrint StringのIn Stringへ渡します。Floatの線をString入力へつなぐと変換ノードが入ります。Durationは10秒にします。
マナを減らすのはCooldownを通った後 です。手前で減らすと、連打で発動しなかった分までマナを消費してしまいます。

今回の入力は練習用です。実際のゲームの操作へ組み込むときは、Enhanced InputのInput Actionへ置き 換えられます。そのときも、押した瞬間に呼ぶのか、押している間に繰り返すのかを決めます。
⑤ 連打・待ち時間・マナ不足を分けて確かめる
Compile・保存してPlayし、ゲーム画面をクリックして入力を受け取れる状態にします。
| 操作 | 期待する結果 |
|---|---|
| 最初にFを押す | 発動メッセージ。マナは50→25 |
| 3秒たつ前に、Fを離して何度か押す | 新しい発動メッセージは増えず、マナは25のまま |
| 最初の発動から3秒以上待ち、Fを押し直す | 2回目の発動。マナは25→0 |
| さらに3秒以上待ち、Fを押し直す | マナ不足なので発動しない |
Floatの表示は25.0などになることがありますが、確認する値は25と0です。押しっぱなしにして待つだけでは、次のPressedが発生しないため、自動では発動しません。
次にPlayを止め、bIsStunnedの既定値をtrueにして再び試します。今度は最初から発動しません。確認後はfalseへ戻します。これで「条件を満たさないので通さない」と「直前に使ったので通さない」を別々に確かめられます。
発動したら、弾や音を加える
ここまで動いたら、Cooldownを通った後の処理へ、弾の生成や効果音を加えます。弾のBlueprint、生成する位置と向き、飛ぶ速さはSpawn ActorとProjectile Movementで作れます。
同じ分け方は、ダッシュやボム、扉の連打防止にも使えます。「実行してよい条件」と「連続で実行させない間隔」を分けると、 片方だけを調整しやすくなります。
おまけ:先に知っておくと良いこと
Cooldownを2個置くと、待ち時間も別々になる
このMacro内のDoOnceは、配置したCooldownノードごとに状態を持ちます。入力Aと入力Bから別々のCooldownへつないでも、1つの共通クールダウンにはなりません。
同じスキルを複数の入力で使うなら、1つの発動処理へまとめてから同じCooldownを通します。別々のスキルの待ち時間を分けたい場合は、別ノードにすることが役立ちます。
MacroにLocal Variableはない?
関数と同じ名前付きのLocal Variables欄はありませんが、Macroには匿名のローカル値を使う仕組みがあります。今回の実践では扱わず、複雑な計算が必要になったらFunctionへ分け、結果をMacroへ渡す形から始めると見通しがよくなります。
Collapse Nodesは、共通の部品を作る操作とは違う
ノードを選んで「Collapse Nodes」を使うと、まとまりを折り畳んで見やすくできます。コピーもできますが、コピー先を含めて一括で直す共通定義にはなりません。
複数の場所で同じ処理を使い、1か所の修正を反映したいなら、FunctionやMacroへまとめます。見た目の整理と、共通化したい範囲を分けて考えます。
別のBlueprintでも使いたくなったら
汎用的な計算はBlueprint Function Library、マクロはMacro Libraryへまとめる方法があります。ただし、使えるノ ードや対象クラスの条件もあります。今回のCooldownはまずキャラクター内で完成させ、共有が必要になってから切り出す範囲を決めると進めやすくなります。
状態や複数の処理をまとめて再利用するなら、Blueprint Componentも選択肢になります。
まとめ
Functionは「処理を呼び、答えを受け取る」ために、Macroは「実行の流れをひとまとまりにする」ために使えます。今回のCanUseSkillは条件を返し、Cooldownは3秒間の連打を止め、通過後の処理がマナを減らしました。
次に似た処理をまとめるときは、何を答える部品なのか、どの流れを通す部品なのかを考えてみてください。グラフ全体の整理はBlueprintを整理する10のテクニック、時間で処理を呼ぶ別の方法はTickをやめてTimerとイベントで設計するで扱います。