【Unreal Engine】構造体(Struct)入門:アイテムの情報をまとめ、配列の値を書き換える

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

名前・攻撃力・耐久値を1つの構造体にまとめ、MakeとBreakで扱います。コピーだけを90にしても配列は100のまま、という実験から、Set Array Elemで書き戻すまでをBlueprintで追います。

持ち物の「名前」「攻撃力」「耐久値」を別々の変数で管理していると、アイテムを渡すたびに3つの値を揃える必要があります。持ち物が増えると、「この名前と、この耐久値は同じ剣のものだろうか」と、対応を確かめる手間も増えてきます。

構造体(Struct) は、こうした情報をひとまとめにするための型です。「アイテム1個分の情報」を1本のワイヤーで渡せるようになります。

この記事では、鉄の剣のデータを作り、耐久値を100から90へ変えます。その途中で、手元のコピーは90なのに、持ち物の中身は100のまま になる場面も確かめます。どちらの値を変えたのかが分かれば、配列の更新で迷いにくくなります。

鉄の剣の名前・攻撃力・耐久値を、アイテム1個分のカードにまとめる

この記事でわかること

  • 構造体に名前・攻撃力・耐久値をまとめる
  • Makeで組み立て、Breakで必要な値を取り出す
  • コピーと元の配列を読み比べ、書き戻した結果を確認する

Blueprintで変数を作り、ノードをつないだことがある人向けです。持ち物の画面は作らず、まずPrint Stringでデータの動きを確かめます。

Sponsored

構造体は1個分、配列は複数個分

構造体に入れる各項目を メンバー と呼びます。今回は「名前」「攻撃力」「耐久値」の3つです。まとめるかどうかは、項目数よりも、同じものの情報として一緒に扱いたいか を目安に考えます。

一方、配列(Array) は、同じ型の値を順番に並べて持つものです。構造体が「剣1本分の情報」なら、構造体の配列は「何本かの剣を並べた持ち物リスト」に当たります。

同じ項目を持つ鉄の剣と木の剣を、Inventoryの0番と1番に並べる

配列内の位置を表す番号が インデックス(Index) です。最初が0、次が1と、0から数えます。名前と耐久値を別々の配列に分ける方法もありますが、アイテム1個を構造体にすると、その情報を同じ位置にまとめておけます。

構造体は、ゲーム内に剣を置く機能ではありません。まずは剣についての「情報」を扱います。見た目のActorを出す処理や、持ち物UIへ表示する処理は、その情報を受け取る側の仕事です。

構造体を作り、MakeとBreakを知る

練習用のフォルダで、コンテンツブラウザを右クリックし、「Blueprints」→「Structure」から S_DemoItem を作ります。S_ は構造体を見分けるための名前の付け方で、UEの必須ルールではありません。

開いたら「Add Variable」で項目を追加し、次の名前と型にします。 は、その項目へ入れられる値の種類です。

メンバー名今回の意味
DisplayNameText画面に表示するアイテム名
AttackInteger攻撃力。整数で扱う
DurabilityInteger今の耐久値。整数で扱う

「Default Values」で DisplayName を空、Attack を0、Durability を100にして保存します。デフォルト値 は、値を指定しなかったときの出発点です。すでに作った剣を、一斉に回復させる設定ではありません。

この型をBlueprintで使うと、次の2つのノードを作れます。

ノードすること鉄の剣の例
Make S_DemoItem各項目から構造体の値を組み立てる鉄の剣・10・100 → 1個分の情報
Break S_DemoItem構造体から各項目を取り出す1個分の情報 → 名前、攻撃力、耐久値
Makeで3つの値をまとめ、Breakで同じ3つの値を取り出す

Breakは「項目ごとに分けて読む」という意味です。アイテムを壊したり、配列から削除したりはしません。

MakeとBreakには白い実行ピンがありません。こうした 純粋ノード は、値を使う処理に必要になったときに評価されます。白い線で実行順をつなぐSetやPrint Stringと、役割が違います。

コピーを変えても、元の値は変わらない

構造体は、代入すると中の値がコピーされる 値型 です。今回の配列から取り出す Get (a copy) も、その位置にあるアイテムの情報をコピーして返します。

たとえば、持ち物にある鉄の剣の耐久値が100だとします。その情報を取り出して90へ変えても、変わったのは取り出した側です。元の配列を90にするには、変更後の情報を同じ位置へ入れ直します。

元の配列は100のまま、取り出したコピーだけ90になり、書き戻すと配列も90になる

