芋出し画像

【プロゞェクトNeith】GW合宿線みんなで䜜るゲヌム制䜜【4/29,4/30】

■今回やった事

今回は以䞋の凊理を䜜り蟌みたした

4/29(æ°Ž)

  • むンベントリの䜜成

  • アむテムの䜿甚凊理

  • アむテム入手


4/30(朚)

  • ショップ機胜䜜成

  • バトル開始たで

■募集䞭のアむディア
①「暹海線」で発生しそうなむベント
䟋森の䞭、クマさんに出䌚った。お化けず遭遇 など
※期限はありたせん皆さんの自由でナニヌクな発想をお埅ちしおいたす。

② 䞻人公・ネむトの「スキル」※もう少し延長したす
䟋ファむアボヌル / 射皋2マス先の䞀䜓 / 効果察象に小ダメヌゞ
※王道からちょっず笑えるネタスキルたで、
どんなアむディアでも倧歓迎です


③ゲヌムで流す著䜜暩フリヌのBGMを教えおください

無料のフリヌのBGMを探しおたす

あなたのお気に入りを教えおください
生成AIで自䜜したものも可胜。
その堎合は、コメントやDMでお知らせください


こんにちはたる。です。


投皿が遅れおしたい、申し蚳ございたせん🙇‍♂


この2日間、ガッツリ開発を進めおいたのですが、
䜜業に熱䞭するあたり蚘事の執筆が远い぀かず、
noteの曎新がストップしおしたっおいたした  


さお、1ヶ月チャレンゞの「プロゞェクトネむト」もいよいよ2週間目に突入し、期間も残り半分を切りたした。


そこで、今回からはGW特別䌁画「合宿線」ず題したしお、
さらにハむペヌスで開発を進めおいきたす🔥


実装内容が耇雑になっおきたため、以前のような詳现な解説は少し枛っおしたうかもしれたせんが  


完成に向けお党力で駆け抜けたすので、
どうか最埌たで応揎しおいただけるず嬉しいです


それでは、さっそく4/29(æ°Ž)・4/30(朚)の2日分の開発蚘録をご芧ください😎



二人の茶番

🎧今日の䜜業甚BGM

Tipsy_Dance䜜線曲 ヒオ
【民族音楜颚/é…’å Ž/螊り】Tipsy Dance【フリヌBGM】

ポマむラ自称ネむトの䜿い魔

「よお、おたえらオレだよ、ポマむラ様だ

おたえら、ちゃんず枩かくしお寝おるか
今の時期、油断しおいるずすぐ颚邪を匕くからな
ちゃんず䜓調管理するんだぞ」

ネむト幻の星の粟霊

「  ちなみに、私は完党に喉をやられたわ。
あヌ  むガむガする」

ポマむラ自称ネむトの䜿い魔

「おいおい、ネむトさんよ。
これから開発も折り返しだっおのに、そんなんで倧䞈倫かよ」

ネむト幻の星の粟霊

「ゲヌム開発はもう、私の日垞に完党に溶け蟌んでるから平気よ。
むしろ、觊っおないず萜ち着かないくらいだわ。」

ネむト幻の星の粟霊

「  ずは蚀え、集䞭力が切れたら遠慮なく䌑たせおもらうわね。
身䜓が䞀番倧事だもの」

ポマむラ自称ネむトの䜿い魔

「そうだぜ、ネむト
䜓調が良い時に本気で打ち蟌むのが䞀番だからな」


■ プロゞェクトの方向転換「1日2時間ルヌル」の撀廃に぀いお

ネむト幻の星の粟霊

「たず、皆さんに報告  ずいうか、謝りたいこずがあるの」

ポマむラ自称ネむトの䜿い魔

「どうした、ネむト。藪から棒に」

ネむト幻の星の粟霊

「私たちが初日に掲げたルヌル  『開発時間は毎日1〜2時間たで』ずいう制限を、
ここで撀回させおもらえないかしら」

2. 開発時間は「毎日1〜2時間」たで
本線の開発がおろそかになっおしたっおは本末転倒なので、
きっちり時間を区切りたす。
※どうしおも ずいう熱い倜だけは残業を蚱可したす 😗

ポマむラ自称ネむトの䜿い魔

「あぁ、本線の開発に支障が出ないように決めたあのルヌルか。
でも、どうしお今になっお改たっお」

ネむト幻の星の粟霊

「シミュレヌションRPGSRPGのバトルシステムを構築しおいお、痛感したの。

いくら生成AIを駆䜿しおコヌディングを効率化しおいるずはいえ、1日2時間ではこのシステムを完成させるのは䞍可胜だわ」

ポマむラ自称ネむトの䜿い魔

「たあ、SRPGは凊理が耇雑だもんな。
正盎、かなり苊戊しおるだろ」

ネむト幻の星の粟霊

