トリガーに入ると扉が開く。その仕掛けをLevel Blueprintに作った後、別の部屋にも同じ扉を置きたくなったら、どこまでコピーすればよいでしょうか。
ここで分けたいのが、「扉がどう開くか」と「この部屋では、何をきっかけに開くか」 です。開き方を扉のBlueprint Classへ持たせれば、Level Blueprintには「このトリガーに入ったら、この扉を開ける」という対応付けを残せます。
この記事では、Level Blueprintを「そのレベルの台本」、Blueprint Classを「使い回す部品の設計図」として見比べます。最後に、プレイヤーが近づくと1.5秒でせり上がる扉を作り、役割を分ける意味を確かめましょう。
この記事でわかること
- レベル専用の処理と、使い回す処理の分け方
- 配置したActorを参照で指定する方法
- 扉の動きを作ってから、トリガーへつなぐ手順
- 同じ設計図の扉を増やし、共通の変更を試す方法
Level Blueprint:そのレベルの台本
Level Blueprint は、各レベルに用意されている専用のグラフです。レベルエディタ上部の「Blueprints」メニューから「Open Level Blueprint」で開きます。
例えば「この部屋のトリガーに入ったら、奥の扉を開ける」「このマップの開始時にカメラ演出を流す」といった、その場所で起きる出来事をまとめられます。

便利なのは、レベルに配置したActorを、そのままグラフで指定しやすいこと です。OutlinerでActorを選び、Level Blueprintの右クリックメニューから「Create a reference to[Actor名]」を選ぶと、その個体を指すノードを置けます。
この 参照 は、「どの扉に処理を頼むか」 を指定するためのものです。同じBP_Doorから作った扉が3個あっても、入口の扉を指す参照なら、頼む相手はその1個に決まります。
ただし、参照しているのは、このレベルに置いた個体です。新しく別のレベルを作っても、同じ配置物や対応付けが自動で用意されるわけではありません。
Blueprint Class:使い回す部品の設計図
Blueprint Class には、扉や敵、拾えるアイテムなどの見た目・変数・処理をまとめられます。今回はActorを親にしたClassを扱います。
BP_Doorという設計図を1つ作り、それをレベルへ3個置いたとします。配置された1個ずつが インスタンス です。開くための処理は共通でも、「いま開いているか」といった状態や、置かれた位置はそれぞれ別に持ちます(→ UE5の基本概念)。
扉の中にOpenDoorという処理を用意すれば、呼び出す側は、内部のノードを毎回組み直さずに「開いて」と頼めます。

このように、部品の中へデータと処理をまとめ、外からは必要な操作を呼ぶ形を カプセル化 といいます。今回なら、レベル側が扉の座標を少しずつ変える代わりに、扉自身へOpenDoorを頼む形です。
どこまで共通に使いたいか で分ける
判断の軸は、見た目が「モノ」か「演出」かだけではありません。別の場所でも同じ仕組みを使い、まとめて直したいか を考えます。
| 作りたいこと | まとめる場所の例 |
|---|---|
| どの部屋でも同じように開く扉 | BP_DoorというBlueprint Class |
| この部屋のトリガーと奥の扉の対応付け | このレベルのLevel Blueprint |
| 複数のステージで共通に使う勝敗ルール | GameModeなどの共通クラス |
| 何か所でも使う警告灯や演出装置 | 再利用するBlueprint Class |
「扉という部品はClassへ、この場所だけの対応付けはLevelへ」と考えると、今回の分担が見えてきます。ゲーム全体のルールやスコアを置く場所は、Game Frameworkでも整理しています。