この「取り出す→変える→元の場所へ入れる」という最後の操作を、ここでは 書き戻し と呼びます。ファイルへの保存ではなく、実行中の配列を更新する操作です。

配列には Get (a ref) もあります。こちらの 参照 は、配列内の値そのものを扱うためのものです。「Getならすべてコピー」とは限りません。今回は違いを追いやすい Get (a copy) と、明示的な書き戻しで進めます。

Sponsored

実践:90と100の違いを確かめる

Playすると、コピーの耐久値90、元の配列の耐久値100を順に表示する実験を作ります。その後で書き戻しを追加し、配列を読み直した値が90になるところまで確かめます。

1. 練習用Actorに持ち物を用意する

親クラスがActorのBlueprint BP_StructPractice を作り、レベルへ1体だけ置きます。以降の変数とノードは、すべてこのBlueprintの中に作ります。

変数名用途
InventoryS_DemoItemのArray元の持ち物リスト
WorkingItemS_DemoItem(単一の値)変更後の情報を一時的に置く場所

変数の型で S_DemoItem を選び、Inventory だけコンテナの種類を「Array」にします。コンパイルしてから「Class Defaults」でInventoryを展開し、「+」で要素を1個追加します。

0番の中身を、DisplayName = 鉄の剣Attack = 10Durability = 100 にしてください。WorkingItemの初期値は後で上書きするので、そのままで構いません。

今回は、0番が存在する配列から始める ことが大切です。配列を空のままにすると、最初の読み取りでつまずきます。

2. 0番の情報を取り出す

Event GraphへInventoryをドラッグし、「Get」を選びます。これは配列全体を使うための変数ノードです。その出力から Get (a copy) を作り、位置の入力を0にします。さらに出力から Break S_DemoItem を作ります。

InventoryからGet (a copy)で0番を取り出し、Breakへ渡す接続

この3つは値を読み出す側です。まだ実行する処理につながっていないので、次に「読み出した値を、どこへ入れるか」を作ります。

3. 耐久値だけ90にして、WorkingItemへ入れる

Make S_DemoItemSet WorkingItem を作ります。先ほどのBreakから DisplayNameAttack を、Makeの同じ名前の入力へつなぎます。Makeの Durability には90を直接入力します。

Breakの名前と攻撃力をMakeへ渡し、耐久値だけ90を入力する

図のBreakは、直前に作ったものを続けて使います。ここでは減算の仕組みを増やさず、耐久値を90へ設定します。名前と攻撃力も渡しているのは、変更しない項目を保つため です。Makeの入力を空けると、元の剣の値を自動で引き継ぐわけではありません。

次にMakeの出力をSet WorkingItemへ、Event BeginPlay の白い実行出力をSet WorkingItemの実行入力へつなぎます。BeginPlayは、このActorがプレイを始めるときに呼ばれるイベントです。

同じMakeの出力をWorkingItemへ渡し、BeginPlayで代入する

図は同じグラフを分けて示しています。MakeやSet WorkingItemを図ごとに増やさず、前の接続へ続けてください。

4. コピーと元の配列を、それぞれ表示する

まずWorkingItemをGetし、Breakへ渡します。Breakの DurabilityPrint StringIn String へドラッグしてつなぐと、整数を文字列に変える小さな変換ノードが入ります。図では To String (Integer) として描いています。

Print Stringは文字を表示するノード なので、整数90を表示するにも、この変換が必要です。Set WorkingItemの白い実行出力もPrint Stringへつなぎます。

WorkingItemの耐久値を文字列に変換し、Set WorkingItemの後でPrint Stringを実行する

この段階でコンパイルしてPlayすると、90が表示されます。停止して、次に元の配列を読む処理を続けます。

InventoryのGet→Get (a copy) の0番→Break→耐久値の文字列変換→2個目のPrint Stringを作ります。1個目のPrint Stringの実行出力を、2個目の実行入力につなぎます。

元のInventoryの0番を読み直し、耐久値を2個目のPrint Stringへ渡す

Playすると、1個目は90、2個目は100を表示します。画面上では新しいメッセージが上に並ぶことがあるため、上下の順番だけで判断せず、必要なら「Output Log」で出力順を確認してください。表示がすぐ消える場合は、各Print Stringの詳細ピンを開き、Duration を10にします。

WorkingItemに入れた90は、Inventoryの0番にはまだ入っていません。 Set WorkingItemまでの接続が失敗したのではなく、別の変数を更新した結果です。

5. 配列へ書き戻し、もう一度読む