「ええ。正盎に蚀うず、私の技術力䞍足も倧きいわ。
この2日間ずっず詊行錯誀しおいたけれど、
れロからバトルシステムを組むのは想像以䞊に倧倉だった  。
特に、自䜜の育成システムや『宎3』ず連動させながら動かす郚分が、想定の䜕倍も耇雑だったのよ」

ポマむラ自称ネむトの䜿い魔

「育成呚りが順調だった分、バトルの重さを芋誀っちたったか」

ネむト幻の星の粟霊

「そうね  そこは芋積もりが甘かったず反省しおいるわ。
でも、だからずいっお劥協しお終わらせたくはないの。
この『1ヶ月でゲヌムを完成させる』ずいう挑戊をやり遂げるために、これからは時間の制玄を倖しお党力で取り組むこずに決めたわ」

ポマむラ自称ネむトの䜿い魔

「でも、そうなるず本線メむンプロゞェクトの開発が止っちたわないか」

ネむト幻の星の粟霊

「ええ。
でも、今は『プロゞェクトネむト』を通じおゲヌム開発のスキルを磚くこずが、䜕より貎重な経隓になるず刀断したの。

ここで埗た技術や知芋は、たずえゲヌム゚ンゞンが倉わっおも、
必ずどこかで私たちの圹に立぀はず。
だから、今はこれに専念させおほしいの」

ポマむラ自称ネむトの䜿い魔

「  そこたで蚀うなら止めねえよ。
その代わり、このnoteにはどれだけ時間がかかったか、
しっかり『䜜業工数』ずしお蚘録を残しおいこうぜ。
1ヶ月で䜕ができるか、みんなも気になっおるだろうしな」

ネむト幻の星の粟霊

「そうね
これからは『どれだけの時間で完成たで挕ぎ着けたか』を蚌明する挑戊にシフトしおいくわ。
みんな、匕き続き芋守っおいおね」


■ 4/29(æ°Ž) むンベントリシステムの䜜成䜜業時間玄5時間

ポマむラ自称ネむトの䜿い魔

「さお、ここからは実際の䜜業の振り返りだな。
たずは䞀昚日、4/29の䜜業から振り返っおいくんだろ」

ネむト幻の星の粟霊

「そうね。ガッツリ開発に没頭しおいたから、詳现なコヌドたでは茉せきれないけれど  
どんな颚に進めたのか、順を远っお説明しおいくわ」

ポマむラ自称ネむトの䜿い魔

「この日のメむンは『むンベントリシステム』だったよな。
暪で芋おおも、盞圓沌っおるのが䌝わっおきたぜ  」

ネむト幻の星の粟霊

「本圓に倧倉だったわ  。
甚意するUIパヌツも倚いし、裏偎のデヌタ凊理も耇雑で。
䜕より、組み䞊がった埌の现かいバグ修正に䞀番時間が溶けちゃった気がするわね」

ポマむラ自称ネむトの䜿い魔

「でも、これでようやくゲヌムらしくなっおきたよな」

ネむト幻の星の粟霊

「ええ
ようやく育成メニュヌでアむテムを管理・確認・䜿甚ができるようになったの。
ずいうわけで、たずは苊劎しお䜜り䞊げた4/29時点の成果を、動画で皆さんに共有するわね」

■むンベントリメニュヌ完成版動画


むンベントリメニュヌUI䜜成䜜業時間:時間ほど

ネむト幻の星の粟霊

「たず着手したのは、むンベントリに必芁なUIの掗い出しね。
今回、最䜎限必芁だず刀断したのはこの5぀の画面よ」

  • むンベントリメむン画面所持アむテムの䞀芧衚瀺

  • アむテム詳现・効果説明欄説明文を衚瀺する゚リア

  • 䜿甚確認ダむアログ「はい/いいえ」の最終確認

  • 察象遞択画面誰に䜿甚するかを遞ぶ画面

  • 䜿甚結果・反映画面䜿甚埌のステヌタス倉化などを通知


① むンベントリメむン画面効果説明欄

ネむト幻の星の粟霊

「たずはベヌスずなる䞀芧画面。
スピヌド重芖でシンプルにデザむンしたわ。
以前䜜った遞択画面の仕組みを流甚しお、
アむテムリスト甚のスクロヌルビュヌの䞭に、アむコン甚のプレハブが䞊ぶようにしたの」


■アむテム効果説明欄

ネむト幻の星の粟霊

「効果説明欄は、利䟿性を考えおメむン画面ず䞀䜓化させおいるの。
アむテムにカヌ゜ルを合わせるず、リアルタむムでテキストや画像が切り替わる仕組みね」


② 䜿甚確認察象遞択画面

ネむト幻の星の粟霊

「アむテムを遞んだ埌は、誀操䜜を防ぐための『䜿甚確認画面』が出るようにしたわ。
画像ず遞択肢だけのシンプルな構成ね」

■誰に䜿うかの遞択画面

ネむト幻の星の粟霊

「察象者の遞択画面。
ここは線成画面などで䜿った仕組みを応甚できたから、迷わず実装できたわね」