コピーした処理は、後から別々に直すことになる
レベルごとのLevel Blueprintへ同じ扉の処理をコピーすると、後で開く速さを統一したくなったときに、各レベルを直す必要があります。
一方、開き方をBP_Doorへまとめてあれば、その定義を直すことで、同じClassを使う扉へ変更を反映できます。試作をLevel Blueprintから始めても構いません。似た処理を別の場所にも欲しくなったときが、共通の部品へ移す目安です。
レベル自体を複製すればLevel Blueprintもコピーされますが、コピー同士は共通の定義にはなりません。「複製できること」と「1か所の修正を使い回せること」は区別します。
実践:トリガーに入ると扉が開く仕掛け
プレイヤーが扉の手前の範囲へ入ると、扉が 1.5秒で300cm上がる 仕掛けを作ります。範囲を出て入り直しても、そのプレイ中はもう開き直しません。
ここでいう トリガー は、入ったことを検出する領域です。床のスイッチの見た目がなくても、見えない箱の範囲で検出できます。今回は扉を作り、単体で動かしてから、レベル側のトリガーとつなぎます。

① 扉の見た目を用意する
Third PersonのBlueprintプロジェクトを使います。Variantがある版はNoneにして、テンプレートのキャラクターで歩けるレベルを開きます。
Content Browserで「Blueprint Class」を作成し、親をActor、名前を BP_Door にします。Componentsの DefaultSceneRootを残したまま、その子にStatic Meshを追加し、名前を DoorMesh にします。
| DoorMeshの設定 | 値 |
|---|---|
| Static Mesh | エンジン標準のCube |
| 相対Location | X=0、Y=0、Z=0 |
| 相対Rotation | X=0、Y=0、Z=0 |
| Scale | X=0.2、Y=1.5、Z=2.2 |
| Mobility | Movable |
| Collision Presets | BlockAll |
| Simulate Physics | オフ |
Cubeが見つからない場合は、アセット選択欄の設定で「Show Engine Content」を有効にし、EngineのBasicShapesにあるCubeを選びます。
相対Location は、親コンポーネントから見た位置です。今回はDefaultSceneRootを固定した基準にして、その子のDoorMeshだけを上へ動かします。DoorMeshをRootへ置き換えないのは、この基準を残すためです。
VariablesにFloatの OpenHeight を作り、Compile後の既定値を300.0にします。これは「閉じた位置から、何cm上へ動かすか」です。

② 扉の開き方を作る
BP_DoorのEvent GraphでCustom Eventを追 加し、名前を OpenDoor にします。Custom Eventは、自分で名前を付けて呼べる処理の入口です。
続けて右クリックから「Add Timeline」で TL_Open を作り、ダブルクリックで開きます。Timeline は、時間に合わせて値を変えるためのノードです。ここでは「開き具合」を0から1へ変えます。
- Floatトラックを追加し、名前を
Alphaにする。 - 長さを1.5秒にし、LoopとAutoPlayをオフにする。
- トラック内を右クリックしてキーを2個追加し、各キーを選んで下表のTimeとValueを入力する。
- 2個のキーを選び、補間をLinearにする。今回は一定の速さで開ける。
| キー | Time | Value |
|---|---|---|
| 開き始め | 0.0 | 0.0 |
| 開き終わり | 1.5 | 1.0 |
キー は「この時刻には、この値にする」という目印です。Alphaは今回付けた開き具合の名前で、0が閉じた状態、1が開き切った状態、0.5が途中を表します。
Event Graphへ戻り、OpenDoorの白い出力をTL_Openの「Play from Start」へつなぎます。これでOpenDoorを呼ぶと、時間0から開き始めます。
次にFloatの Lerp を置き、Aを0.0、BをGet OpenHeight、AlphaをTL_OpenのAlpha出力へつなぎます。Lerp は、AとBの間の値を、Alphaの割合で求めるノードです。今回は0と300の間なので、Alphaが0.5なら高さ150になります。
DoorMeshをComponentsからグラフへドラッグし、その参照から Set Relative Location を作ります。TargetにはDoorMeshがつながります。New Locationピンを右クリックして「Split Struct Pin」を選び、X・Y・Zへ分けます。
| 接続・設定する先 | 値・接続元 |
|---|---|
| Set Relative Locationの白い実行入力 | TL_OpenのUpdate |
| Target | DoorMeshの参照 |
| New Location X / Y | どちらも0.0 |
| New Location Z | Lerpの結果 |
| Sweep / Teleport | どちらもオフ |
Update は、Timelineの再生中に位置を更新するための実行出力です。Updateの白い線が「今、位置を変える」、Lerpから来る値が「どの高さにするか」、Targetが「どのコンポーネントを動かすか」を受け持ちます。

