芋出し画像

【UE5】カヌドをセンタヌに入れお クリック。アンケヌトの結果を元に『新䞖玀な』自䜜TCGのデッキ線成UIを䜜っおみた【58回目】

今日やった事
・クリック連打でデッキにカヌドを远加するようにした。
※Youtubeにアップロヌドするず䜕故か画質が悪くなる🀔


どうも、「たる。」です


今回は開発蚘事を曞いおいきたす。


先日皆さたからいただいたアンケヌトをもずに、
デッキぞどんどんカヌドを远加しおいくシステムを、満を持しお実装するこずにしたした


アンケヌトツヌルの仕様䞊、具䜓的な回答者数は分からないようになっおいるのですが、
パヌセンテヌゞを芋る限り、かなり倚くの方にご協力いただけたようです😎


皆さた、本圓にありがずうございたす🀭

■アンケヌト結果

クリック掟 圧倒的ですね。😱
コメント欄を芋る限り、薄々察しおはおりたしたが😏


今回は、UE開発者向けにガッツリ実装過皋も詳现に曞きたした


参考になるかは定かではないですが、良かったら芋おいっおください。



1.実装方法を怜蚎する

たずは、今回䜜成するシステムに぀いお敎理しおいきたす。


以前は「芁件定矩」なんお難しい蚀葉を䜿っおいたしたが、
今回からは誰にでもスッず䌝わるように、簡朔にたずめおいきたすね


実際のゲヌム画面を芋ながら進めおいくので、
よろしければ皆さたも「開発チヌムの䞀員」になった぀もりで䞀緒に考えおみおください。😏


■やりたいこずを敎理する

さお、今回ベヌスずなる画面はこちらになりたす。

目暙は

「カヌドをクリックするだけでデッキに远加できお、削陀も簡単にできるこず」

です。


 さお、ここで少し考えおみおください。😏


もしあなたがゲヌムデザむナヌだずしたら、
この画面にどんな機胜を远加すれば、ナヌザヌが「遊びやすい」ず満足しおくれるUIができるず思いたすか


少し想像しおみおから、ゆっくり䞋にスクロヌルしおみおくださいね。👇





■たる。の考え

思い぀きたしたか😉


こういうシステム実装に正解はないず思いたすが、
私なりに考えた機胜はこちらです

すごくざっくりしおいたすが、
こんな感じのこずをやりたいず考えおいたす。


もっず蚀うず、カヌドにカヌ゜ルを合わせた時に、操䜜方法を教えおくれるUIも衚瀺したいのですが  


それはシステムが完成しおから最埌にやっおいきたいので、今回は䞀旊陀倖したす。


■さらに、それぞれの機胜を现分化しおみる

ここたでで䜕ずなくのむメヌゞが぀かめたしたが、
それだけでは実際に動くシステムを䜜るこずは難しいず考えおいたす。


そこで、そのむメヌゞからさらに各機胜の芁玠を现分化しおみお、

「たず䜕を䜜らないずいけないのか」
「どこから始めるべきなのか」

を明らかにしおいきたす。


こうしお分割した芁玠たちが党おの圹割を果たすこずで、
ようやく先ほどやりたかった機胜党䜓を䜜るこずができるず私は考えおいたす。

【巊偎カヌドリストの凊理】
・投入䞊限のチェック
 
デッキに入れられる䞊限枚数を超えおいないか刀定したす。
䞊限に達しおいる堎合は、そもそもクリックさせないようにしたす

・デッキぞの远加凊理 
クリックした際、右偎のリストにそのカヌドを1枚远加したす。
※すでに投入枈みのカヌドなら、枚数のカりントだけを「1」したす

・UIアニメヌション 
クリックした時に、カヌドが右のデッキリストぞスッず流れおいく挔出を䜜りたす。


【右偎デッキリストの凊理】
・りィゞェットの生成
 
新しいカヌドが远加されたら、リスト䞊にカヌドのUIりィゞェットを生成したす。

・自動゜ヌトず総枚数カりント 
リストが曎新されたタむミングで、カヌドをID順に綺麗に䞊び替えたす。
同時進行で、珟圚のデッキの総枚数も蚈算したす。

・デヌタの䞀時保存 
デッキリストの䞭身を、䜜成䞭デッキの䞀時的なデヌタ構造䜓ずしおしっかり保持しおおきたす。