③ アむテム効果反映リザルト画面

ネむト幻の星の粟霊

「これは私のこだわりなんだけど、
アむテムを䜿った埌に『䜕がどう倉わったか』をしっかり芋せる画面も甚意したわ。
䜿甚したアむテムの皮別によっおアむコンが倉わるようにデザむンしおいるの」


■ なぜアセットを䜿わず「自䜜」したの


ポマむラ自称ネむトの䜿い魔

「こうしお芋るず、むンベントリだけでも結構な数のUIを䜜ったんだな
  でもよ、こういうのっお無料のアセットずか䜿えばもっず楜にできたんじゃねえのか」

ネむト幻の星の粟霊

「確かに、効率だけを考えればアセット導入が䞀番かもしれないわね。
でも、このプロゞェクトではアむテム情報を『宎3』や『Json』で管理しおいるでしょう」

ネむト幻の星の粟霊

「倖郚のアセットを䜿うずなるず、たずそのアセットの仕様を読み解いお、私のシステムに合うようにコヌドを曞き換えなきゃいけないの。
そうなるず、修正箇所を探す手間のほうが倧きくなっおしたうのよ」

ネむト幻の星の粟霊

「結果的に、1から自分で䜜った方が完党にコントロヌルできるし、埌の拡匵もしやすい。
だから今回は、あえお『自䜜』の道を遞んだの」

ポマむラ自称ネむトの䜿い魔

「なるほどな  。
アセットは䟿利だけど、自分の蚭蚈に組み蟌むなら、䜿い勝手たで考えなきゃいけないっおこずか。
自䜜の方が『自由が利く』っおわけだな」


むンベントリシステムの䜜成(4時間ほど)

ネむト幻の星の粟霊

「UIができたずころで、次は『䞭身』
――むンベントリシステムの䜜成よ。

コヌドを党郚茉せるず倧倉なボリュヌムになっちゃうから、
どんな機胜を実装したか敎理しおみたわ」

  • UIアクセス機胜: 各メニュヌ画面ぞのスムヌズな遷移凊理

  • デヌタ読み蟌みず衚瀺: 『宎3』に蚘録されたプレむダヌの所持アむテムJSONを読み蟌み、所持しおいるアむテムず個数だけをリスト䞊にプレハブずしお生成

  • 察象者のフィルタリング:

    • 「奜感床アップアむテム」の䜿甚時は、ネむト以倖の仲間にしおいるアルカステラのみを衚瀺

    • 「ステヌタス䞊昇アむテム」の䜿甚時は、ネむトを含む党員を衚瀺

  • 各皮実行凊理: 回埩・ステヌタス䞊昇・奜感床アップのロゞック構築

  • リアルタむム曎新: アむテム䜿甚埌にテキストや画像を最新の状態ぞ反映する凊理

ポマむラ自称ネむトの䜿い魔

「どひゃヌ  。
箇条曞きにするずさらっず流しちたいそうだけど、これ、めちゃくちゃやるこず倚いじゃねぇか」

ネむト幻の星の粟霊

「そうなのよね。
䞀気に党郚䜜ろうずするず、どこで躓いたか分からなくなるから  。
たずは『画面が正しく切り替わるか』、次に『テキストが正しく倉わるか』ずいう颚に、段階を螏んで䞀歩ず぀実装しおいったわ」

ネむト幻の星の粟霊

「それ以倖にも、䞊行しお『アむテムを取埗するむベント』を甚意したりもしたのだけど、最初は䞊手くいかなくお  。

ずにかく䞀個ず぀確認しおはバグを盎しおの繰り返し。
その泥臭い䜜業が䞀番倧倉だったわね」

ポマむラ自称ネむトの䜿い魔

「それで、あんなに時間が掛かっおたのか  。
よく投げ出さなかったな、頑匵ったじゃねえかネむト」

ネむト幻の星の粟霊

「ふふ、今のずころは倧きな䞍具合もなく、ちゃんず動いおくれおいるわ。
苊劎した分、愛着の湧くシステムになったから良しずするわね」


■ 4/30(朚) むンベントリのブラッシュアップ・ショップ䜜成・戊闘開始凊理䜜業時間玄8時間

ネむト幻の星の粟霊

「次は昚日4/30実装した内容ね。
正盎、䜜業に没頭しすぎお正確な工数は芚えおいないの  。
䜓感で8時間くらいかしら。ごめんなさいね」

ポマむラ自称ネむトの䜿い魔

「8時間っお  マゞかよ。
でも、これで育成メニュヌのシステムはほが完成したんだろ」

ネむト幻の星の粟霊

「ええ。
ただオプションメニュヌが残っおいるけれど、おおよその根幹郚分は完成したずいう認識で構わないわ
実はこの日は開発14日目  ぀たり、プロゞェクトの『折り返し地点』だったの。
このタむミングたでに育成メニュヌのシステムを䜜り䞊げるこずは、最初から目暙に決めおいたから、
䞀気にスパヌトをかけお頑匵ったわ」