この例ではDoorMeshの最初の相対位置を0に揃えているため、X・Yは0のまま、Zだけを変えられます。別の相対位置から動かす応用は、Timelineの記事で扱います。
③ まず扉だけで動作を確かめる
Compile・保存して、BP_Doorを平らな床の上へ1個置きます。ActorのRotationは0、Scaleは1のままにします。Cubeの高さは220cmで中心が原点なので、Actorの位置を床の表面から110cm上 にすると、扉の下面が床に接します。
BP_DoorのEvent Graphへ、一時的に Event BeginPlay → OpenDoor(Target: self) をつなぎます。Play開始時に扉自身のOpenDoorを呼び、トリガーなしで動くかを確かめるためです。
Playすると、扉が開始位置から300cm上へ動き、1.5秒後に止まれば成功です。確認できたらPlayを止め、このBeginPlayからの接続を外して Compile・保存します。次は、近づいたときだけ呼ぶ形へ変えます。
ここで動かなければ、まだLevel Blueprintを調べる必要はありません。DoorMeshがMovableか、Updateの白線とTarget、New Location Zがつながっているかを確認します。
④ レベルへトリガーを置く
Place Actorsなどから Trigger Box を配置します。プレイヤーの開始位置とは重ならないように、扉の手前へ置きます。
| 設定 | 値 |
|---|---|
| Box Extent | X=100、Y=100、Z=100 |
| Collision Presets | OverlapAllDynamic |
| Generate Overlap Events | オン |
| ActorのScale | X=1、Y=1、Z=1 |
| 高さ | 中心を床の表面から100cm上 |
Box Extentは中心から端までの長さなので、この箱は各辺200cmです。扉の正面から200cmほど手前を目安に置き、歩いて横切れる位置へ調整します。
Overlap は、衝突で押し返す代わりに、領域の重なりを検出する仕組みです。検出するTrigger Boxだけでなく、入ってくるキャラクターのCapsule ComponentもGenerate Overlap Eventsをオンにします。
Trigger Boxの枠は通常、Play中には見えません。どこを通るか迷う場合は 、エディタで扉とトリガーの位置を確認してから歩いてください。
⑤ Level Blueprintで「いつ、どの扉を開けるか」をつなぐ
OutlinerでTrigger Boxを選び、Blueprints → Open Level Blueprintを開きます。グラフを右クリックし、「Add Event for[Trigger名]」のCollisionから On Actor Begin Overlap を追加します。
このイベントの Other Actor は、領域へ入ってきた相手です。そのピンから Cast To BP_ThirdPersonCharacter を作り、イベントの白い実行出力もCastへつなぎます。
Cast は、渡された相手を指定したClassとして扱えるか調べます。今回のテンプレートでは操作キャラクターがBP_ThirdPersonCharacterなので、成功した場合だけ続けます。同じClassのキャラクターを複数置いた場合はそれらにも反応するため、今回はテンプレートの1人で確認します。
Castの成功側から DoOnce へつなぎ、Start Closedをオフにします。DoOnceは、Resetされるまで最初の1回しか通さないノードです。今回はResetをつながず、入り直しても開き直さない形にします。

次にレベルへ戻り、配置したBP_Doorを選びます。Level Blueprintのグラフで右クリックし、「Create a reference to[扉名]」を選びます。Content Browserの設計図ではなく、Outlinerにある配置済みの扉を選ぶ のが要点です。
その参照の出力ピンから OpenDoor を呼び出すノードを作り、DoOnceのCompletedを白い実行入力へつなぎます。OpenDoorのTargetは、配置した扉の参照です。Cast Failed側は何もしません。
次の図は、同じグラフのDoOnce以降を取り出したものです。DoOnceをもう1個追加する必要はありません。