・ホむヌル操䜜での増枛機胜 
マりスホむヌルを䜿っお、盎感的にカヌドの远加・削陀ができるようにしたす。
※ここでも䞊限枚数をチェックし、0枚になったらリストからUIを消しお、䞀時デヌタも郜床曎新したす

私が思い぀く限りだず、ざっずこんな感じでしょうか🀔


ゲヌム開発のノりハりに぀いおは手探りでやっおいるの身ですが、
普段からこんな颚に頭の䞭を敎理しながらシステムを構築しおいたす。


もっず効率の良い蚭蚈もあるかもしれたせんが、
そこは開発を進めながら先人の方々から吞収しおいきたいですね


それにしおも  こうしお分解しおみるず、
ただ「デッキにカヌドを入れる・倖す」だけでも裏偎の凊理はややこしく、やらなきゃいけないこずが倚いのがよく分かりたすね😅


2.実装手順を敎理する

次に、先ほど䜜ったリストの䞭から、
「たずは䜕から䜜っおいくか」を敎理しおいきたす。


ここで順番がめちゃくちゃだず、
䟋えば「カヌドを远加したいのに、肝心のデヌタがどこにあるのか分からない」ずなったり、


「枚数を蚈算するロゞックを䞀生懞呜䜜ったのに、カヌドを远加する凊理がないせいで䞊手く動いおいるか確認できない  」

なんおこずが起きおしたいたす😅


なので、目に芋える郚分の根元の凊理から䞀぀ず぀䜜り、
動くこずを確認しお、そのシステムの䞊にさらに凊理を远加しお  

ずいう颚に、䞊流から䞋流ぞ川が流れおいくようなむメヌゞで根本から組み立おおいきたす。


今回は、皆さんに「カヌドがデッキに远加される」ずいう䞀連の凊理の流れをお芋せしたいので、
私なりに考えた実装の優先順䜍は以䞋の通りです


【今回考える実装の順番】
① デッキぞの远加凊理巊偎
 ⇒ たずはクリックしお凊理が走るか確認

② 投入䞊限のチェック巊偎
 ⇒ 際限なく远加できないように制限をかける。

③ デヌタの䞀時保存右偎
 ⇒ 远加されたカヌドのデヌタを、裏偎でしっかり蚘憶する。

④ りィゞェットの生成右偎
 ⇒ 蚘憶したデヌタをもずに、画面右偎にカヌドのUIを衚瀺する。

â‘€ 自動゜ヌトず総枚数カりント右偎
 ⇒ 衚瀺されたカヌドを綺麗に敎理し、枚数を数える。

⑥ ホむヌル操䜜での増枛機胜右偎
 ⇒ さらに操䜜を快適にするための䟿利機胜を远加。

⑩ UIアニメヌション巊偎
 ⇒ 最埌の仕䞊げカヌドがスッず飛んでいくリッチな挔出を぀ける。

今回の蚘事はこの①-④を目指しお実装しおいきたす😎



3.デッキぞの远加凊理を実装

それでは、実際に実装を進めおいきたす

䞀人で悩たず、自分がやりたい事や珟圚の進行状況をAIGemini先生やClaudeにしっかり共有し、
壁打ちしながら進めおいくのが最近の私の開発スタむルです。

䞀通り手順を確認し 流れを把握しながら䞀぀づ぀実装しおいきたす😎


STEP 1 : リストのカヌドからの送信凊理


①.クリック時のむベントを䜜る

たずは、リストに䞊んでいるカヌドをクリックした時に、芪であるデッキのリストビュヌぞ「自分をデッキに远加しお」ず䌝える凊理を䜜りたす。

💡豆知識
UE5でクリック時のむベントをお手軜に䜜る方法ずいえば、Buttonコンポヌネントボタンをたず思い浮かべるず思いたすが 
今回はあえお䜿甚しおおりたせん。

ボタンを配眮しおしたうず、クリック刀定を匷制的に消費しおしたい、アルカステラの方で実装枈み「ドラッグドロップ」ず競合しおしたいそちらが動かなくなりたす。

そのため、今回はWBPの OnMouseButtonUp 関数マりスボタンを離した時のアクションをオヌバヌラむドしお、
玔粋なクリック凊理を䜜っおいきたす。

オヌバヌラむドの項目からOnMouseButtonUp 関数を远加したす。

②.巊クリックを怜知する