ポマむラ自称ネむトの䜿い魔

「おおっ぀いに育成システムの完成か
なんか胞が熱くなるな」

ネむト幻の星の粟霊

「  ずはいえ。
育成に関しおはあず䞀぀だけ、どうしおも䜜っおおきたいシステムがあるの。
ただ、それは戊闘システムの実装が萜ち着いおから着手する぀もりよ」


■ 自分だけのネむトを䜜成「ノァンサバ颚」スキルピックシステムの構想

ポマむラ自称ネむトの䜿い魔

「あず䞀぀䜜らなきゃいけないシステムっおなんだ」

ネむト幻の星の粟霊

「私が戊闘䞭に習埗するスキルを、
『ノァンパむア・サバむバヌズ』のようにランダム提瀺からピック遞択しおいく機胜よ
これは、䌁画の最初にみんなからゲヌムゞャンルのアンケヌトを取った時に着想を埗たの」

ポマむラ自称ネむトの䜿い魔

「おいおい  
ノァンサバの芁玠たで取り入れる気かよ。
でもよ、その仕様にするなら、ネむトが芚えるスキルをめちゃくちゃ沢山甚意しないずいけねぇよな」

ネむト幻の星の粟霊

「そこなのよだから今、読者の皆さんにスキルのアむディアを倧募集しおいるの。

皆さんが考えおくれた効果やスキル名を、このシステムにそのたた取り入れようず思っおいるわ」

ネむト幻の星の粟霊

「  ずはいえ、このスキルの実装䜜業がどれくらい倧倉なボリュヌムになるかは未知数だから、
システムの開発自䜓は少し埌回しにしおいるのだけれど」

ポマむラ自称ネむトの䜿い魔

「なるほどな
みんなの考えたスキルで、毎回違うネむトに育っおいく  。
これが実珟したら、ずんでもなく面癜いゲヌムになりそうだぜ」

ネむト幻の星の粟霊

「そうね
私にたくさんのアむディアを頂戎
どうか応揎しおね」


むンベントリシステムのブラッシュアップずショップシステムの䜜成(4時間くらい)

ネむト幻の星の粟霊

「ここからは少し駆け足での玹介になっおしたっお申し蚳ないのだけど  最終的に、こんな感じでショップシステムも完成させたわ」

■ショップ機胜動䜜確認

ポマむラ自称ネむトの䜿い魔

「4時間もかけた䜜業を党郚説明するのは、流石に骚が折れるからな。
ちなみに、䜜っおみおの『コツ』や苊劎したポむントは䜕かあったか」

ネむト幻の星の粟霊

「基本的なシステムの仕組み自䜓は、さっき玹介したむンベントリずほが同じよ。
たずはUIを䜜っお、リストの䞭に商品のプレハブを生成しお  ずいう流れね」

ネむト幻の星の粟霊

「ただ、少し倧倉だったのは『店員さんに商品説明をさせる』郚分かしら。
アむテムの効果をプレむダヌにどう䌝えるか考えた時に、『お店の人にセリフで解説しおもらおう』ず決めたの」


ネむト幻の星の粟霊

「アむディアずしおは良かったのだけど、アむテムごずに説明甚のセリフを考えたり、
それをUI䞊でスムヌズに衚瀺させる凊理を組むのが、思ったより手間がかかったわね」

ポマむラ自称ネむトの䜿い魔

「なるほどな。
でもそのこだわりのおかげで、ただの無機質なシステムじゃなくお『お店で買い物しおる感』が出お、䞭々良いものが䜜れたんじゃねぇか」

ネむト幻の星の粟霊

「そう蚀っおもらえるず嬉しいわ苊劎した甲斐があったずいうものね」


バトルシヌンぞの移行凊理4時間くらい

ネむト幻の星の粟霊

「そしお次に、いよいよゲヌムの華『バトルシヌン』の構築にも本栌的に着手したわ。
  ずは蚀え、ここたで来るのにコヌドを曞いおは消しお、たた新しく組み盎しお  ずいう泥臭い䜜業の繰り返しだったの。
だから今回は、個人的に倧倉だった郚分ず芁点だけをかい぀たんで䌝えるわね」

ポマむラ自称ネむトの䜿い魔

「埅っおたした、バトルシステム
埡蚗はいいから、早速今どんな感じで動いおるのか芋せおくれよ」

■バトル開始たで動画

ポマむラ自称ネむトの䜿い魔

「おおっ、すげぇ
ちゃんず前回䜜ったマス目状の戊堎に、キャラクタヌのナニットが配眮されおるじゃねぇか
しかも、戊闘BGMたで鳎っおる」

ネむト幻の星の粟霊

「ただ内郚で『バトルのタヌン制埡』ができるようになった段階で、
具䜓的な行動は『移動』くらいしかできないのだけど  。
それでも、SRPGずしおの土台をここたで動かすのには本圓に苊劎したわ」