ここではLevel Blueprintが開き方を計算していません。入ってきた相手を確認し、1回だけ、指定した扉へOpenDoorを頼んでいます。
⑥ 入り直したときと、扉を増やしたときを比べる
BP_DoorとLevel BlueprintをCompile・保存してPlayします。
| 確認すること | 期待する結果 |
|---|---|
| トリガーへ入る前 | 扉は閉じたまま |
| 歩いて範囲へ入る | 1.5秒で300cm上へ動く |
| 範囲を出て、もう一度入る | 開いたまま。最初から再生し直さない |
| Playを止めて、再びPlay | 閉じた状態からやり直せる |
単体確認では動いたのに近づいても開かない場合は、Overlapイベントの直後へPrint Stringを置きます。表示されなければ領域と衝突設定、表示されるならCastの対象・DoOnce・OpenDoorのTargetの順に調べます(→ Print Stringで調べる)。
仕組みが動いたら、レベルへBP_Doorをもう1個置いてみてください。今のトリガーに入って開くのは、Targetで指定した扉だけ です。参照先を2個目の扉へ替えれば、同じ仕組みで別の扉を開けられます。
2組のトリガーと扉を作る場合は、各組に別のDoOnceと参照先を用意します。そのうえでBP_Door内のTimelineで、2個目のキーのTimeとTimeline全体の長さを両方3秒へ変えると、どちらの扉も3秒で開くようになります。レベル側の呼び出しを直さず、共通の開き方を変えられたことを確かめ、最後は両方1.5秒へ戻します。
おまけ:先に知っておくと良いこと
Blueprint Classでも、配置した相手を指定できる
今回の対応付けはLevel Blueprintに置きましたが、同じ仕掛けを何部屋も使うなら、トリガー側も BP_DoorTrigger のようなClassへまとめられます。
その中にBP_DoorのObject Reference型変数を作り、「Instance Editable」をオンにすれば、レベルに置いた各トリガーのDetailsから相手の扉を選べます。Overlapや Get All Actors Of Class で探すことだけが、相手を指定する方法ではありません。
参照の受け渡しや通信の選び方は、アクター間通信の3つの方法で扱います。
1枚の扉だけ、上がる高さを変えたい
OpenHeightをInstance Editableにすると、配置した扉ごとに300や400を設定できます。「開く処理を共通にすること」と「全個体の値を同じにすること」は別です。
Classの既定値を変えても、個体側ですでに上書きした値はそのまま残ります。共通の変更を試すときは、どこで値を設定したかも確認してください(→ Class Variablesの使い方)。
扉以外にも同じ頼み方をしたくなったら
扉だけを開ける今回の仕掛けは、参照からOpenDoorを呼ぶ形で十分です。扉・宝箱・跳ね橋へ同じ「操作する」という頼み方をしたくなったら、Blueprint Interface を検討できます。
Interfaceは、相手が受け付ける操作名を共通にするための仕組みです。実際にどう反応するかは各部品へ任せます。使っても「どの相手へ送るか」の参照は必要です(→ Blueprint Interface)。
Level Blueprintが向く場面も残る
このマップだけのカットシーン開始や、配置済みActor同士の小さな対応付けには、Level Blueprintの直接参照が役立ちます。必要以上に避けるのではなく、繰り返し使う範囲が増えたら部品へ分けます。
Sequencerによる演出の開始や、Level Streamingの指示も、その使い道です。
まとめ
今回のBP_Doorは「どう開くか」を持ち、Level Blueprintは「何が入ったら、どの扉を開けるか」を決めました。扉の開き方を共通にしたので、別の場所へ置いても、呼び出すきっかけだけを変えて使えます。
いまLevel Blueprintに 似た処理が並んでいたら、どこを共通に直したくなるか見てみてください。そのまとまりが、Blueprint Classへ切り出す候補になります。