【Unreal Engine】FunctionとMacroの違い:スキルの判定とクールダウンを分けて作る

作成: 2025-12-12最終更新: 2026-09-05

BlueprintのFunctionとMacroを、返す値・実行ピン・Delayの違いから使い分けます。スキルを使えるかの判定と、3秒間の連打防止を分け、マナ50→25→0で確かめる実践つき。

「いまスキルを使えるかを調べる」と「発動したら3秒間は連打を止める」。どちらもひとまとまりにしたい処理ですが、前者は答えを返す仕事、後者は実行の流れを通したり止めたりする仕事です。

Blueprintの Function(関数)Macro(マクロ) は、こうした処理を名前の付いた部品にまとめる道具です。今回はスキルを題材に、条件の判定をFunctionへ、クールダウンをMacroへ分けます。

マナを50から25、次に0へ減らしながら、「連打では増えない」「待てば次が使える」「マナが足りなければ使えない」を確かめていきましょう。

処理を呼ぶ箱と、処理のまとまりを写すスタンプ。FunctionとMacroを見比べる人形

この記事でわかること

  • Functionが返す値と、Macroの実行ピンの違い
  • Pure Functionと、Delayを使う場所
  • 判定と連打防止を分けて組み立てる方法
  • 押しっぱなし・クールダウン・マナ不足を区別して確認する手順

Sponsored

Function:処理を呼び、結果を受け取る

Functionは、ひとまとまりの処理を名前で呼び出すためのものです。例えば「マナが25以上あるか」を調べて、使えるならtrue、足りなければfalseを返せます。このtrue/falseを扱う型が Boolean です。

関数へ渡す値を 入力、処理して返す値を 戻り値 と呼びます。関数を呼び出した側は、その答えを次の処理に使います。関数の中身を修正すれば、同じ関数を使っている場所へ変更を反映できます。

Functionには、HPを減らすような変更処理もまとめられます。必ず値を返す必要もありません。今回は、その使い方の一つとして「条件を調べて答える関数」を作ります。

白い実行線と、値を渡す線

Blueprintの白い三角ピンは、いつ処理を実行するか をつなぐ入口・出口です。色の付いた値のピンは、数値やtrue/falseなどを渡します。

通常のFunction呼び出しには、白い実行入力と出力が1つずつあります。一方、数値などの入力・出力は複数作れます。「出口が1つ」とは、返せる値が1個という意味ではありません。

関数の中には、条件ごとに複数のReturn Nodeを置いても構いません。どのReturnから終えても、呼び出し側の白い出口は同じです(→ 変数と戻り値の使い分け)。

Pure Functionは、値が必要なときに計算する

通常のFunctionは白い実行の入口・出口を持ち、Pure Functionにはない。値のピンは複数作れ、Macroは実行出口も増やせる

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の中身が展開されます。実行するたびに新しくコピーするという意味ではありません。

Functionは共通の関数を呼んで戻り、MacroはCompile時に利用箇所へ中身が展開される

時間を待つ処理は、置ける場所が違う

Delay は、指定した秒数を待ってから、その先の処理を再開するノードです。ゲーム全体を止めるポーズとは違い、その実行の続きだけを待たせます。

Functionは呼ばれた処理を終えて戻るため、途中にDelayを挟めません。今回のようにActor系BlueprintのEvent Graphで使うMacroなら、Delayを含めた流れをまとめられます。

FunctionにはDelayを入れられない。時間を待つ処理はEvent Graphや、そこで使うMacroへ分ける

ただし、Delay入りのMacroをFunctionへ置いても、Function内で待てるようにはなりません。中に入れるノードだけでなく、そのMacroをどこで使うか も合わせて考えます。

使い分けを整理する

比べることFunctionMacro
値の入力・出力複数作れる複数作れる
白い実行ピン通常は入1・出1。Pureの呼び出しはなし入口・出口を複数作れる
Delayを含む処理関数内には置けないEvent Graphで使う今回のMacroには置ける
名前付きのLocal Variables関数内に作れる関数と同じ作成欄はない
別のActorに処理を頼む参照を使って相手の関数を呼べる関数のように相手をTargetにして呼ぶ道具ではない

比較の要点は、戻したいものが「計算した値」なのか、まとめたいものが「実行の流れ」なのかです。Macroにも値の計算は書けますが、どちらでも書ける処理なら、意図を読み取りやすい形を選びます。

FunctionとMacroで、できること・できないことを並べた比較

まずFunctionを考え、必要な流れをMacroへ

迷ったら、まずFunctionで「何をする処理か」を名前にします。CalculateDamageならダメージを求める、CanUseSkillなら使えるかを答える、と役割を小さくすると扱いやすくなります。

そのうえで、複数の実行出口や、Delayを含んだ流れをまとめたくなったらMacroを検討します。時間を待つだけならEvent Graphへ直接組んでもよく、必ずMacroにする必要はありません。今回は、連打防止をひとまとまりにして使う練習としてMacroを作ります。

Sponsored

実践:判定と3秒のクールダウンを組み合わせる

クールダウン は、スキルを使った後、次に使えるまでの待ち時間です。今回はFキーを押すとスキルが発動し、マナを25消費します。発動から3秒間は、何度押しても追加で発動しない形にします。

まずは、発動したことと残りマナをPrint Stringで表示します。弾やエフェクトを加える前に、判定と待ち時間が働くかを確かめるためです。

最初のFでマナ50から25、3秒以内の連打では変わらず、待って押し直すと0になる。待つだけでは自動発動しない

① キャラクターへ値を用意する