ネむト幻の星の粟霊

「ずはいえ
䞀番の鬌門だった『基瀎システムの構築』ずいう壁は無事に越えられたわ。
あずは個別の凊理やデヌタを䞀぀ず぀䜜っおいくだけの段階たで来おいるから、安心しおね」


■ 宎ずバトルシヌンを独立させるBattleSessionDataアセットの䜜成

ポマむラ自称ネむトの䜿い魔

「そんじゃ、たずはどうやっおその土台を䜜ったのか聞かせおくれよ」

ネむト幻の星の粟霊

「SRPGを䜜る䞊で私がたず思ったこずは、
『どうやっおプレむダヌ偎のナニット情報を管理しお、バトルに持ち蟌むか』だったわ」

ネむト幻の星の粟霊

「ほら、育成メニュヌの時は『宎3』の機胜を䜿っお、Json圢匏でアむテムやステヌタスの情報を持たせおいたでしょ
でも、バトルはそもそもUnity䞊の『シヌン堎面』が違うから、
宎3の機胜をそのたた匕っ匵っおくるこずはできないの」

ネむト幻の星の粟霊

「簡単に蚀うず、グラりンドバトルシヌンでサッカヌをやりたいのに、
サッカヌボヌルキャラクタヌのデヌタがスポヌツショップ宎3にしか眮いおなくお持ち出せない  みたいな状況ね。
バトル䞭から宎偎のデヌタは盎接確認できないのよ」

ネむト幻の星の粟霊

「そこで解決策ずしお、育成メニュヌ偎からバトルぞ切り替わる盎前に、
線成された『アルカステラ』の情報を、ランタむムゲヌム実行䞭専甚の『ScriptableObjectスクリプタブル・オブゞェクト』に曞き蟌むようにしたの」

💡 ネむトのUnity豆知識ScriptableObjectっおなに
Unityで䜿える「デヌタを入れおおくための専甚の箱ファむル」のこずよ
通垞、キャラクタヌや画面のデヌタはシヌン堎面を移動するず消えちゃうんだけど、ScriptableObjectはシヌンの倖に独立しお存圚できるから、「シヌンをたたいでもデヌタが消えずに持ち越せる」ずいうすごく䟿利な特城があるの。

ネむト幻の星の粟霊

「この機胜を䟋えるなら、シヌンをたたいでも消えない『䌝蚀掲瀺板』みたいな圹割ね
バトル開始前に、プレむダヌの線成情報を育成メニュヌ偎のシヌンからこの掲瀺板に曞き蟌んでおくの。
そしお、バトルシヌン偎はそこに曞かれた情報を読んで、ナニットを䜜成する。そんなむメヌゞよ」

ポマむラ自称ネむトの䜿い魔

「なるほどな
シヌン同士で盎接やり取りするんじゃなくお、共通の参照先ファむルを別で甚意しお、そこをデヌタの䞭継地点にするっおわけか」



■ シヌンを跚いでもデヌタを枡すBattleSceneBridgeの䜜成

ネむト幻の星の粟霊

「さっき、『シヌンを跚ぐず宎3が䜿えない』っお話をしたわよね
ずいうこずは  バトルが終わった埌に、育成画面や勝利埌のむベント宎3のシステムに戻すには、どうすれば良いず思う」

ポマむラ自称ネむトの䜿い魔

「えっず  育成メニュヌやむベント挔出は『宎3』がある元のシヌンでやっおるんだよな。
で、バトルシヌンには宎3がない  。」

ポマむラ自称ネむトの䜿い魔

「あれ そもそもバトル䞭はどうやっお元のシヌンの様子を知るんだ」

ネむト幻の星の粟霊

「その通り、そこが問題なのよポマむラ。
そこで、バトル前にさっきの䌝蚀掲瀺板ScriptableObjectぞ曞き蟌みを行い぀぀、
シヌン間の行き来を管理する『橋枡し圹BattleSceneBridge』が必芁になるの」

ネむト幻の星の粟霊

「この橋枡し圹の圹割は、倧きく分けお2぀よ。
䞀぀は、宎3がいるシヌンから䌝蚀掲瀺板にバトル情報を曞き蟌んで、
バトルシヌンに切り替えるこず。
もう䞀぀は、䌝蚀掲瀺板に『バトルが終わった』ずいう報告が曞き蟌たれたのを確認しお、再び宎3がいる元のシヌンに切り替えお戻すこずよ」

ポマむラ自称ネむトの䜿い魔

「なるほどな。シヌン間の『䌝什圹』っおわけか
  でもよ、そい぀はどうやっお䌝蚀掲瀺板が曎新されるたで、
ずっず倧人しく芋匵っおおくれるんだ」

ネむト幻の星の粟霊

「そこで䜿うのが『コルヌチンCoroutine』ずいうプログラミングの呜什よ
これは、特定の条件を満たすたで凊理を䞀時停止しお埅機させるこずができる、ずっおも䟿利な機胜なの」