2個目のPrint Stringの後へ、Set Array Elem を追加します。これは配列の指定した位置へ、値を入れるノードです。

入力つなぐもの・設定値
実行入力2個目のPrint Stringの実行出力
Target ArrayInventoryのGet
Index0。取り出したときと同じ位置
ItemWorkingItemのGet
Size to FitOFF
InventoryとWorkingItemをSet Array Elemへ渡し、0番を置き換える

Size to Fit は、指定位置が配列の外にあるときに配列を広げる設定です。今回はすでに存在する0番を置き換えるので、OFFにします。

最後に、手順4の「Inventoryから読み直してPrint Stringへ渡す」一組を複製し、3個目のPrint Stringを作ります。Set Array Elemの白い実行出力を、このPrint Stringの実行入力へつなぎます。最後の表示もWorkingItemではなく、Inventoryの0番から読みます。

最終的な白い実行線は、次の順です。

  1. Event BeginPlay → Set WorkingItem
  2. Print String:WorkingItemの耐久値を表示
  3. Print String:Inventoryの0番の耐久値を表示
  4. Set Array Elem:Inventoryの0番へ書き戻す
  5. Print String:Inventoryの0番を読み直して表示

コンパイルしてPlayし、出力順が 90→100→90 になれば成功です。最後が100のままなら、Set Array Elemの実行線、Target Array、Index、Itemを順に見ます。

コピー90、書き戻す前の配列100、書き戻した後の配列90という実験結果

今度はMakeの耐久値を70にしてみてください。結果は70→100→70になります。Playを停止して再開するたび、InventoryはClass Defaultsで指定した100から始まります。実行中の更新と、次の起動まで残すセーブは別の処理です。

ここまでできれば、「剣を使ったら耐久値を減らす」処理でも、元の値を読む→変更後の情報を作る→同じ位置へ戻す と考えられます。複数アイテムを扱うときは、読み取りと書き戻しに同じIndexを渡し、その位置が存在するか Is Valid Index で先に確かめます。

Sponsored

項目を増やすときの注意

今回の3項目なら、Makeへつなぐ線も多くありません。価格やアイコンを足していくと、耐久値だけを変えるのに、変更しない項目の線が増えていきます。

その場合は Set Members in Struct が役立ちます。今回の型では Set members in S_DemoItem という名前です。対象の構造体変数から作り、ノードのDetailsで Durability だけを入力として表示すれば、名前や攻撃力を保ったまま耐久値を変更できます。表示していないメンバーは変更されません。

Makeでは全項目の線が要るが、Set Members in Structなら変えたい項目だけを表示してつなげる

ただし、WorkingItemを変更するなら、変更先はWorkingItemです。このノードを使っても、元のInventoryへ自動で書き戻されるわけではありません。先ほどの実験と同じように、変更する場所を確かめます。

また、剣1本の耐久値を変える操作と、S_DemoItem 自体へ項目を追加する操作は別です。後者は データの形を変える操作 なので、その型を使うBlueprintやData Tableにも確認が必要になります。

項目の削除や型の変更をする前は、プロジェクトをバージョン管理へ保存するか、バックアップを取ります。変更後は利用先をコンパイルし、未接続のピン、初期値、Data Tableの行を確認してください。CSVを書き出しておくのも補助になりますが、プロジェクト全体の代わりにはなりません。

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

  • 構造体にも「今の状態」を入れられる:今回の耐久値がその例です。プレイヤーやUIが別々に正しい値を持とうとするより、Inventoryを管理するActorやComponentを決め、その場所の値を更新すると追いやすくなります。
  • 種類の設定と、持っている1個の状態を分ける:鉄の剣の基本攻撃力は種類ごとの設定、使い込んだ1本の残り耐久値は所持品ごとの状態です。種類が増えたら、Data TableData Assetで共通設定を管理する方法へ進めます。
  • 構造体をコピーしても、Actorが増えるわけではない:構造体の中にActorなどのObject参照があれば、コピー側の参照も同じObjectを指します。今回のTextとIntegerの例から、「中に入れたものすべてが別個に複製される」とは考えないようにします。

まとめ

構造体は、名前・攻撃力・耐久値を「アイテム1個分」として扱うための型です。Makeで組み立て、Breakで必要な項目を読みます。

配列の更新で迷ったら、いま変えたのはコピーか、元の配列か を確かめてください。今回の90→100→90という出力は、その違いを目で追うための小さな実験です。

次はこのデータに「拾う」「使う」といった操作とUIを加えると、インベントリシステムにつながります。

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