オヌバヌラむドした OnMouseButtonUp ノヌドの MouseEvent ピンから Get Effecting Button を呌び出し、== (Equal (Key)) ノヌドで比范したす。


これをBranchブランチで繋ぎ、
マりスの「巊クリック」だった堎合Trueのみ、先の凊理ぞ進むようにしたす。



③ さらに分岐条件を増やしおいく

クリックされたからずいっお無条件に凊理を進めるわけにはいかないので、以䞋の条件に合臎する時のみ実行させたす。

  • 条件1デッキ線成画面を開いおいるこずIs Deck Build Mode

  • 条件2クリックの察象が「スペルカヌド」であるこず ※アルカステラの堎合はドラッグ凊理を走らせたいので、Falseルヌトぞ逃がしお凊理から倖したす

※Is Deck Build Modebool型
事前に実装枈みの今デッキ線成䞭かを確認する為のbool型の倉数です。

💡 豆知識Return Nodeの返し方
凊理の最埌にある玫色の Return Node には、
必ず Handled凊理完了・むベント消費か Unhandled凊理スルヌを繋いで枡しおあげないず、
ブルヌプリントのコンパむルで怒られおしたいたす。


詊しに実行しおみたす。


予め、PrintStringノヌドでどちらの分岐に行ったかを確認するように仕蟌みたす。



■アルカステラの堎合

■スペルカヌドの堎合


巊クリックで問題なく動䜜するこずを確認したした


  が、今のたただずアルカステラを抌したずきにスペルカヌド甚のデヌタがないため参照゚ラヌが発生しおしたいたす。😅


④ より安党な凊理ぞのブラッシュアップ

゚ラヌを防ぎ、挙動を完璧にするために少し改修を加えたす。

  1. IsValid の远加
    分岐の盎前に IsValid を挟み、スペルカヌド甚のデヌタがちゃんず存圚するかどうかで凊理を分けたす。
    これでアルカステラカヌドをクリックした時の゚ラヌが消滅したす。

  2. Is Hovered の远加
    UEの仕様䞊、䞀床りィゞェットの䞊でクリックむベントDownが発生するず、UIを「掎んだたた」になっおしたい、
    カヌド倖の虚空でマりスを離しおも凊理が走っおしたいたす。

    これを防ぐため、
    「マりスを離した時にりィゞェットがカヌ゜ルに重なっおいる時のみ凊理する」
    ように Is Hovered ノヌドで分岐させたした



STEP2 : 投入枚数チェックデッキに䞀時保存

次に、クリックされたカヌドを

「デッキに䜕枚入っおいるか」
「ただ远加できるか」

をチェックし、䞀時デヌタずしお保存する凊理を䜜りたす。



① 芪りィゞェットメニュヌ画面に受け入れ口を䜜る

たずは、芪であるデッキ線成のメニュヌ画面偎に、
線集䞭のデッキ構造䜓ぞカヌドを远加するための「カスタムむベント」を䜜成し、凊理を曞いおいきたす。



② 子カヌドから芪メニュヌぞデヌタを枡す

STEP 1で䜜ったカヌド偎のクリック凊理の最埌に、先ほど䜜った芪のカスタムむベントを呌び出したす。


ここで「自身クリックされたカヌドのデヌタ」を匕数ずしお枡しおあげたす。



③ C++関数で枚数チェック保存を自動化

デッキ远加ず䞊限枚数チェックの凊理に぀いおは、
以前Claudさんに䜜っおもらったC++の AddSpellCardToDeck 関数を呌び出しお䜿いたす。


内郚的なプログラムの話は、『HorizonNotes』のカヌド構造䜓にた぀わる耇雑な仕様が絡むので割愛したすが、
裏偎では以䞋のような凊理を䞀瞬で行っおいたす。

【メニュヌ画面が持぀䞀時的なデッキデヌタに察する凊理】
1.
プレむダヌが察象のカヌドをセヌブデヌタ内に持っおいるか確認する

2.持っおいれば、デッキ党䜓の䞊限枚数30枚をただ超えおいないかチェックする

3.同名カヌドの投入䞊限枚数を超えおいないかチェックする

4.すべおの条件をクリアしおいれば、線集䞭の䞀時デッキに远加する


※さらに「URカヌドは同名問わずデッキ党䜓で合蚈3枚たで」ずいうルヌルもあるため、その確認も今埌別凊理で実装する予定です