ネむト幻の星の粟霊

「぀たり、この䌝什圹に『䌝蚀掲瀺板に終了の知らせが曞き蟌たれるたで埅機しおね』ずコルヌチンで呜什しおおくの。

そしお、バトルシヌン偎で戊闘が終わった時にその報告を曞き蟌めば、
䌝什圹がそれに気づいお無事に元のシヌンぞ切り替えおくれる、ずいう仕組みよ」

ポマむラ自称ネむトの䜿い魔

「おお
その䌝什圹ずコルヌチンのおかげで、シヌンの切り替えずむベントの再開がスムヌズに連携できるっおわけか コむツは偉いぜ」


■ バトルの準備をしおくれる舞台挔出家BattleSceneSetup

ネむト幻の星の粟霊

「他にも倚くの  本圓に倚くのシステムがそれぞれの仕事をこなしお、
ようやく䞀぀のバトルシステムが動いおいるのだけど。
今回は代衚しお、この『BattleSceneSetupバトルシヌンセットアップ』ずいう子を玹介するわね」

// BattleSceneSetup.cs
// バトルシヌンのマップ生成・敵配眮を担う MonoBehaviour。
//
// 【v2 倉曎点】
//   AdvEngine ぞの䟝存を完党に排陀。
//   battleId ず PartyData は BattleSessionDataScriptableObjectから読み取る。
//   → バトルシヌンに AdvEngine や TrainingMenuBridge を眮く必芁がなくなった。
//
// 【責務の敎理】
//   BattleSceneSetup  : BattleSessionData からデヌタを受け取り、マップ生成 + 敵配眮Awake で実行
//   PartyEditPanel    : プレむダヌナニット配眮 + SetupBattle + StartBattle
//   BattleViewManager : ビゞュアル生成マップ描画・ナニットスプラむト
//
// 【デヌタの流れ】
//   宎3シナリオ
//     → $SetParam CurrentBattleId, "battle_001"
//     → SendMessage, StartBattleたたは OpenPartyEdit
//   BattleSceneBridge育成シヌン
//     → BattleSessionData.WriteForBattle(battleId, party)
//     → SceneManager.LoadScene("BattleScene")
//   BattleSceneSetupバトルシヌン
//     → sessionData.battleId を読んで BattleSetupDatabase を怜玢
//     → マップ・敵を生成
//   PartyEditPanel / BattleManager
//     → SetupBattle → StartBattle

using System.Collections.Generic;
using UnityEngine;
using TrainingGame.Battle;

namespace TrainingGame
{
    public class BattleSceneSetup : MonoBehaviour
    {
        // ── Inspector フィヌルド ──────────────────────────────────────

        [Header("デヌタ参照")]
        [Tooltip("党バトルシナリオを管理するルックアップテヌブル")]
        [SerializeField] private BattleSetupDatabase battleDatabase;

        [Tooltip("シヌン間のデヌタ受け枡し甚 ScriptableObject\n" +
                 "BattleSceneBridge ず同じアセットをアサむンするこず")]
        [SerializeField] private BattleSessionData sessionData;

        [Header("テスト甚フォヌルバック゚ディタヌ再生・単䜓テスト甚")]
        [Tooltip("sessionData が未セット or isReady=false のずきに䜿うデフォルトデヌタ")]
        [SerializeField] private BattleSetupData fallbackSetupData;

        [Header("バトル開始甚参照")]
        [SerializeField] private BattleManager battleManager;
        [SerializeField] private View.BattleViewManager battleViewManager;

        [Header("オヌディオ")]
        [Tooltip("BGMを鳎らすためのAudioSourceコンポヌネント")]
        [SerializeField] private AudioSource bgmSource;

        private BattleSetupData _currentSetupData;

        // ── 生成枈みデヌタ ────────────────────────────────────────────

        private GridMap                _map;
        private List<UnitBattleState>  _enemyUnits = new List<UnitBattleState>();

        // ── 公開プロパティ ────────────────────────────────────────────

        /// <summary>生成枈みのグリッドマップ</summary>
        public GridMap Map => _map;

        /// <summary>配眮枈みの敵ナニット䞀芧</summary>
        public List<UnitBattleState> EnemyUnits => _enemyUnits;

        /// <summary>マップず敵の初期化が完了しおいるか</summary>
        public bool IsInitialized { get; private set; }

        /// <summary>
        /// セッションデヌタから埩元したパヌティ情報。
        /// PartyEditPanel や BattleManager が参照する。
        /// </summary>
        public PartyData SessionParty { get; private set; }

        // ── 互換メ゜ッドPartyEditPanel から呌ばれる ──────────────

        public GridMap GetMap() => _map;
        public List<UnitBattleState> GetEnemyUnits() => _enemyUnits;

        // ── Unity ラむフサむクル ──────────────────────────────────────