Third PersonのBlueprintプロジェクトを用意し、Variantを選べる版ではNoneにします。プレイに使う BP_ThirdPersonCharacter を開き、Variablesへ次を作ります。Compile後に既定値を設定します。

変数名既定値用途
CurrentManaFloat50.0現在のマナ
SkillCostFloat25.01回の消費マナ
bIsStunnedBooleanfalse行動できない状態か

Floatは小数を扱う型です。今回は50、25という整数の値で試しますが、マナの回復量などに小数を使えるようにFloatで揃えます。

② Functionで「使える条件」を返す

Functionsの「+」から CanUseSkill を作り、DetailsのPureをオンにします。OutputsへBooleanの bResult を追加します。入力ピンは追加せず、このキャラクターの変数を読んで判定します。

条件は「マナが足りる」かつ「スタン中ではない」です。次のようにつなぎます。

  1. Floatの >= に、A=Get CurrentMana、B=Get SkillCostを入れる。
  2. NOT Boolean へGet bIsStunnedを入れる。NOTはtrue/falseを反転するので、スタン中でないときにtrueになる。
  3. 2つの結果を AND Boolean へ入れ、結果をReturn NodeのbResultへつなぐ。ANDは両方trueのときだけtrueになる。
  4. 関数内の入口からReturn Nodeへ白い実行線をつなぎ、Compileする。
CurrentManaとSkillCostの比較、スタン状態の反転をANDで合わせ、Return NodeのbResultへ返す

Pureでも、作成中の関数グラフには入口とReturnがあります。白い実行ピンがなくなるのは、この関数を 呼び出すノード の見た目です。

CanUseSkillは「使えるか」を答えるだけで、マナは減らしません。実際の消費は、発動できた場合にだけ後で行います。

③ Macroで3秒間の連打を止める

同じBlueprintのMacrosの「+」から Cooldown を作ります。Detailsで次の入出力を追加します。

名前
InputsInExec
InputsTimeFloat
OutputsThenExec

Execは、白い実行ピンを作るための型です。Macroの中にはInputsとOutputsという入口・出口のノードがあり、今設定したピンが現れます。

中へ DoOnceSequenceDelay を置きます。DoOnceのStart Closedはオフにし、次の順でつなぎます。

  1. InputsのIn → DoOnceの通常の実行入力。
  2. DoOnceのCompleted → Sequenceの実行入力。
  3. SequenceのThen 0 → OutputsのThen。今回の発動を外へ通す。
  4. SequenceのThen 1 → Delayの実行入力。DurationへInputsのTimeをつなぐ。
  5. DelayのCompleted → 同じDoOnceのReset入力

DoOnce は、最初の1回だけ通し、Resetへ実行が来るまで次を通さないノードです。Sequence は、Then 0、Then 1の順に処理を進めます。1本の実行出力を2つへ直接分岐できないため、ここでSequenceを使います。

最初の入力は発動を通し、その直後に待機を始めます。Delayが終わると同じDoOnceが再び通せる状態に戻ります。Resetという名前の別ノードを作るのではなく、線を元のDoOnceへ戻す ところが要点です。

接続を2枚に分けて見ます。どちらも同じMacroの一部なので、2枚目のためにDoOnceやSequenceを追加しないでください。

InputsからDoOnce、Sequenceへ進み、Then 0からOutputsへ発動を通す。Then 1は次の図のDelayへつなぐ

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

SequenceのThen 1からDelayへ進み、Completedを同じDoOnceのResetへ戻す。InputsのTimeはDelayのDurationへ

クールダウン中に届いた入力は、後でまとめて実行する予約にはなりません。DoOnceで止まり、3秒後には「次の入力を受け付けられる状態」になるだけです。

④ Fキーから判定と発動へつなぐ

Event GraphにFキーのイベントを作ります。今回使うのは Pressed です。押した瞬間に1回だけ処理が来ます。Fキーの入力が取れていることを先にPrint Stringで確認してから、次の接続へ進むと切り分けやすくなります。

  1. FのPressed → Branchの実行入力。
  2. My BlueprintからCanUseSkillをドラッグして呼び出しノードを置き、そのbResult → BranchのCondition。
  3. BranchのTrue → CooldownのIn。Timeは3.0にする。False側は何もしない。
  4. CooldownのThen → Set CurrentMana。値にはFloatの減算で CurrentMana - SkillCost を入れる。
  5. Set CurrentManaの後にPrint Stringを置き、更新後のCurrentManaを表示する。
FのPressedからBranchへ、CanUseSkillのbResultをConditionへ。TrueだけCooldownを通り、マナ消費へ進む

表示は Append のAに SKILL / Mana: 、BにCurrentManaをStringへ変換した値を入れ、結果をPrint StringのIn Stringへ渡します。Floatの線をString入力へつなぐと変換ノードが入ります。Durationは10秒にします。

マナを減らすのはCooldownを通った後 です。手前で減らすと、連打で発動しなかった分までマナを消費してしまいます。

CurrentManaからSkillCostを引き、Cooldownから実行が来たときだけSet CurrentManaへ書き込む。更新後の値をPrint Stringへ渡す

今回の入力は練習用です。実際のゲームの操作へ組み込むときは、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で作れます。

同じ分け方は、ダッシュやボム、扉の連打防止にも使えます。「実行してよい条件」と「連続で実行させない間隔」を分けると、片方だけを調整しやすくなります。

Sponsored

おまけ:先に知っておくと良いこと

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とイベントで設計するで扱います。

参考リンク

Unreal Engine このセクションのノート98