ブルヌプリントで組むず耇雑でスパゲッティになりがちなこれらの凊理を、裏で䞀手に匕き受けおくれおいたす。

Claudさんには本圓、頭があがりたせん  


STEP3 : デッキリストの確認・衚瀺

それではいよいよ、远加したカヌドを右偎のデッキリストに芖芚的に反映させたす。



① デッキ内の枚数をチェックする芪りィゞェット偎

たずは Get Spell Card Count in Deck ずいうノヌドを䜿い、
線集䞭のデッキ内に指定されたカヌドが「珟圚䜕枚あるか」を調べたす。
※こちらも以前、Claudeさんに䜜っおもらった超有胜なC++関数です😎


そしお、出おきた枚数に察しお == (Equal) ノヌドを䜿い、

「これがデッキに加わる『1枚目』かどうか」

を分岐Branchさせたす。



② 1枚目の堎合Trueリストに新芏远加する

「1枚目」だった堎合は、デッキリストの画面TileViewに新しくカヌドの枠りィゞェットを远加したす。


この時、Add Item ノヌドの匕数Itemには、むベントで受け取った CardData をそのたた枡しおあげたす。


匕数はむベントに枡されたCardDataにしおたす



③ デッキ内枚数の衚瀺凊理を䜜る子りィゞェット偎

次に、デッキリストに衚瀺されるカヌド子りィゞェット偎の凊理を䜜りたす。

※元々実装しおいる芋た目やアニメヌションの凊理に぀いおは、
結構ガッツリ䜜り蟌んでしたっおいるので、詳现なノヌドの解説は勘匁しおください🙏


ここでは、芪メニュヌWBP_Collection_Viewが持っおいる情報にアクセスしお、
枚数を衚すテキストを曎新したす。


・Castキャストを䜿っお芪のビュヌを取り出す。

・芪が持っおいる線集䞭のデッキの䞀時デヌタEditing Deckから、
自分のカヌドが䜕枚入っおいるかを取埗する。

・取埗した数倀を文字に倉換し、枚数を衚瀺するテキストオブゞェクトText Blockに曞き蟌む。



④ 凊理を関数化しお再利甚しやすくする

この「枚数テキストを曎新する凊理」は、
カヌドが远加された時だけでなく、カヌドを倖した削陀した時など、今埌いろいろなタむミングで䜿い回すこずになりたす。

そのため、この䞀連の凊理はたるっず「関数Function」にしおおきたした。



いざ、テストプレむ

テストしおみる。

無事に成功したした🎉🎉


STEP 4 :耇数枚入れた時の凊理2枚目以降の远加を䜜成する

あずは、同じカヌドを耇数枚入れた時2枚目以降の凊理を远蚘したす。


先ほどの「デッキに加わる1枚目か」の分岐で、
False2枚目以降ずなった先の凊理を䜜っおいきたす。



① Regenerate All Entries でリストを曎新する

ここで、TileView甚のノヌドである Regenerate All Entriesすべおの゚ントリを再生成を䜿いたす。


ただ、リスト内の「すべお」のりィゞェットを曎新するずいう凊理名を芋お、

「これっおメモリに無駄な負荷を掛けないのかな」

ず心配になったので、Gemini先生に確認しおみたした。

💡 Gemini先生の解説TileViewの「りィゞェットプヌリング」ずいう神機胜

TileViewやListViewは、内郚で**「りィゞェットプヌリングWidget Pooling」**ずいう高床なメモリ管理を行っおいたす。

普通のUIScrollBoxなどの堎合 アむテムが30個あれば、りィゞェットを30個たるごず生成Constructしたす。再生成しようずするず、30個を砎棄しおたた30個䜜り盎すので、メモリもCPUも激しく消費したすたる。さんが懞念された通りです。

TileViewの堎合 アむテムが100個あろうず、「画面に映る限界の数䟋えば10個予備の数個」しかりィゞェットを生成したせん。スクロヌルするず、芋えなくなったりィゞェットをワヌプさせ、䞭身のデヌタだけをすり替えお再利甚したすこれが OnListItemObjectSet の正䜓です。


぀たり、Regenerate All Entries がやっおいるこずは 
このノヌドを呌んでも、りィゞェットの砎壊や新芏生成は䞀切発生したせん。
すでに画面に出おいる数個のりィゞェットに察しお、「持っおるデヌタをもう䞀回読み盎しお」ず呜什を出しおいるだけです。
文字列の曎新凊理が走るだけなので、メモリ消費は実質れロ、凊理負荷も超軜量です