        private void Awake()
        {
            _currentSetupData = ResolveSetupData(); // ←倉数に保存するように倉曎
            if (_currentSetupData == null)
            {
                Debug.LogError("[BattleSceneSetup] BattleSetupData を取埗できたせんでした。");
                return;
            }

            // 【削陀】↓↓↓ ここから䞋の5行は䞍芁です ↓↓↓
            // var setupData = ResolveSetupData();
            // if (setupData == null)
            // {
            //     Debug.LogError("[BattleSceneSetup] BattleSetupData を取埗できたせんでした。");
            //     return;
            // }
            // 【削陀】↑↑↑ ここたで ↑↑↑

            // セッションデヌタからパヌティを埩元しおおく
            SessionParty = sessionData != null && sessionData.isReady
                ? sessionData.RestoreParty()
                : new PartyData();

            // ★ 䞋蚘の BuildMap ず PlaceEnemyUnits の匕数を `setupData` から `_currentSetupData` に倉曎したす
            BuildMap(_currentSetupData);
            PlaceEnemyUnits(_currentSetupData);

            IsInitialized = true;
            Debug.Log($"[BattleSceneSetup] '{_currentSetupData.battleName}' のマップ・敵を初期化完了。" +
                      $"敵 {_enemyUnits.Count} 䜓。");
        }

        private System.Collections.IEnumerator Start()
        {
            // BattleViewManager がマップを描画し終わるたで1フレヌム埅぀
            yield return null;

            if (_currentSetupData == null || !IsInitialized) yield break;

            // 1. プレむダヌナニットの生成
            var startPositions = _currentSetupData.playerStartPositions;
            var playerUnits = new System.Collections.Generic.List<UnitBattleState>();
            int posIndex = 0;

            for (int i = 0; i < PartyData.MaxSlots; i++)
            {
                string unitId = sessionData.partySlots[i];
                if (string.IsNullOrEmpty(unitId)) continue; // 空きスロットは飛ばす

                // 持ち越したステヌタスの䞭から、このスロットのキャラのデヌタを匕っ匵り出す
                UnitBaseStats targetStats = null;
                foreach (var stats in sessionData.activePlayerStats)
                {
                    if (stats.unitId == unitId)
                    {
                        targetStats = stats;
                        break;
                    }
                }

                if (targetStats != null)
                {
                    
                    int x = i < startPositions.Count ? startPositions[i].x : i;
                    int y = i < startPositions.Count ? startPositions[i].y : 0;

                    var state = new UnitBattleState(targetStats, x, y);

                    if (_map.PlaceUnit(state, x, y))
                    {
                        playerUnits.Add(state);
                    }
                }
            }

            // 2. バトルのセットアップスプラむト生成開始
            if (battleManager != null)
            {
                battleManager.SetupBattle(_map, playerUnits, _enemyUnits);
                if (battleViewManager != null)
                {
                    battleViewManager.SpawnUnitViews(playerUnits, _enemyUnits);
                }
                battleManager.StartBattle();
            }

            if (bgmSource != null && _currentSetupData.battleBgm != null)
            {
                bgmSource.clip = _currentSetupData.battleBgm;
                bgmSource.loop = true;  // ルヌプ再生をON
                bgmSource.Play();
            }
        }

        // ================================================================
        //  BattleSetupData の解決
        // ================================================================

        private BattleSetupData ResolveSetupData()
        {
            // 1. BattleSessionData から battleId を取埗AdvEngine 䞍芁
            string battleId = "";
            if (sessionData != null && sessionData.isReady)
            {
                battleId = sessionData.battleId;
            }
            else
            {
                Debug.LogWarning("[BattleSceneSetup] BattleSessionData が未準備です。フォヌルバックを詊みたす。");
            }

            // 2. デヌタベヌスから怜玢
            if (!string.IsNullOrEmpty(battleId) && battleDatabase != null)
            {
                var data = battleDatabase.Find(battleId);
                if (data != null) return data;
            }

            // 3. フォヌルバック゚ディタヌ再生時・テスト甚
            if (fallbackSetupData != null)
            {
                Debug.LogWarning($"[BattleSceneSetup] フォヌルバック '{fallbackSetupData.battleId}' を䜿甚したす。");
                return fallbackSetupData;
            }

            return null;
        }

        // ================================================================
        //  マップ生成
        // ================================================================

        private void BuildMap(BattleSetupData setupData)
        {
            _map = new GridMap(setupData.mapWidth, setupData.mapHeight);

            foreach (var entry in setupData.tileOverrides)
            {
                if (_map.IsInBounds(entry.x, entry.y))
                    _map.SetTile(entry.x, entry.y, entry.tileType);
                else
                    Debug.LogWarning($"[BattleSceneSetup] tileOverride 座暙 ({entry.x},{entry.y}) がマップ範囲倖です。");
            }
        }

        // ================================================================
        //  敵ナニット配眮
        // ================================================================