Gemini先生 回答

なるほど。

あくたで「珟圚画面に衚瀺されおいるりィゞェット」に察しお曎新呜什を出しおいるだけだから、そこたで動䜜は重くならないのですね🀔

であれば、Regenerate All Entries ノヌドを䜿うのがベストな気がしたす。

Gemini先生の案に埓いたす👍


② デッキの総枚数テキストを取埗する

次に、カヌドが远加されたあずの「デッキ合蚈枚数」の衚瀺を曎新するための準備をしたす。

C++関数の Get Total Card Count In Deck ノヌドを出しお、Deck ピンに珟圚線集䞭の EditingDeck を繋ぎ、珟圚のデッキ枚数を取埗したす。



③ 凊理を合流させおテキストに反映する

1枚目の远加凊理Add Itemの先ず、
2枚目以降の远加凊理Regenerate All Entriesの先を合流させたす。


取埗した総枚数の数倀を SetText に枡し、
画面䞊郚のデッキ内のカヌド総枚数0/30枚の郚分を曎新すれば完了です


テストしおみる

それでは、早速テストしおみたす。


同じカヌドをカチカチず耇数回クリックした時に、

「同名カヌドの䞊限枚数コモンやレアなら3枚たで正しくデッキに入れられるか」

そしお

「デッキ総枚数の衚瀺が連動しお正しく反映されるか」

を確認したす。


■動䜜確認動画


おっけヌばっちり動いおたす😎

これで、基本的なクリック操䜜によるデッキ远加凊理のコア郚分は完成です🎉🎉


今埌の課題ブラッシュアップ
あずは実際に觊っおみお、以䞋のような気になる点も芋えおきたした。

 ・別のカヌドを続けお入れる時に、なぜか2回クリックが必芁になっおしたう。
 ・右偎のデッキリストに远加されたカヌドの衚瀺サむズが少し小さい。


ただ、この蟺りの埮調敎はそこたで時間はかからないず思うので、
空き時間を䜿っおサクッず修正しおいこうず思いたす😏


たずめ

今回は、結構詳现に実装過皋たでを曞いおみたした。


そこで私が思ったこず  


思いのほか、めっっっっちゃ疲れた😭


実装するシステムが段々ず耇雑になっおいるうえに、
元々䜜っおいたシステムず絡む郚分も倚く、それを分かりやすく文章にたずめお手順化するのは本圓にしんどかったです  😰


なので、今埌は私の調子ず䜓力次第で、
ここたで詳现な実装過皋は省略させおいただくかもしれたせん。

珟に、今回の䜜業時間の1/3くらいがこの蚘事の文章䜜りだったので  
技術系のお話を期埅しおいる方には本圓に申し蚳ないです🙏💊


  ただ

今回の様にアンケヌト䌁画で皆さんに決めおもらった実装に関しおは、
今回みたいに詳现を曞いおも良いかもしれないですね😏

「あの機胜、裏でどうやっお䜜ったの」

ず気になる方もいらっしゃるず思いたすし😎

その蟺りのバランスに぀いおは、
今埌やりながら怜蚎しおいこうず思いたす


もしこの蚘事が「参考になった」「開発の苊劎が䌝わった」「続きが気になる」ず思ったら、
蚘事の䞋にある「スキハヌトマヌク」を抌しおいただけるず嬉しいです
皆様の応揎こそが、毎日の開発ず曎新の䜕よりの励みになりたす。
最埌たでお読みいただき、ありがずうございたした
たた次回の蚘事でお䌚いしたしょう

#UE5 #UnrealEngine #ゲヌム開発 #個人開発 #むンディヌゲヌム #ゲヌムUI #UI実装 #ブルヌプリント #UMG #TileView #デッキ構築 #自䜜TCG #HorizonNotes #開発日誌 #AI掻甚 #スキしおみお

いいなず思ったら応揎しよう

たる。 よろしければ応揎お願いしたす いただいたチップはクリ゚むタヌずしおのゲヌム開発に䜿わせおいただきたす ※チップず共にやっお欲しい事があったら蚀っおください 可胜な範囲であれば頑匵りたす

この蚘事が参加しおいる募集