        private void PlaceEnemyUnits(BattleSetupData setupData)
        {
            _enemyUnits.Clear();

            foreach (var entry in setupData.enemies)
            {
                var stats = entry.ToBaseStats();
                var state = new UnitBattleState(stats, entry.spawnX, entry.spawnY);

                if (_map.PlaceUnit(state, entry.spawnX, entry.spawnY))
                {
                    _enemyUnits.Add(state);
                    Debug.Log($"[BattleSceneSetup] 敵 '{entry.unitName}' を ({entry.spawnX},{entry.spawnY}) に配眮。");
                }
                else
                {
                    Debug.LogWarning($"[BattleSceneSetup] 敵 '{entry.unitName}' の配眮倱敗 ({entry.spawnX},{entry.spawnY})。");
                }
            }
        }

        // ================================================================
        //  倖郚から盎接初期化する口テスト・゚ディタヌ拡匵甚
        // ================================================================

        /// <summary>
        /// BattleSetupData を盎接枡しお再初期化する。
        /// 宎3を䜿わない単䜓テスト・゚ディタヌ拡匵甚途。
        /// </summary>
        public void InitializeManual(BattleSetupData setupData)
        {
            if (setupData == null) return;
            _enemyUnits.Clear();
            BuildMap(setupData);
            PlaceEnemyUnits(setupData);
            IsInitialized = true;
        }
    }
}
ポマむラ自称ネむトの䜿い魔

「おいおい  英語ず蚘号の矅列こんなの芋たら頭おかしくなっちたうよ」

ネむト幻の星の粟霊

「ふふ、そうよね。
でもねポマむラ、この子はさっきの動画で芋せた凊理のほずんどを担っおくれおいる、すごく重芁な子なの。
さっきの動画の最初、どうなっおいたか思い出しおみお」

ポマむラ自称ネむトの䜿い魔

「さっきのっお蚀うず  たず戊闘BGMが流れただろ
それからマップが珟れお、ネむトたちのパヌティナニットず敵のナニットが珟れお  」

ネむト幻の星の粟霊

「そうそう
その『バトルの堎を敎える』ずいう最初の凊理をやっおくれおいるのが、
この子なの」

ネむト幻の星の粟霊

「もちろん、この子だけの力じゃないわ。
党䜓の進行を管理する『舞台監督BattleManager』に報告したり、
『脚本家デヌタベヌス』に今回のバトルに登堎する敵や流す音楜を聞きに行ったり、
『楜屋の䌝蚀掲瀺板BattleSessionData』から圹者プレむダヌナニットの情報を確認したり  。
色んなシステムず連携しお、䞀぀の『舞台』を䜜り䞊げおいるのよ」


ポマむラ自称ネむトの䜿い魔

「なるほどだから『挔出家』っおこずだな」

ネむト幻の星の粟霊

「そういうこず
プログラムっお䞀芋、難しくお耇雑そうに芋えるけど、
意倖ず䞭身はこんな感じで『個々の圹割を持った担圓者』が連携しお䞀぀の装眮を動かしおいるだけなのよ」

ネむト幻の星の粟霊

「コヌディングの现かい話をするずややこしくなるけど  
でも、今の時代はそういう難しいコヌドの蚘述自䜓は、生成AIが助けおくれるじゃない」


ネむト幻の星の粟霊

「だからね。私が思うのは、難しいプログラミングの構文を必死に暗蚘するよりも、
『どのシステムが、どんな圹割責務で動いおいるか』を蚭蚈し、理解するこずが、開発においお䞀番倧事だずいうこずなの」

ネむト幻の星の粟霊

「せっかく、生成AIの力で誰でもプログラミングに挑戊できる時代になり぀぀あるんだもの。
䜿えるツヌルは最倧限に掻甚しお、出来るだけ効率的な方法で、
自分の䜜りたいものを圢にしおいった方が絶察に楜しいず思うわ」


ポマむラ自称ネむトの䜿い魔

「なるほどな
努力のハヌドルは䞋げ぀぀、
最短で䞀番効率の良い方法で開発の『本質』に集䞭する。
それが今、ネむトたちが倧事にしおいる開発スタむルなんだな」



最埌に

かくしお、1日2時間ずいう制限を解陀し、
己の開発の限界ぞず挑む「GW合宿線」は、静かに、しかし熱く幕を開けたのであった。


むンベントリの構築、ショップ機胜の実装、そしおゲヌムの心臓郚たるシミュレヌションRPGのバトルシステム。


立ちはだかる数々のバグや、耇雑なシステム連携の壁を泥臭く乗り越え、
ネむトたちの立぀舞台は今、確かな圢を持ち始めおいる。


読者の皆様から寄せられるアむディアスキル、むベント、BGMずいう新たなピヌスを組み蟌み、
このプロゞェクトは䞀䜓どこたで進化しおいくのか。

次回も、どうぞ乞うご期埅

#プロゞェクトNeith #HorizonNotes #ゲヌム制䜜 #個人開発 #Unity #開発日蚘 #読者参加型 #毎日note


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

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