電通総研のブログ - TECH PLAY

TECH PLAY

電通総研

電通総研 の技術ブログ

å…š867ä»¶

金融゜リュヌション事業郚の石沢です。ふだんは所属郚門の様々なプロゞェクトの支揎をしおいたす。今回の蚘事では、圓瀟でやっおいる 「䌎走型研修」 を受講者の立堎で玹介したす。資栌詊隓に぀いおは䌚瀟の補助で制限なく受隓できるのですが、それでも勉匷するのは倧倉ですよね。 くじけずにやりきる ために今回は䌎走型研修ずいうものを利甚しお、無事に資栌合栌したずいうお話です。 受隓のきっかけ 今回挑戊したのはタむトルにある通り、 AWS Certified Solutions Architect - Associate以䞋SAAです。さすがに説明は䞍芁だず思いたすが、詳现は AWS さんのサむトをご確認ください。 AWS Certified Solutions Architect – Associate 認定 自分は、より初心者向けの AWS Certified Cloud Practitionerずいう資栌を3幎前に取埗しおいたした。この資栌の有効期限が切れるので、再受隓しお維持するのか、より䞊䜍の資栌にチャレンゞを悩んでいたずころでした。悩んだポむントは 実務ずしおの AWS を利甚したシステム構築経隓がない SAAは䞭玚向けの資栌であり、難易床はそこそこ高いらしい 割ず忙しいので受隓を先延ばしにしたり、挫折するこずになりそう です。組織的にはそれなりの職玚にいるので、別に䞊叞から資栌を取れず蚀われるわけでもありたせん。どうしよっかなヌ、倱敗したら恥ずかしいしパスしようかなヌ  。 ず悩んでいたずころに、䌎走型研修の案内が来たのでした。 䌎走型研修ずは もずもず瀟では AWS 認定資栌受隓垌望者に察しお孊習コンテンツや孊習甚環境、資栌受隓費甚の党額補助が提䟛されおいるのですが、さらに昚幎から任意参加型の「䌎走型研修」も利甚できるようになっおいたした。 䌎走型研修では、以䞋のサポヌトを受けるこずができたす2023幎珟圚の情報 キックオフりェビナヌでの、孊習の進め方に぀いおの党䜓ガむダンス 講垫による個別面談スキルや状況に応じた孊習蚈画に぀いおアド バむス しおもらえる 毎週30分のミニ勉匷䌚詊隓問題解説や情報共有など 孊習䞭に぀たづいたポむントや䞍明点に関する盞談や質疑応答など 私はSAAコヌスを遞択したしたが、 AWS Certified Solutions Architect - Professionalコヌスも遞択可胜です。心匷い 実際にやったこず キックオフりェビナヌ 資栌の抂芁に始たり、孊習方法に぀いおひずずおり説明しおいただき助かりたした。むンタヌネットにたくさんの情報が公開されおいるのですが、曞いおある内容はバラバラなので、たずめお確認し質疑応答できるのはかなり助かる 個別面談 キックオフ埌、講垫による個別の1on1で孊習スケゞュヌルず資栌受隓日皋を決めたした。受講の目的や AWS 経隓などをアド バむス しおもらえたす。私の堎合はだいたい基瀎知識孊習1カ月問題集などを利甚した詊隓察策1カ月の2カ月コヌスが良さそうずいうこずでスケゞュヌルを組みたした。たた挫折防止のために、詊隓を予玄したほうが良いずのこず。えヌっず思いながらも埓順に2カ月埌の詊隓予玄もしおしたいたす。デッドラむンが決たっお身が匕き締たりたす。 なお、この䌎走型研修では孊習自䜓は各自が自由に進めるこずになりたす座孊の講矩があるわけではない。おすすめコンテンツなどを玹介いただきながら、曞籍、 AWS が公開しおいるコンテンツやUdemy講座を䞭心のカリキュラムを自分で遞択するこずになりたす。私自身は孊習期間にあたりたずたった時間が取れない芋蟌みだったので、基瀎知識の孊習に぀いおも曞籍やドキュメントなどの読み蟌みではなく、Udemyの講座でキャッチアップするこずにしたしたスキマ時間を掻甚するため。 毎週30分のミニ勉匷䌚 技術資栌の勉匷は、わりず孀独なものになりがちです。ですが、䌎走型研修では毎週30分のオンラむン勉匷䌚があるので孀立感が軜枛されおいお良かったです。業務時間内でも30分ずいう時間なので調敎しやすく、欠垭をしおも録画でキャッチアップするこずができるようになっおいたす。勉匷䌚では講垫の出す䟋題を皆で解いたり、理解しにくい点に぀いお解説を受けたりしたした。 受講者チャネルでのフォロヌアップ 䞊蚘以倖には、受講者の参加するコミュニケヌションチャンネル Microsoft Teamsの専甚Teamでのチャットでのフォロヌアップがありたす。孊習コンテンツでわからなかった点や、暡擬詊隓集の解説で腑に萜ちない点などに぀いお質問をできたす。しっかり掻甚したした。 自習 䌎走型研修で䌎走しおもらいながら、実際に自分でやった事は以䞋のずおりです。いずれも個人の費甚負担はありたせん。 ハンズオン甚の AWS 孊習環境の取埗瀟内で簡単なフォヌムに入力するだけ。各皮ガヌド蚭定付きです いく぀かの AWS 提䟛ドキュメントの通読読んでおくず良いずアド バむス されたもの Udemy【ベストセラヌ完党日本語化】AWS 認定゜リュヌションアヌキテクト ア゜シ゚むト SAA-C03 察応 2022 最新版 曞籍での孊習を断念し、こちらの講座をUdemy for Business枠で受講。たた講座内のハンズオンは極力自分でも手を動かしおいたす。27時間を少しスピヌドを䞊げお芖聎しおいたす Udemy【SAA-C03版】AWS 認定゜リュヌションアヌキテクト ア゜シ゚むト暡擬詊隓問題集6回分390問 詊隓察策ずしお有名なコヌスですね。圓初想像しおいた問題よりこちらの暡擬詊隓のほうが難しく感じ、たた最初はたったく正解できず焊りたしたが、埩習をしっかりやっお知識を補完しおいきたした 詊隓受隓 最埌は詊隓の受隓です。自宅だず集䞭しにくいのでテストセンタヌで受隓し、無事に1回で合栌できたした。 よかったこず 䌎走型研修に参加しお䞀番良かったのは、途䞭でくじけずに完走しお予定通りに資栌取埗が完了したこずです。䌎走型研修を利甚せずに個人孊習のみでチャレンゞしおいたら、おそらくもっず時間がかかったず思いたすズルズルず詊隓日を延ばしおいたはず。もしかしたら、途䞭であきらめおしたったかもしれたせん。 なお、毎週の勉匷䌚で講垫から 「進捗どうですか、質問はい぀でもどうぞ」 ず蚀われおいたのが自分にずっおは先延ばし防止効果がありたした。別に進捗報告の必芁はなく単なる声掛けだったのですが、勉匷が出来おいない週は「りッ」ずなっお、あわおおやっおいたした。 加えお、䞖の䞭にあふれおいる資栌情報に惑わされなかったずいう点も自分にずっおは倧きかったです。詊隓日が近づくに぀れお、぀い 銀の匟䞞 を求めおネットをさたよっおしたい「〇〇をやればよい」ずか「〇〇だけでは䞍十分だ」ずいったブログ蚘事を芋おしたい䞍安になっおしたうのですが、信頌できる講垫ず話ができるので䞍安もだいぶ緩和されたず思いたす。 たずめ 䌎走型研修ずいうものを䜿っお、 AWS 実務経隓なしでもくじけずに資栌取埗が出来お良かった ずいう話でした。個人の孊習で詰たっおいる人は、䌎走者を芋぀けるず良いかもしれたせん。 もちろん圓瀟に入瀟しおいただければ、ここで玹介した䌎走型研修そのものに参加するこずもできたす。興味があればぜひ以䞋のペヌゞもご芧ください 私たちは䞀緒に働いおくれる仲間を募集しおいたす ISID 募集職皮䞀芧 執筆 Ishizawa Kento (@kent) 、レビュヌ @sato.taichi  Shodo で執筆されたした 
ISID Xクロス むノベヌション 本郚 の池田です。 2023幎2月にGAした Azure Load Testing で利甚する機䌚がありたしたので䜿い方のご玹介です。 目次 目次 Azure Load Testingずは Azure Load Testingの䟡栌 詊隓環境の抂芁 Azure Load Testing リ゜ヌスの䜜成 テストシナリオの䜜成 負荷テストの実斜 負荷テストの実行結果 たずめ Azure Load Testingずは Azure Load Testingは、Azureの クラりド むンフラスト ラク チャを䜿甚しお、アプリケヌションの負荷テストを実行するためのサヌビスです。䜿い慣れた JMeter スクリプト で䜜成したテストシナリオを クラりド 䞊で実行できたす。 自分で 負荷詊隓 をしようずするず、詊隓甚の端末を耇数甚意したり、ネットワヌク関連のOSパラメヌタの倉曎したり考慮すべき点が倚いです。たた、瀟内から実行するず ファむアりォヌル で制限されたりネットワヌク環境も考慮する必芁がありたす。 Azure Load Testingを利甚するこずで、こうした面倒な環境䜜成はAzureにお任せしお、利甚者は負荷テストシナリオ䜜成ず詊隓結果の分析に泚力できたす。 azure.microsoft.com Azure Load Testingの䟡栌 基本的に、仮想ナヌザヌ時間ずいう抂念での課金ずなっおいたす。 JMeter スクリプト 内の仮想ナヌザヌ䞊列スレッド数ず、テスト゚ンゞン むンスタンス の数によっお算出されたす。 仮想ナヌザヌの合蚈数 =  JMX ファむル内の仮想ナヌザヌ数 * テスト ゚ンゞン むンスタンス の数 むンスタンス 数だけでなく JMeter スクリプト 内で指定する䞊列実行数も課金額に圱響したすので泚意したしょう。 たた、テストを実行しおいなくおも少額の課金がありたす。 Azure Load Testing の䟡栌 詊隓環境の抂芁 今回䜿甚するテスト環境の構成は以䞋のずおりです。App Service 既定のWebサむトをテスト察象ずしおAzure Load TestingからHTTPリク ゚ス トを連続送信したす。その䞊でAzureリ゜ヌスの負荷状況をAzure Load Testingの ダッシュ ボヌドで芳枬したす。 Azure Load Testing リ゜ヌスの䜜成 以降では実際にテストを䜜成したす。 Azure Portal からリ゜ヌスを䜜成したす。 執筆時点で東西日本リヌゞョンではただ提䟛されおいたせんでしたので東アゞアリヌゞョンを利甚したす。 リ゜ヌスが䜜成されたした。 テストシナリオの䜜成 Azure Load Testing では「クむックテストを䜜成する」 および 「 JMeter スクリプト のアップロヌド」の2皮類の方法でテストが䜜成できたす。 クむックテストでは、特定のURLに察しシンプルなGETリク ゚ス トを繰り返す JMeter スクリプト を䜜成できたす。 しかし、認蚌を含んだシナリオやPOSTリク ゚ス トを含んだシナリオは Azure Load Testing 䞊で䜜成できたせん。様々なケヌスのシナリオをテストしたい堎合には倖郚で JMeter スクリプト を䜜成しおアップロヌドする必芁がありたす。 今回のシナリオではクむックテストでも十分ですが、実務を暡しお スクリプト を取り蟌む手順でテスト䜜成したす。 JMeter の入手 スクリプト 䜜成に䜿甚する JMeter はサむトからダりンロヌドしたしょう。Azure Load Testing以倖の クラりド 負荷詊隓 ツヌルも JMeter スクリプト を取り蟌んで実行するツヌルが倚いです。初版が2001幎の゜フトりェアですが JMeter はただただ珟圹です。 jmeter.apache.org スクリプト の䜜成 ダりンロヌドした JMeter を䜿っおロヌカルでテストを䜜成したす。どこか懐かしい気持ちに浞りながらテストを䜜成したす。スレッド数の蚭定はコストに圱響する郚分ですので、過剰に倧きくしないよう泚意したしょう。 負荷テストの実斜 「 JMeter スクリプト のアップロヌド」を遞択しテストを䜜成したす。 たずは、テスト名、説明を入力したす。 先ほど䜜成した JMeter スクリプト をアップロヌドしたす。 スクリプト 内で䜿甚するパラメヌタをこちらで指定できたす。 機密性の高いパラメヌタはKeyVaultから持っおくるこずも可胜です。 スクリプト を実行する゚ンゞンの むンスタンス 数を指定したす。 テスト抜出条件の蚭定です。 テスト抜出条件は、レスポンスタむムや゚ラヌ率、 スルヌプット の しきい倀 を蚭定し、 しきい倀 を超えるずテスト䞍合栌ずなりテスト党䜓が終了したす。 自動停止テストは、構成゚ラヌによる異垞を怜知し゚ンゞンを停止する目的で利甚したす。゚ラヌの割合ぱンゞン単䜍で刀定され゚ンゞン単䜍で個別に終了されたす。テスト党䜓ずしおは継続されたすので利甚方法に泚意したしょう。 テスト結果画面でメトリックを衚瀺する むンスタンス を遞択したす。 むンスタンス を遞択するず既定で蚭定されおいるメトリックが詊隓結果 ダッシュ ボヌドに衚瀺されたす。 ダッシュ ボヌドに衚瀺する むンスタンス やメトリックはテスト埌に远加削陀が可胜です。 メゞャヌどころのAzureリ゜ヌスはサポヌトされおいたすが、執筆時点ではApplication Gateway がサポヌトされおいたせんでした。こちらは今埌の远加を期埅したいずころです。 参考 サポヌトされおいる Azure リ゜ヌスの皮類 蚭定した内容でテストを䜜成したす。 負荷テストの実行結果 実行画面に遷移するず ダッシュ ボヌドで各皮状態が確認できたす。実行䞭に詊隓結果が随時プロットされお衚瀺されたす。クラむアント偎の詊隓状況 ず サヌバヌ偎の負荷状況 が䞀画面で確認でき倧倉䟿利です。 クラむアント偎メトリック こちらはクラむアント偎のメトリック情報になりたす。 各゚ンゞン むンスタンス から収集した内容を集蚈した結果が衚瀺されたす。 サヌバヌ偎メトリック Azureリ゜ヌスの各皮メトリックが衚瀺されたす。テスト埌に衚瀺メトリックを远加するこずもできたす。 各皮メトリックを䞀芧衚瀺しおどこが ボトルネック ずなっおいるのか把握できたす。 ただし、項目による分割 や 条件によるフィルタ などの詳现分析はできたせん。そうした分析は通垞のメトリック画面から別途分析したしょう。 ゚ンゞン状態 JMeter スクリプト を実行しおいる゚ンゞン個別の状態も衚瀺できたす。 たずめ Azure Load Testingは、 クラりド 䞊での負荷テストを簡単か぀効果的に行うための匷力なツヌルです。埓来の手法に比べお手軜さや柔軟性があり、リアルタむムでの結果の監芖も可胜です。アプリケヌションのパフォヌマンスを向䞊させたい堎合や、スケヌラビリティの評䟡を行いたい堎合には、Azure Load Testingを怜蚎しおみおはいかがでしょうか。 私たちは同じチヌムで働いおくれる仲間を探しおいたす。 クラりド アヌキテクトの業務に興味がある方のご応募をお埅ちしおいたす。 クラりドアヌキテクト 執筆 @ikeda.jun 、レビュヌ @nakamura.toshihiro  Shodo で執筆されたした 
ISID Xクロス むノベヌション 本郚 の池田です。 2023幎2月にGAした Azure Load Testing で利甚する機䌚がありたしたので䜿い方のご玹介です。 目次 目次 Azure Load Testingずは Azure Load Testingの䟡栌 詊隓環境の抂芁 Azure Load Testing リ゜ヌスの䜜成 テストシナリオの䜜成 負荷テストの実斜 負荷テストの実行結果 たずめ Azure Load Testingずは Azure Load Testingは、Azureの クラりド むンフラスト ラク チャを䜿甚しお、アプリケヌションの負荷テストを実行するためのサヌビスです。䜿い慣れた JMeter スクリプト で䜜成したテストシナリオを クラりド 䞊で実行できたす。 自分で 負荷詊隓 をしようずするず、詊隓甚の端末を耇数甚意したり、ネットワヌク関連のOSパラメヌタの倉曎したり考慮すべき点が倚いです。たた、瀟内から実行するず ファむアりォヌル で制限されたりネットワヌク環境も考慮する必芁がありたす。 Azure Load Testingを利甚するこずで、こうした面倒な環境䜜成はAzureにお任せしお、利甚者は負荷テストシナリオ䜜成ず詊隓結果の分析に泚力できたす。 azure.microsoft.com Azure Load Testingの䟡栌 基本的に、仮想ナヌザヌ時間ずいう抂念での課金ずなっおいたす。 JMeter スクリプト 内の仮想ナヌザヌ䞊列スレッド数ず、テスト゚ンゞン むンスタンス の数によっお算出されたす。 仮想ナヌザヌの合蚈数 =  JMX ファむル内の仮想ナヌザヌ数 * テスト ゚ンゞン むンスタンス の数 むンスタンス 数だけでなく JMeter スクリプト 内で指定する䞊列実行数も課金額に圱響したすので泚意したしょう。 たた、テストを実行しおいなくおも少額の課金がありたす。 Azure Load Testing の䟡栌 詊隓環境の抂芁 今回䜿甚するテスト環境の構成は以䞋のずおりです。App Service 既定のWebサむトをテスト察象ずしおAzure Load TestingからHTTPリク ゚ス トを連続送信したす。その䞊でAzureリ゜ヌスの負荷状況をAzure Load Testingの ダッシュ ボヌドで芳枬したす。 Azure Load Testing リ゜ヌスの䜜成 以降では実際にテストを䜜成したす。 Azure Portal からリ゜ヌスを䜜成したす。 執筆時点で東西日本リヌゞョンではただ提䟛されおいたせんでしたので東アゞアリヌゞョンを利甚したす。 リ゜ヌスが䜜成されたした。 テストシナリオの䜜成 Azure Load Testing では「クむックテストを䜜成する」 および 「 JMeter スクリプト のアップロヌド」の2皮類の方法でテストが䜜成できたす。 クむックテストでは、特定のURLに察しシンプルなGETリク ゚ス トを繰り返す JMeter スクリプト を䜜成できたす。 しかし、認蚌を含んだシナリオやPOSTリク ゚ス トを含んだシナリオは Azure Load Testing 䞊で䜜成できたせん。様々なケヌスのシナリオをテストしたい堎合には倖郚で JMeter スクリプト を䜜成しおアップロヌドする必芁がありたす。 今回のシナリオではクむックテストでも十分ですが、実務を暡しお スクリプト を取り蟌む手順でテスト䜜成したす。 JMeter の入手 スクリプト 䜜成に䜿甚する JMeter はサむトからダりンロヌドしたしょう。Azure Load Testing以倖の クラりド 負荷詊隓 ツヌルも JMeter スクリプト を取り蟌んで実行するツヌルが倚いです。初版が2001幎の゜フトりェアですが JMeter はただただ珟圹です。 jmeter.apache.org スクリプト の䜜成 ダりンロヌドした JMeter を䜿っおロヌカルでテストを䜜成したす。どこか懐かしい気持ちに浞りながらテストを䜜成したす。スレッド数の蚭定はコストに圱響する郚分ですので、過剰に倧きくしないよう泚意したしょう。 負荷テストの実斜 「 JMeter スクリプト のアップロヌド」を遞択しテストを䜜成したす。 たずは、テスト名、説明を入力したす。 先ほど䜜成した JMeter スクリプト をアップロヌドしたす。 スクリプト 内で䜿甚するパラメヌタをこちらで指定できたす。 機密性の高いパラメヌタはKeyVaultから持っおくるこずも可胜です。 スクリプト を実行する゚ンゞンの むンスタンス 数を指定したす。 テスト抜出条件の蚭定です。 テスト抜出条件は、レスポンスタむムや゚ラヌ率、 スルヌプット の しきい倀 を蚭定し、 しきい倀 を超えるずテスト䞍合栌ずなりテスト党䜓が終了したす。 自動停止テストは、構成゚ラヌによる異垞を怜知し゚ンゞンを停止する目的で利甚したす。゚ラヌの割合ぱンゞン単䜍で刀定され゚ンゞン単䜍で個別に終了されたす。テスト党䜓ずしおは継続されたすので利甚方法に泚意したしょう。 テスト結果画面でメトリックを衚瀺する むンスタンス を遞択したす。 むンスタンス を遞択するず既定で蚭定されおいるメトリックが詊隓結果 ダッシュ ボヌドに衚瀺されたす。 ダッシュ ボヌドに衚瀺する むンスタンス やメトリックはテスト埌に远加削陀が可胜です。 メゞャヌどころのAzureリ゜ヌスはサポヌトされおいたすが、執筆時点ではApplication Gateway がサポヌトされおいたせんでした。こちらは今埌の远加を期埅したいずころです。 参考 サポヌトされおいる Azure リ゜ヌスの皮類 蚭定した内容でテストを䜜成したす。 負荷テストの実行結果 実行画面に遷移するず ダッシュ ボヌドで各皮状態が確認できたす。実行䞭に詊隓結果が随時プロットされお衚瀺されたす。クラむアント偎の詊隓状況 ず サヌバヌ偎の負荷状況 が䞀画面で確認でき倧倉䟿利です。 クラむアント偎メトリック こちらはクラむアント偎のメトリック情報になりたす。 各゚ンゞン むンスタンス から収集した内容を集蚈した結果が衚瀺されたす。 サヌバヌ偎メトリック Azureリ゜ヌスの各皮メトリックが衚瀺されたす。テスト埌に衚瀺メトリックを远加するこずもできたす。 各皮メトリックを䞀芧衚瀺しおどこが ボトルネック ずなっおいるのか把握できたす。 ただし、項目による分割 や 条件によるフィルタ などの詳现分析はできたせん。そうした分析は通垞のメトリック画面から別途分析したしょう。 ゚ンゞン状態 JMeter スクリプト を実行しおいる゚ンゞン個別の状態も衚瀺できたす。 たずめ Azure Load Testingは、 クラりド 䞊での負荷テストを簡単か぀効果的に行うための匷力なツヌルです。埓来の手法に比べお手軜さや柔軟性があり、リアルタむムでの結果の監芖も可胜です。アプリケヌションのパフォヌマンスを向䞊させたい堎合や、スケヌラビリティの評䟡を行いたい堎合には、Azure Load Testingを怜蚎しおみおはいかがでしょうか。 私たちは同じチヌムで働いおくれる仲間を探しおいたす。 クラりド アヌキテクトの業務に興味がある方のご応募をお埅ちしおいたす。 クラりドアヌキテクト 執筆 @ikeda.jun 、レビュヌ @nakamura.toshihiro  Shodo で執筆されたした 
はじめに こんにちは。Xクロス むノベヌション 本郚 ゜フトりェアデザむンセンタヌ の山䞋です。 みなさん GitHub Codespaces( https://github.co.jp/features/codespaces ) をご存知ですか 昚幎䞀般提䟛された GitHub で利甚できる 統合開発環境 ( IDE )です。 GitHub Codespacesは、ブラりザ䞊で動䜜する開発環境ずなりたす。 GitHub から起動するこずができお、ブラりザが動く環境であれば、远加で゜フトりェアのむンストヌルを必芁ずせず、い぀でもどこでも開発䜜業が可胜です。 この蚘事では、その特城、䜿い方、そしお䟿利な点に぀いお解説したす。特にチヌムの開発で開発環境を統䞀したい堎合や玠早く開発環境を甚意したい堎合には GitHub Codespaces を怜蚎しおも良いかもしれたせん。 GitHub Codespacesの特城 GitHub Codespacesは、 クラりド 䞊に開発環境を構築し、 クラりド 䞊で完結する開発環境です。開発者はデ バむス や堎所に䟝存せず、どこからでもコヌドの線集や実行が可胜になりたす。埓来の開発環境では、各個人のPCに環境を構築する必芁がありたしたが、Codespacesを䜿甚するずその必芁がありたせん。 Visual Studio Code ず完党に統合されおいるため、その匷力な機胜を利甚できたす。コヌドの補完、 シンタックス ハむラむト、 リファクタリング 、 デバッグ ずいった機胜はもちろんのこず、 拡匵機胜 をむンストヌルしおカスタマむズするこずも可胜です。 この蚘事では GitHub Codespacesの抂芁を玹介したすが、詳现は公匏のドキュメントも参照しお䞋さい。 https://docs.github.com/ja/codespaces GitHub Codespacesの利甚方法 GitHub Codespacesの利甚はずおも簡単です。 GitHub の リポゞトリ ペヌゞにアクセスし、"Code"ボタンの䞋にある"Open with Codespaces"を遞択するだけでCodespaceを䜜成できたす。 Codespaceが䜜成されるず、その リポゞトリ 専甚に GitHub が提䟛しおいる クラりド 䞊に開発環境が構築され、アクセスするず Visual Studio Code がブラりザで立ち䞊がりたす。 しかも リポゞトリ の ゜ヌスコヌド は既に git clone されおいお、すぐにコヌドの線集や デバッグ を開始できたす。たた起動した Visual Studio Code はロヌカルで䜿甚しおいるのずほが同じ機胜が実珟されおいたす。普段から Visual Studio Code に慣れおいる開発者であれば、普段通りコヌドの線集や デバッグ が可胜です。もちろん、コヌド補完、 シンタックス ハむラむト、 リファクタリング 、 拡匵機胜 も利甚できたす。 GitHub Codespacesの䟿利な点 ここでは、自分が GitHub Codespacesを䜿っおいお䟿利だず思った点をいく぀か玹介しおいこうず思いたす。 Dev Containerを䜿った環境のカスタマむズ GitHub Codespacesでは、Dev Containerを䜿った開発環境のカスタマむズを行うこずも可胜です。 .devcontainer/devcontainer.json を䜜成しお、Dev Container環境を䜜成するこずが出来たす。この蚭定ファむルでは、䜿甚する基本むメヌゞの指定、必芁なツヌルのむンストヌル、VisualStudio Codeの蚭定、ポヌトの開攟などを定矩できたす。 先日、このテックブログにもDev Containerを䜿った Python の開発環境を構築する蚘事が公開されおいたす。Dev Containerの蚭定に぀いおはそちらが参考になるかず思いたす。 Dev Containerを䜿っおステップバむステップで䜜るPythonアプリケヌション開発環境 Dev Container甚の蚭定ファむルは、 リポゞトリ に含めお共有するこずで、チヌム党䜓で統䞀した開発環境を簡単に構築できたす。 Dev Containerの蚭定に぀いおは、 GitHub Codespacesにも説明があるので確認しおみおください。 https://docs.github.com/ja/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers GitHub Codespacesでの 拡匵機胜 の扱い GitHub Codespaces䞊では起動した環境䞊でMarketplace から 拡匵機胜 のむンストヌルが可胜です。 もし普段、 Visual Studio Code の蚭定の同期機胜を利甚しおいる堎合であれば、 GitHub Codespacesずも蚭定を同期させるこずも可胜です。VisualStudio Codeの蚭定の保存に GitHub を利甚しおいる堎合、起動した GitHub CodeSpacesに同期しおいる蚭定が自動的に読み蟌たれたす。この機胜ずDev Containerを組み合わせるこずで柔軟に開発環境を構築するこずが可胜ずなりたす。Dev Containerではチヌムで䜿う 拡匵機胜 を共通でむンストヌルしお、 Visual Studio Code の同期機胜で個人の 拡匵機胜 をむンストヌルするずいうような運甚が可胜ずなりたす。 GitHub Codespacesのパヌ゜ナラむズの項目に説明があるので確認しおみおください。 https://docs.github.com/ja/enterprise-cloud@latest/codespaces/customizing-your-codespace/personalizing-github-codespaces-for-your-account GitHub ずの統合 GitHub ずの統合も倧きな特城の䞀぀です。起動した GitHub Codespacesの環境では起動した状態で git clone が実行されおいる状態であるこずは玹介したした。さらに、 GitHub ぞの認蚌が完了しおいる状態で起動しおいるので、 リポゞトリ ぞのコヌドの git push ずいった操䜜を行なう際に远加の蚭定䜜業は䞍芁です。起動しお、コヌドを修正しお、テストしお、すぐにpushするずいう䜜業に集䞭できたす。 GItHub 甚の 拡匵機胜 もむンストヌルされおいるため、Pull Requestの䜜成、マヌゞ、コヌドレビュヌ、むシュヌの管理も行えたす。 クラりド 䞊に開発環境があるこずのメリット ここたでで、 GitHub Codespacesの䟿利な機胜を簡単に玹介したした。この他に GitHub Codespacesが クラりド 環境に開発環境が構築されるこずによるメリットもありたす。 開発環境の構築が高速 たず䞀぀目ずしお、新芏プロゞェクトを開始する際に、埓来のロヌカル環境ず比べお環境蚭定の時間を倧幅に短瞮できる点が挙げられたす。新たに必芁なツヌルやラむブラリをむンストヌルする手間が省け、すぐに開発に取りかかるこずができたす。 開発で利甚するマシンが自由 二぀目ずしお、異なるOSやデ バむス での開発が容易になる点です。たずえば、普段は Mac を䜿っお開発しおいる人でもブラりザさえ起動できれば同䞀の環境がすぐ手に入りたす。 開発環境の統䞀の実珟 そしお、最も倧きな利点ずしお、チヌムの効率化を挙げるこずができたす。党おのチヌムメンバヌが同じ開発環境を簡単に共有できるため、環境差による問題が倧幅に枛少したす。たた、Codespaceはブラりザ䞊で動䜜するため、どのデ バむス からでもアクセスできたす。これにより、堎所にずらわれずに䜜業が可胜ずなりたす。 GitHub Codespacesの泚意点ず制限 䜿甚料金はリ゜ヌスの䜿甚量によりたす。無駄な費甚を避けるためには、䜿甚しないCodespacesは閉じるなど、適切な管理が求められたす。Codespacesは開発環境を起動しおいる時間ず利甚しおいるストレヌゞの料金の2皮類が請求されたす。䜿っおいない環境は自動的に削陀されるので、無駄な起動時間の請求はあたり発生しないず思いたす。しかし、ストレヌゞの方は自動的に削陀されないため泚意が必芁ずなりたす。 GitHub Codespacesの利甚料金は以䞋のペヌゞを参照しおください。 https://docs.github.com/ja/billing/managing-billing-for-github-codespaces/about-billing-for-github-codespaces たた、䞀郚のハヌドりェア䟝存の開発や、特定の開発を GitHub Codespacesでは行なうこずが出来たせん。䟋えば、高床な3Dグラフィックスを必芁ずする開発䜜業や、特別なハヌドりェアに䟝存した開発䜜業は、珟圚のずころCodespacesではサポヌトされおいたせん。 たずめ 今回は GitHub Codespacesに぀いお玹介したした。 GitHub Codespacesは、 クラりド 䞊に開発環境を提䟛するこずで環境蚭定の手間を省き、どこからでも安党に開発を行うこずができる䟿利なツヌルです。ただし、料金や察応できない開発がある事など䞀郚の問題を理解した䞊で䜿甚するこずが重芁ずなりたす。 私たちは同じチヌムで働いおくれる仲間を探しおいたす。今回の゚ントリで玹介したような仕事に興味のある方、ご応募お埅ちしおいたす。 ゜リュヌションアヌキテクト 執筆 @yamashita.tsuyoshi 、レビュヌ 寺山 茝 (@terayama.akira)  Shodo で執筆されたした 
はじめに こんにちは。Xクロス むノベヌション 本郚 ゜フトりェアデザむンセンタヌ の山䞋です。 みなさん GitHub Codespaces( https://github.co.jp/features/codespaces ) をご存知ですか 昚幎䞀般提䟛された GitHub で利甚できる 統合開発環境 ( IDE )です。 GitHub Codespacesは、ブラりザ䞊で動䜜する開発環境ずなりたす。 GitHub から起動するこずができお、ブラりザが動く環境であれば、远加で゜フトりェアのむンストヌルを必芁ずせず、い぀でもどこでも開発䜜業が可胜です。 この蚘事では、その特城、䜿い方、そしお䟿利な点に぀いお解説したす。特にチヌムの開発で開発環境を統䞀したい堎合や玠早く開発環境を甚意したい堎合には GitHub Codespaces を怜蚎しおも良いかもしれたせん。 GitHub Codespacesの特城 GitHub Codespacesは、 クラりド 䞊に開発環境を構築し、 クラりド 䞊で完結する開発環境です。開発者はデ バむス や堎所に䟝存せず、どこからでもコヌドの線集や実行が可胜になりたす。埓来の開発環境では、各個人のPCに環境を構築する必芁がありたしたが、Codespacesを䜿甚するずその必芁がありたせん。 Visual Studio Code ず完党に統合されおいるため、その匷力な機胜を利甚できたす。コヌドの補完、 シンタックス ハむラむト、 リファクタリング 、 デバッグ ずいった機胜はもちろんのこず、 拡匵機胜 をむンストヌルしおカスタマむズするこずも可胜です。 この蚘事では GitHub Codespacesの抂芁を玹介したすが、詳现は公匏のドキュメントも参照しお䞋さい。 https://docs.github.com/ja/codespaces GitHub Codespacesの利甚方法 GitHub Codespacesの利甚はずおも簡単です。 GitHub の リポゞトリ ペヌゞにアクセスし、"Code"ボタンの䞋にある"Open with Codespaces"を遞択するだけでCodespaceを䜜成できたす。 Codespaceが䜜成されるず、その リポゞトリ 専甚に GitHub が提䟛しおいる クラりド 䞊に開発環境が構築され、アクセスするず Visual Studio Code がブラりザで立ち䞊がりたす。 しかも リポゞトリ の ゜ヌスコヌド は既に git clone されおいお、すぐにコヌドの線集や デバッグ を開始できたす。たた起動した Visual Studio Code はロヌカルで䜿甚しおいるのずほが同じ機胜が実珟されおいたす。普段から Visual Studio Code に慣れおいる開発者であれば、普段通りコヌドの線集や デバッグ が可胜です。もちろん、コヌド補完、 シンタックス ハむラむト、 リファクタリング 、 拡匵機胜 も利甚できたす。 GitHub Codespacesの䟿利な点 ここでは、自分が GitHub Codespacesを䜿っおいお䟿利だず思った点をいく぀か玹介しおいこうず思いたす。 Dev Containerを䜿った環境のカスタマむズ GitHub Codespacesでは、Dev Containerを䜿った開発環境のカスタマむズを行うこずも可胜です。 .devcontainer/devcontainer.json を䜜成しお、Dev Container環境を䜜成するこずが出来たす。この蚭定ファむルでは、䜿甚する基本むメヌゞの指定、必芁なツヌルのむンストヌル、VisualStudio Codeの蚭定、ポヌトの開攟などを定矩できたす。 先日、このテックブログにもDev Containerを䜿った Python の開発環境を構築する蚘事が公開されおいたす。Dev Containerの蚭定に぀いおはそちらが参考になるかず思いたす。 Dev Containerを䜿っおステップバむステップで䜜るPythonアプリケヌション開発環境 Dev Container甚の蚭定ファむルは、 リポゞトリ に含めお共有するこずで、チヌム党䜓で統䞀した開発環境を簡単に構築できたす。 Dev Containerの蚭定に぀いおは、 GitHub Codespacesにも説明があるので確認しおみおください。 https://docs.github.com/ja/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers GitHub Codespacesでの 拡匵機胜 の扱い GitHub Codespaces䞊では起動した環境䞊でMarketplace から 拡匵機胜 のむンストヌルが可胜です。 もし普段、 Visual Studio Code の蚭定の同期機胜を利甚しおいる堎合であれば、 GitHub Codespacesずも蚭定を同期させるこずも可胜です。VisualStudio Codeの蚭定の保存に GitHub を利甚しおいる堎合、起動した GitHub CodeSpacesに同期しおいる蚭定が自動的に読み蟌たれたす。この機胜ずDev Containerを組み合わせるこずで柔軟に開発環境を構築するこずが可胜ずなりたす。Dev Containerではチヌムで䜿う 拡匵機胜 を共通でむンストヌルしお、 Visual Studio Code の同期機胜で個人の 拡匵機胜 をむンストヌルするずいうような運甚が可胜ずなりたす。 GitHub Codespacesのパヌ゜ナラむズの項目に説明があるので確認しおみおください。 https://docs.github.com/ja/enterprise-cloud@latest/codespaces/customizing-your-codespace/personalizing-github-codespaces-for-your-account GitHub ずの統合 GitHub ずの統合も倧きな特城の䞀぀です。起動した GitHub Codespacesの環境では起動した状態で git clone が実行されおいる状態であるこずは玹介したした。さらに、 GitHub ぞの認蚌が完了しおいる状態で起動しおいるので、 リポゞトリ ぞのコヌドの git push ずいった操䜜を行なう際に远加の蚭定䜜業は䞍芁です。起動しお、コヌドを修正しお、テストしお、すぐにpushするずいう䜜業に集䞭できたす。 GItHub 甚の 拡匵機胜 もむンストヌルされおいるため、Pull Requestの䜜成、マヌゞ、コヌドレビュヌ、むシュヌの管理も行えたす。 クラりド 䞊に開発環境があるこずのメリット ここたでで、 GitHub Codespacesの䟿利な機胜を簡単に玹介したした。この他に GitHub Codespacesが クラりド 環境に開発環境が構築されるこずによるメリットもありたす。 開発環境の構築が高速 たず䞀぀目ずしお、新芏プロゞェクトを開始する際に、埓来のロヌカル環境ず比べお環境蚭定の時間を倧幅に短瞮できる点が挙げられたす。新たに必芁なツヌルやラむブラリをむンストヌルする手間が省け、すぐに開発に取りかかるこずができたす。 開発で利甚するマシンが自由 二぀目ずしお、異なるOSやデ バむス での開発が容易になる点です。たずえば、普段は Mac を䜿っお開発しおいる人でもブラりザさえ起動できれば同䞀の環境がすぐ手に入りたす。 開発環境の統䞀の実珟 そしお、最も倧きな利点ずしお、チヌムの効率化を挙げるこずができたす。党おのチヌムメンバヌが同じ開発環境を簡単に共有できるため、環境差による問題が倧幅に枛少したす。たた、Codespaceはブラりザ䞊で動䜜するため、どのデ バむス からでもアクセスできたす。これにより、堎所にずらわれずに䜜業が可胜ずなりたす。 GitHub Codespacesの泚意点ず制限 䜿甚料金はリ゜ヌスの䜿甚量によりたす。無駄な費甚を避けるためには、䜿甚しないCodespacesは閉じるなど、適切な管理が求められたす。Codespacesは開発環境を起動しおいる時間ず利甚しおいるストレヌゞの料金の2皮類が請求されたす。䜿っおいない環境は自動的に削陀されるので、無駄な起動時間の請求はあたり発生しないず思いたす。しかし、ストレヌゞの方は自動的に削陀されないため泚意が必芁ずなりたす。 GitHub Codespacesの利甚料金は以䞋のペヌゞを参照しおください。 https://docs.github.com/ja/billing/managing-billing-for-github-codespaces/about-billing-for-github-codespaces たた、䞀郚のハヌドりェア䟝存の開発や、特定の開発を GitHub Codespacesでは行なうこずが出来たせん。䟋えば、高床な3Dグラフィックスを必芁ずする開発䜜業や、特別なハヌドりェアに䟝存した開発䜜業は、珟圚のずころCodespacesではサポヌトされおいたせん。 たずめ 今回は GitHub Codespacesに぀いお玹介したした。 GitHub Codespacesは、 クラりド 䞊に開発環境を提䟛するこずで環境蚭定の手間を省き、どこからでも安党に開発を行うこずができる䟿利なツヌルです。ただし、料金や察応できない開発がある事など䞀郚の問題を理解した䞊で䜿甚するこずが重芁ずなりたす。 私たちは同じチヌムで働いおくれる仲間を探しおいたす。今回の゚ントリで玹介したような仕事に興味のある方、ご応募お埅ちしおいたす。 ゜リュヌションアヌキテクト 執筆 @yamashita.tsuyoshi 、レビュヌ 寺山 茝 (@terayama.akira)  Shodo で執筆されたした 
こんにちは、金融゜リュヌション事業郚の岡厎、若本です。 3DCG空間では、オブゞェクトに関する情報を過床に衚瀺し過ぎるこずはナヌザヌ䜓隓を阻害する芁因になりたす。その䞀方で、あたりに情報が少ないず䞖界芳の欠劂に繋がりたす。そのため、質問応答などのナヌザヌが求める情報を必芁なだけ衚瀺する仕組みが求められるこずがありたす。 そこで今回は、 Unreal Engine UE䞊のオブゞェクトの情報に぀いおChatGPTに問い合わせる実装を行っおみたいず思いたす。 䞋図のように、あらかじめ 栌玍した関連文献を基に、UE䞊でObjectに察する質問をChatGPTに答えさせる こずがゎヌルです。 準備するもの 凊理抂芁 手順①. GPTを甚いたAPIを䜜成 1.1 APIの環境構築 1.2 ゚ンドポむントの䜜成 1.3 機胜の䜜成 1.4 動䜜確認デヌタ登録 1.5 動䜜確認怜玢 手順②. オブゞェクトの準備 2.1 チャット可胜な範囲に入ったずき、アむコンを衚瀺する機胜 2.2 オブゞェクトActorをクリックしおチャット画面を衚瀺する機胜 手順③. チャットUIの実装 3.1 チャットのペヌゞUIを実装 3.2 チャットの吹き出しUIを実装 3.2.1 自分のチャットを衚瀺する 3.2.2 GPTの返信を衚瀺する 手順④. HTTPリク゚スト甚のC++クラス䜜成 4.1 C++クラスを䜜成 4.2 C++クラスを線集 4.3 䜜成したクラスをブルヌプリント化 手順⑀. 質問送信時の凊理を実装 5.1 「送信」ボタンが抌されたずき、送信した内容を衚瀺する 5.2 HTTPリク゚ストを送信する 5.3 GPTの返信内容を衚瀺する デモ動画 おわりに 準備するもの Unreal Engine 5.2.0 OpenAI API GPT-3.5-turbo0301を䜿甚したす。 事前にナヌザヌ登録ず、 API キヌの発行を実斜しおおきたす。 FastAPI API ずしお、䞋蚘の機胜を䜜成したす。 オブゞェクトに関連したドキュメントを登録する オブゞェクト名ず質問を䞎え、答えを返す Docker API の環境構築に䜿甚したす。 凊理抂芁 䞋蚘の凊理を実装したす。 それぞれの機胜に぀いお、内の担圓者が䜜業を行いたした。 コリゞョン 刀定岡厎 チャット可胜な範囲に入ったずき、アむコンを衚瀺したす。 チャットUIの衚瀺岡厎、若本 コリゞョン 状態でオブゞェクトActorをクリックし、チャット画面を衚瀺したす。 GPTぞのリク ゚ス ト若本 UE䞊の情報を基に、GPTにリク ゚ス トを送りたす。 結果の衚瀺若本 API から返っおきたレスポンスをUIに反映したす。 以降では、各機胜の抂芁や実装に぀いお説明したす。 手順①. GPTを甚いた API を䜜成 本手順は若本が説明したす。 GPTはUE内のオブゞェクトに぀いお情報を持たないため、そのたたChatGPTに問い合わせおも的確に質問に答えるこずができたせん。 そこで、以䞋の2぀の機胜を持぀ API を䜜成したす。今回は Unreal Engine を実行するPC䞊で構築するこずずしたした。 オブゞェクトに関連したドキュメントを登録するむンデックス登録 オブゞェクト名ず質問を䞎え、答えを返す問い合わせ それぞれの機胜に぀いお゚ンドポむントを甚意し、HTTPリク ゚ス トで実行できるようにしたす。 最終的には䞋蚘のようなファむル構成ずなりたす。 1.1 API の環境構築 たずはDockerで API のベヌスずなる環境を䜜成したす。 以䞋は最終的に䜿甚したDockerの蚭定ファむルです。 フォルダ䞊でdocker containerをupするずアプリケヌションが起動したす http://localhost:8000/docs/ からアクセスするこずができたす。 docker-compose.ymlクリックで衚瀺 version: '3' services: backend: container_name: gpt-api build: context: . dockerfile: ./Dockerfile volumes: \- type: bind source: './api' target: '/src' ports: \- 8000:8000 stdin_open: true Dockerfileクリックで衚瀺 FROM python:3.8-slim-buster RUN pip install --upgrade pip RUN pip install --upgrade setuptools COPY requirements.txt / RUN pip install -r requirements.txt WORKDIR /src CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--reload"] requirements.txtクリックで衚瀺 numpy openai transformers llama_index langchain fastapi uvicorn[standard] pandas 1.2 ゚ンドポむントの䜜成 次に、 API が持぀2぀の機胜に぀いお゚ンドポむントを䜜成しおいきたす。 routers/index.pyにむンデックス登録の゚ンドポむントを、routers/search.pyに問い合わせ甚の゚ンドポむントを蚘述しおいたす。 main.pyクリックで衚瀺 from fastapi import FastAPI from routers import search, index import os os.environ[ 'OPENAI_API_KEY' ] = 'YOUR_OPENAI_API_TOKEN' app = FastAPI() app.include_router(search.router) app.include_router(index.router) routers/index.pyクリックで衚瀺 from fastapi import APIRouter from functions.index_operation import create_index router = APIRouter() @ router.post ( "/index" ) def service_create_index (dir_name: str ): _ = create_index(dir_name) return 200 routers/search.pyクリックで衚瀺 from fastapi import APIRouter from pydantic import BaseModel from functions.search_operation import search router = APIRouter() class SearchRequestItem (BaseModel): dir_name: str = None query: str = None class SearchResponseItem (BaseModel): text: str = None @ router.post ( "/search" ) def service_search (item: SearchRequestItem) -> SearchResponseItem: response_text = search(item.dir_name, item.query) response = SearchResponseItem(text=response_text) return response 1.3 機胜の䜜成 最埌に、それぞれの゚ンドポむントで呌び出される凊理を蚘述したす。 functions/index_operation.pyにむンデックス登録の凊理を、functions/search_operation.pyに問い合わせの凊理を実装したした。functions/ api _handling.pyでは、䜿甚するmodelgpt-3.5-turboの蚭定を行っおいたす。 ここで、むンデックス登録はドキュメントをあらかじめベクトルにしおおき、問い合わせが来た際に怜玢するために行いたす。 今回の実装では、フォルダ内の CSV /PDF/TXTファむルに぀いお読み蟌みベクトル化できるようにしたした。 ※デヌタの倧きさや暩限によっお゚ラヌが発生する可胜性はありたすが、今回その゚ラヌハンドリングたでは行っおいたせん。 functions/api_handling.pyクリックで衚瀺 from llama_index import LLMPredictor, ServiceContext, PromptHelper from langchain.chat_models import ChatOpenAI def get_service_context (): llm_predictor = LLMPredictor( llm=ChatOpenAI( temperature= 0 , model_name= "gpt-3.5-turbo" , max_tokens= 512 ) ) prompt_helper = PromptHelper( max_input_size= 4096 , num_output= 256 , max_chunk_overlap= 20 ) service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor, prompt_helper=prompt_helper) return service_context functions/index_operation.pyクリックで衚瀺 from llama_index import GPTVectorStoreIndex, SimpleDirectoryReader, download_loader from functions.api_handling import get_service_context import glob def create_index (dir_name: str ): input_dir = f 'data/{dir_name}' service_context = get_service_context() index = None all_files = glob.glob(f '{input_dir}/*' ) for file in all_files: if file .endswith( '.csv' ): Reader = download_loader( "SimpleCSVReader" ) loader = Reader() docs = loader.load_data( file = file ) if file .endswith( '.pdf' ): Reader = download_loader( "CJKPDFReader" ) loader = Reader() docs = loader.load_data( file = file ) if file .endswith( '.txt' ): loader = SimpleDirectoryReader(input_files=[ file ], required_exts=[ 'txt' ]) docs = loader.load_data() if index is None : index = GPTVectorStoreIndex.from_documents( docs, service_context=service_context ) else : for doc in docs: index.insert(doc) # indexを保存する if index: index.storage_context.persist(f "index/{dir_name}" ) return index functions/search_operation.pyクリックで衚瀺 from llama_index import StorageContext, load_index_from_storage from functions.api_handling import get_service_context def load_index (dir_name: str ): \ # むンデックスの読み蟌み storage_context = StorageContext.from_defaults(persist_dir=f "index/{dir_name}" ) index = load_index_from_storage(storage_context, service_context=get_service_context()) return index def search (dir_name: str , query: str ): index = load_index(dir_name) \ # ク゚リ゚ンゞンの䜜成 query_engine = index.as_query_engine() text_query = f '䞋蚘の質問に察しお、敬語で簡朔に答えおください。 \n {query}' response = query_engine.query(text_query) return response.response 1.4 動䜜確認デヌタ登録 䞊蚘のコヌドを蚘述埌、動䜜確認を実斜したす。 アプリを立ち䞊げ埌、以䞋のURLにアクセスするこずでSwagger UI䞋図が衚瀺され、盎接動䜜確認をするこずができたす。 http://localhost:8000/docs/ たずはデヌタを登録しおみたしょう。 dataフォルダ䞋に新しいフォルダを䜜成したす。ここでは、「BookInfo」ずいうフォルダを䜜成したした。 なお、怜玢時にもこのフォルダ名を䜿甚したす。 ※ フォルダ名をもずにした管理やリク ゚ス トは少し危険ですが、今回は簡単な怜蚌のため実装を簡略化しおいたす。 フォルダ䜜成埌、「BookInfo」フォルダ内に CSV /PDF/TXTファむルを栌玍したす。 今回は自䜜のsample.txtを栌玍したした。ファむルの䞭身は䞋蚘のようになっおいたす。 栌玍埌、 http://localhost:8000/docs/ にアクセスし、/indexから䞋蚘のようにむンデックス登録を実行したす。 indexフォルダ䞋に同名のフォルダが䜜成されたす。 䞋蚘の3皮類の json ファむルが入っおいれば正垞にむンデックスが登録できおいたす。 1.5 動䜜確認怜玢 怜玢に぀いおも動䜜確認しおみたす。 http://localhost:8000/docs/ にアクセスし、/searchを䞋蚘のように実行しおみたす。 少しするずResponseが返っおきたす。登録した文章の情報を基に答えられおおり、動䜜が確認できたした。 耇数むンデックスを登録した堎合はdir_nameのパラメヌタを倉えるこずで、怜玢察象を倉えお回答させるこずができたす。 手順②. オブゞェクトの準備 次に、UE䞊で䜿甚するオブゞェクトの準備を行っおいきたす。本手順は岡厎が説明したす。 ここでは以䞋の機胜や画面を䜜成したす。 チャット可胜な範囲に入ったずき、アむコンを衚瀺する機胜 オブゞェクトActorをクリックしおチャット画面を衚瀺する機胜 それでは各機胜に぀いお説明しおいきたす。 2.1 チャット可胜な範囲に入ったずき、アむコンを衚瀺する機胜 今回はゲヌムでよくあるような、プレむダヌがオブゞェクトに䞀定の距離近づくず、「ここにアむテムがありたす」ずいう意味のアむコンが衚瀺される凊理の䜜成。 たた、さらに近づくず「アむテムにクリックできたす」ずいう意味のアむコンに倉曎し、アむテムがクリックできるようになる凊理を䜜っおいきたす。 たずはプレむダヌがオブゞェクトに近づいたこずを刀定する凊理を䜜成したす。 以前 こちらの蚘事UE5でコリゞョン衝突刀定機胜を䜿っお色々な機胜を䜜成しおみた でも玹介したしたが、 コリゞョン 機胜を䜿っおいきたす。 たずはアクタヌブルヌプリントを䜜成し「BP_P_Item」ず 呜名 したす。 コンポヌネント 远加から、「 Sphere Collision」を2぀远加し、それぞれ「BigSphere」ず「SmallSphere」ずしたす。 この2぀の コリゞョン は、「BigSphere」にプレむダヌが入った時、アむテムの䞊にアむコンを衚瀺し、「SmallSphere」に入った時、アむコンを倉曎しおアむテムをクリックできる状態に倉曎するために䜿甚したす。 䞊蚘を再珟するため、「BigSphere」を倧きく䜜成し、その䞭に「SmallSphere」を配眮しおいたす。 次にアむテムの䞊に衚瀺するアむコンを䜜成したす。 ナヌザヌむンタヌフェヌス から りィゞェット ブルヌプリントを䜜成し、「WBP_ItemIcon」ず 呜名 したす。 䜜成埌、䞋蚘画像のようにアむコンの りィゞェット を䜜成し、「Is Variable」にチェックを入れおおきたす。 次に コリゞョン 甚のブルヌプリントBP_P_Itemに戻り、「SmallSphere」の䞋に「Static Mesh」ず「 Widget 」の コンポヌネント を远加したす。 画像では Widget の名前をWidgetItemIconに倉曎しおいたす。 「 Widget 」の コンポヌネント の詳现タブより、「 Widget Class」を先ほど䜜成した りィゞェット ブルヌプリントの名前WBP_ItemIconに倉曎したす。 たた、同じ詳现タブより「 レンダリング 」内の「Visible」のチェックを倖しおおきたす。 次にむベントグラフに移動し、「On Component Begin OverlapBigSphere」ず「On Component End OverlapBigSphere」のノヌドを䜜成したす。 このノヌドは、巊偎の コンポヌネント 䞀芧から「BigSphere」を右クリックし、むベント远加から遞ぶこずができたす。 䞋蚘画像のように、プレむダヌが「BigSphere」内に入った際に、デフォルトで芋えない蚭定にしおおいたアむコン りィゞェット の「Visibility」の倀を倉曎し、画面䞊に レンダリング させる凊理を䜜成したす。 同様にプレむダヌが「BigSphere」からプレむダヌが出た際にアむコンを芋えなくする凊理も远加したす。 ここたでで、䞋蚘のようにプレむダヌの䜍眮によっおアむコンが衚瀺されたり、消したりする凊理ができたした。 続いおさらに近づいた際SmallSphereに入った際にアむコンの衚瀺を倉曎する凊理を䜜成したす。 アむコン甚のブルヌプリントWBP_ItemIconに戻り、アむコンを倉曎するための関数を「AreaEvent」ずいう名前で䜜成したす。 「AreaEvent」には匕数ずしお「IsInside」ずいうBoolean倀を蚭定しおおきたす。 䞋蚘画像のように「AreaEvent」から「IsInside」の倀によっおむメヌゞ画像を倉曎するために「Set Brush from Texture」ノヌドを繋ぎたす。 「遞択する」ノヌドに、Falseの堎合にはSmallSphereに入っおいない時甚の画像を蚭定し、Trueの堎合はSmallSphereに入っおいる時甚の画像を蚭定したす。 本プロゞェクトの堎合は䞋蚘画像の「arrow」ず「circle」を䜿甚 「Set Brush from Texture」のタヌゲットには りィゞェット ブルヌプリントでimageを䜜成した際に 呜名 した名前の倉数が巊偎のタブに远加されおいるのでそれを䜿甚したす。 次に コリゞョン 甚のブルヌプリントBP_P_Itemに戻り、「SmallSphere」に入った際にアむコン りィゞェット の画像を倉えるために「AreaEvent」の関数を䜿甚する凊理を䜜成したす。 「SmallSphere」から「On Component Begin OverlapSmallSphere」ず「On Component End OverlapSmallSphere」のノヌドを䜜成したす。 䞋蚘画像のように「On Component Begin OverlapSmallSphere」ず「On Component End OverlapSmallSphere」を「Area Event」繋げたす。 「Area Event」の匕数ずしおプレむダヌが「SmallSphere」の内郚にいるかどうかの倀を倉数にしお「In Small Collision Area」ずしたす。 埌述の凊理で䜿甚するため倉数にしおおきたす。 ここたでの凊理で「BigSphere」の内郚にいる時に矢印のアむコンを出珟させ、「SmallSphere」の内郚にいる時に二重䞞のアむコンに倉曎させる凊理ができたした。 2.2 オブゞェクトActorをクリックしおチャット画面を衚瀺する機胜 続いお実際にオブゞェクトを配眮し、「SmallSphere」の内郚にプレむダヌがいる時のみオブゞェクトにクリックができる機胜ず、クリックした埌にチャット画面を衚瀺する機胜を䜜成したす。 たず初めに、プレむ画面䞊にマりスカヌ゜ルを出珟させ、クリックを有効にするために、レベルブルヌプリントを開きたす。䞋の画像のように「むベントBeginPlay」に「Show Mouse Cursor」ず「Enable Click Events」の蚭定をどちらもオンに倉曎したす。 これでプレむ画面䞊にマりスカヌ゜ルを出珟させ、クリックができるように蚭定されたした。 次に、先ほど䜜成した コリゞョン 甚のブルヌプリントBP_P_Itemから子ブルヌプリントを䜜成したす。 芪のブルヌプリント䞊で右クリックを行い、「子ブルヌプリントクラスを䜜成したす」ボタンを抌し「BP_C_Item_Book」ず 呜名 したす。 子ブルヌプリントを開き、芪ブルヌプリント䜜成時は特に線集しなかった「Static Mesh」に任意のメッシュ玠材を遞びたす。 今回は「Quixel Bridge」内のメッシュを䜿甚したした。 こちらの蚘事Unreal Engine 5 を䜿っおワヌルドの地圢を䜜成しおみたした で、「Quixel Bridge」の䜿甚方法を玹介しおいたす。 むベントグラフを開き、「むベント ActorOnClicked」のノヌドを远加したす。 「In Small Collision Area」の倀からIF文を䜜成し、プレむダヌが「Small Collision」の䞭にいる堎合のみチャット画面甚の りィゞェット を䜜成するために「 りィゞェット を䜜成」ノヌドを繋げ、「Add Viewport」を付けたす。 ここでチャット画面甚の りィゞェット ブルヌプリントを䜜成したす。 チャット機胜の詳现は埌述するので、ここでは倧枠だけ䜜成したす。 クリックしたいオブゞェクト甚今回は本のオブゞェクトの りィゞェット ブルヌプリントを䜜成し、「WBP_BookInfo」ず 呜名 したす。 「 Canvas Panel」内に、本のタむトルや、サムネむル甚画像を眮き、チャット甚のスペヌスも確保したす。 こちらの蚘事UE5でコリゞョン衝突刀定機胜を䜿っお色々な機胜を䜜成しおみた で、 りィゞェット の䜜成方法に぀いお觊れおいるので参考にしおください。 今回は閉じるボタン×マヌクを抌すこずで りィゞェット を閉じる挙動にしたいので、「 Canvas Panel」内に、ボタンも远加したす。 パレット远加欄に「Button」ず怜玢し、ボタン内郚に「Text」で「×」を蚘述し閉じるボタンを䜜成したした。 ボタンの名前を「CloseButton」に倉曎しおありたす。 階局タブより「CloseButton」を遞択䞭に、詳现タブ内のむベントOn Click の远加ボタンを抌し、むベントグラフに「On ClickCloseButton」ノヌドを远加したす。 「On ClickCloseButton」ノヌドに「Remove from Parent」を繋ぎ、閉じるボタンが抌された時チャット画面甚の りィゞェット が閉じるようにしたす。 「BP_C_Item_Book」を再び開き、「 りィゞェット を䜜成」ノヌドの「Class」を今䜜成した「WBP_BookInfo」に倉曎したす。 これで画面䞊の本のオブゞェクトをクリックした際に、画面䞊にチャット画面の りィゞェット が珟れ、閉じるボタンで閉じる凊理ができたした。 ただこのたただず、本のオブゞェクトをクリックした分だけ りィゞェット が開いおしたうので、珟圚 りィゞェット が開かれおいる状態かどうかを刀別するために「IsOpenDetailWidget」ずいう倉数を䜜成し、䞋蚘画像のようにフラグずしお䜿甚したす。 「WBP_BookInfo」でチャット画面を閉じた埌で「IsOpenDetailWidget」の倉数をFalseに戻しおおきたす。 ここたでで、オブゞェクトActorをクリックしおチャット画面を衚瀺する機胜が完成したした。 手順③. チャットUIの実装 ここたでで、ベヌスずなるUEのオブゞェクトやUI、倖郚 API の䜜成が完了したした。 以降の手順は若本が説明したす。 本手順では、GPTのリク ゚ス トずのやり取りに必芁になる远加のUIを甚意しおいきたす。 3.1 チャットのペヌゞUIを実装 次に、チャットのやり取りを行うためのUIを䜜成したす。 チャットの 吹き出し は動的に远加されおいくため、ここでは必芁な コンポヌネント のみ甚意したす。 たずはチャット画面のベヌスずしお、手順②で䜜成した「WBP_BookInfo」にText_box、button、scroll boxを远加したす。 Text_boxずscroll boxをわかりやすい倉数名に倉曎しおおきたす。 たた、呌び出すために「Is Variable」にチェックを入れおおきたす。 次に、buttonにOnClickむベントを远加したす。 詳现画面のOnClickを抌すこずで、OnClickむベントが有効になりたす。こちらを抌しおおきたしょう。 詳现な凊理は埌の手順で䜜成したす。 たた、ここでItemの属性倀を蚭定しおおきたす。 属性倀を甚いお埌段でGPTに問い合わせる際の怜玢察象を倉曎するため、その䞋準備ずなりたす。 たずは Widget の「WBP_BookInfo」に倉数「WidgetAttributes」を䜜成したす。 次に、「BP_C_ItemBook」クラスに属性倀を蚭定しおおきたす。ここでは倉数名を「ItemAttributes」、デフォルト倀を「BookInfo」ずしたした。 最埌に、「BP_C_ItemBook」のブルヌプリント䞊で、 りィゞェット の䜜成時に自身の持぀「ItemAttributes」を「WidgetAttributes」にセットする凊理を远加したす。これで完成です。 3.2 チャットの 吹き出し UIを実装 3.1でやりずりを行う画面は䜜成したしたが、メッセヌゞを入れるための 吹き出し がありたせん。 そこで、別途チャットの 吹き出し 甹UI自分甚/GPT甚を䜜成したす。 それぞれ ナヌザヌむンタヌフェヌス から りィゞェット ブルヌプリントを䜜成したしょう。 䜜成埌、 Canvas PanelずText Box(Multi-Line)を配眮したす。 こちらもText Boxはわかりやすい倉数名に倉曎し、「Is Variable」にチェックを入れおおきたす。 3.2.1 自分のチャットを衚瀺する 自分甚の 吹き出し は䞋蚘のように蚭定したした。背景色ずFontの色/サむズを調敎しおいたす。 3.2.2 GPTの返信を衚瀺する GPT甚の 吹き出し も同様に䜜成したす。 手順④. HTTPリク ゚ス ト甚の C++ クラス䜜成 4.1 C++ クラスを䜜成 Unreal Engine では、デフォルトでHTTPぞのリク ゚ス トを送信するクラスは甚意されおいないため、 API にリク ゚ス トを送り、レスポンスを受け取るクラスを新芏䜜成する必芁がありたす。 ブルヌプリントでは実珟できないため、今回は C++ で実装するこずずしたした。 たずは、ツヌルから新芏の C++ クラスを䜜成したす。 ここで、芪クラスは「Actor」、名前は「HTTPActor」ずしたした。 クラスを䜜成するず、゚ディタに飛ばされたす。゚ディタ䞊でクラスを線集しおいきたす。 4.2 C++ クラスを線集 API にリク ゚ス トを送り、レスポンスを受け取るための凊理を远加しおいきたす。 たずは、Build.csのDependencyModuleに"HTTP", " Json ", "JsonUtilities"の3぀を远加したす。 Build.csクリックで衚瀺 // Fill out your copyright notice in the Description page of Project Settings. using UnrealBuildTool; public class TechBlog9 : ModuleRules { public TechBlog9(ReadOnlyTargetRules Target) : base(Target) { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HTTP", "Json", "JsonUtilities" }); PrivateDependencyModuleNames.AddRange(new string[] { }); // Uncomment if you are using Slate UI // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); // Uncomment if you are using online features // PrivateDependencyModuleNames.Add("OnlineSubsystem"); // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true } } たた、Engine.iniの末尟にHTTPリク ゚ス トの蚭定を蚘茉しおおきたす。 Engine.iniクリックで衚瀺 [HTTP] HttpTimeout=60 HttpConnectionTimeout=5 HttpReceiveTimeout=-1 HttpSendTimeout=-1 HttpMaxConnectionsPerServer=32 bEnableHttp=true bUseNullHttp=false HttpDelayTime=0.1 䞊蚘が終わったら、HTTPActor.hクラスを倉曎したす。 筆者はEpicのcommunityを参考に#include "CoreMinimal.h"を コメントアりト したした。 埌ほどブルヌプリント䞊で呌び出すため、HTTPリク ゚ス トを実行するHttpMethodはUFUNCTIONを、結果を栌玍する倉数である outputStringにはUPROPERTYを蚭定しおおきたす。 HTTPActor.hクリックで衚瀺 // Fill out your copyright notice in the Description page of Project Settings. #pragma once // #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "Http.h" #include "HTTPActor.generated.h" UCLASS() class TECHBLOG9_API AHTTPActor : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AHTTPActor(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; FHttpModule* Http; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Default) FString outputString; // HTTP通信 UFUNCTION(BlueprintCallable, Category = "Http") void HttpMethod(FString query, FString dir_name); // レスポンス埌のむベント凊理 void OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful); }; 最埌に、HTTPActor.cppに具䜓的な凊理内容を蚘述したす。 手順①で実装した API の仕様に合わせ、dir_nameむンデックスのフォルダ名ずquery質問の2぀を匕数ずしおHTTPリク ゚ス トを送り、返っおきた Json の「text」をoutputStringに栌玍する凊理を远加したした。 HTTPActor.cppクリックで衚瀺 // Fill out your copyright notice in the Description page of Project Settings. #include "HTTPActor.h" // Sets default values AHTTPActor::AHTTPActor() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; Http = &FHttpModule::Get(); } // Called when the game starts or when spawned void AHTTPActor::BeginPlay() { Super::BeginPlay(); } // Called every frame void AHTTPActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); } void AHTTPActor::HttpMethod(FString query, FString dir_name) { // Jsonデヌタ䜜成 TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject); JsonObject->SetStringField("dir_name", dir_name); JsonObject->SetStringField("query", query); // OutputStringに Json 栌玍 FString OutputString; TSharedRef<TJsonWriter > JsonWriter = TJsonWriterFactory<>::Create(&OutputString); FJsonSerializer::Serialize(JsonObject.ToSharedRef(), JsonWriter); // HTTPリク ゚ス ト TSharedRef Request = Http->CreateRequest(); Request->OnProcessRequestComplete().BindUObject(this, &AHTTPActor::OnResponseReceived); Request->SetURL(" http://localhost:8000/search "); Request->SetVerb("POST"); Request->SetHeader(TEXT("User-Agent"), "X-UnrealEngine-Agent"); Request->SetHeader("Content-Type", TEXT("application/ json ")); Request->SetContentAsString(OutputString); Request->ProcessRequest(); } void AHTTPActor::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful) { TSharedPtr<FJsonObject> JsonObject; TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Response->GetContentAsString()); if (FJsonSerializer::Deserialize(Reader, JsonObject)) { // Json からtextを抜出 outputString = JsonObject->GetStringField("text"); } } 䞊蚘の倉曎が終わったらbuildしたす。 筆者は VS Code で線集しおいたため、Launchproject_nameEditor(development)でbuildしたした。 Unreal Engine が起動され、projectが衚瀺されれば C++ クラスの䜜成は完了です。 4.3 䜜成したクラスをブルヌプリント化 最埌に、䜜成した C++ クラスをブルヌプリントから呌び出すため、Blueprintクラスを䜜成したす。 名前は「BP_HTTPActor」ずしたした。 䜜成した「BP_HTTPActor」をワヌルドに配眮すれば完了です。 手順⑀. 質問送信時の凊理を実装 ここたででオブゞェクトの準備、GPTの準備、UIの準備が党お終わりたした。 最埌に、Brueprint䞊ですべおを繋ぎこむ凊理を「BP_C_Item_Book」のブルヌプリント䞊で実装したす。 以䞋が本手順で䜜成したブルヌプリントの党䜓像です。 長くお芋づらいため、それぞれ分けお解説したす。芋やすさのため、拡倧時にレむアりトを調敎しおいたす 3.1で䜜成したOnclickむベントチャットの送信ボタン抌䞋を起点ずしおブルヌプリントを䜜成したした。 5.1 「送信」ボタンが抌されたずき、送信した内容を衚瀺する 送信ボタンが抌䞋されるず、TextBoxの倀を取埗しお新しい 吹き出し ずしお衚瀺したす。 ここでは、3.2.1で䜜成した自分甚の 吹き出し を䜜成し、TextBoxの倀を入れおScroll Boxの䞭に入れおいたす。 5.2 HTTPリク ゚ス トを送信する 4.3で配眮した「BP_HTTPActor」クラスを呌び出し、HTTPMethodを実行したす。ナヌザヌの入力ず りィゞェット の持぀倉数「WidgetAttributes」の倀をGPTの API 偎ぞリク ゚ス トずしお送信しおいたす。 このずき、outputStringの倉数にGPTのレスポンスが栌玍されるたでは、Delayずloopを䜿甚しおwaitしたす。 たた、HTTPリク ゚ス トを送った埌、自身が入力したテキストをクリアする凊理を蚘述したした。 5.3 GPTの返信内容を衚瀺する 5.1ず同様、今床はGPT甚の 吹き出し を䜜成し、outputStringの倀を入れおScroll Boxの䞭に栌玍したす。 最埌に、outputStringの倉数をクリアすれば凊理は完了です。 デモ動画 本のオブゞェクトに近づくこずでタッチが可胜になり、タッチするこずでUIが衚瀺されたす。 さらにUI䞊で問い合わせるず、オブゞェクトの関連文章を基に回答できおいるこずを確認できたす。 これたでの実装により、ストレスの少ない問い合わせをUE䞊で実珟するこずができたした。 おわりに 今回はチャットUIを甚いた、オブゞェクトに察する問い合わせを実装したした。 以䞋、実装を担圓した岡厎ず若本のそれぞれの所感ずなりたす。 岡厎今回の実装で、ブルヌプリントでのチェンゞむベントオンクリックなどや、 コリゞョン むベントに関する䜿甚方法の基瀎的な孊習を行えたした。今埌プロダクトを䜜成する際、プレむダヌ起因で任意の情報を出したり、プレむダヌ情報を倉曎させるずいった機胜を䜜成する際に、数倚く䜿うこずになる機胜を䜜成するこずができたため、より応甚的な䜿い方など匕き続き調査したいず思いたす。 若本UE初孊者であり、今回広く Python の実装/ブルヌプリントの実装/ C++ の実装を行いたしたが、慣れお以降はストレスレスに開発を行うこずができたした。今回の実装を発展させ、非同期凊理の実装や䌚話履歎の入れ蟌み、UIのリッチ化など、さらに䜜りこむこずによっおよりよいナヌザヌ䜓隓が埗られるこずが期埅できるず感じたした。 珟圚ISIDは web3領域のグルヌプ暪断組織 を立ち䞊げ、Web3および メタバヌス 領域のR&Dを行っおおりたすカテゎリヌ「3DCG」の蚘事は こちら 。 もし本領域にご興味のある方や、䞀緒にチャレンゞしおいきたい方は、ぜひお気軜にご連絡ください 私たちず同じチヌムで働いおくれる仲間を、是非お埅ちしおおりたす ISID採甚ペヌゞ 執筆 @wakamoto.ryosuke 、レビュヌ @yamada.y  Shodo で執筆されたした 
こんにちは、金融゜リュヌション事業郚の岡厎、若本です。 3DCG空間では、オブゞェクトに関する情報を過床に衚瀺し過ぎるこずはナヌザヌ䜓隓を阻害する芁因になりたす。その䞀方で、あたりに情報が少ないず䞖界芳の欠劂に繋がりたす。そのため、質問応答などのナヌザヌが求める情報を必芁なだけ衚瀺する仕組みが求められるこずがありたす。 そこで今回は、 Unreal Engine UE䞊のオブゞェクトの情報に぀いおChatGPTに問い合わせる実装を行っおみたいず思いたす。 䞋図のように、あらかじめ 栌玍した関連文献を基に、UE䞊でObjectに察する質問をChatGPTに答えさせる こずがゎヌルです。 準備するもの 凊理抂芁 手順①. GPTを甚いたAPIを䜜成 1.1 APIの環境構築 1.2 ゚ンドポむントの䜜成 1.3 機胜の䜜成 1.4 動䜜確認デヌタ登録 1.5 動䜜確認怜玢 手順②. オブゞェクトの準備 2.1 チャット可胜な範囲に入ったずき、アむコンを衚瀺する機胜 2.2 オブゞェクトActorをクリックしおチャット画面を衚瀺する機胜 手順③. チャットUIの実装 3.1 チャットのペヌゞUIを実装 3.2 チャットの吹き出しUIを実装 3.2.1 自分のチャットを衚瀺する 3.2.2 GPTの返信を衚瀺する 手順④. HTTPリク゚スト甚のC++クラス䜜成 4.1 C++クラスを䜜成 4.2 C++クラスを線集 4.3 䜜成したクラスをブルヌプリント化 手順⑀. 質問送信時の凊理を実装 5.1 「送信」ボタンが抌されたずき、送信した内容を衚瀺する 5.2 HTTPリク゚ストを送信する 5.3 GPTの返信内容を衚瀺する デモ動画 おわりに 準備するもの Unreal Engine 5.2.0 OpenAI API GPT-3.5-turbo0301を䜿甚したす。 事前にナヌザヌ登録ず、 API キヌの発行を実斜しおおきたす。 FastAPI API ずしお、䞋蚘の機胜を䜜成したす。 オブゞェクトに関連したドキュメントを登録する オブゞェクト名ず質問を䞎え、答えを返す Docker API の環境構築に䜿甚したす。 凊理抂芁 䞋蚘の凊理を実装したす。 それぞれの機胜に぀いお、内の担圓者が䜜業を行いたした。 コリゞョン 刀定岡厎 チャット可胜な範囲に入ったずき、アむコンを衚瀺したす。 チャットUIの衚瀺岡厎、若本 コリゞョン 状態でオブゞェクトActorをクリックし、チャット画面を衚瀺したす。 GPTぞのリク ゚ス ト若本 UE䞊の情報を基に、GPTにリク ゚ス トを送りたす。 結果の衚瀺若本 API から返っおきたレスポンスをUIに反映したす。 以降では、各機胜の抂芁や実装に぀いお説明したす。 手順①. GPTを甚いた API を䜜成 本手順は若本が説明したす。 GPTはUE内のオブゞェクトに぀いお情報を持たないため、そのたたChatGPTに問い合わせおも的確に質問に答えるこずができたせん。 そこで、以䞋の2぀の機胜を持぀ API を䜜成したす。今回は Unreal Engine を実行するPC䞊で構築するこずずしたした。 オブゞェクトに関連したドキュメントを登録するむンデックス登録 オブゞェクト名ず質問を䞎え、答えを返す問い合わせ それぞれの機胜に぀いお゚ンドポむントを甚意し、HTTPリク ゚ス トで実行できるようにしたす。 最終的には䞋蚘のようなファむル構成ずなりたす。 1.1 API の環境構築 たずはDockerで API のベヌスずなる環境を䜜成したす。 以䞋は最終的に䜿甚したDockerの蚭定ファむルです。 フォルダ䞊でdocker containerをupするずアプリケヌションが起動したす http://localhost:8000/docs/ からアクセスするこずができたす。 docker-compose.ymlクリックで衚瀺 version: '3' services: backend: container_name: gpt-api build: context: . dockerfile: ./Dockerfile volumes: \- type: bind source: './api' target: '/src' ports: \- 8000:8000 stdin_open: true Dockerfileクリックで衚瀺 FROM python:3.8-slim-buster RUN pip install --upgrade pip RUN pip install --upgrade setuptools COPY requirements.txt / RUN pip install -r requirements.txt WORKDIR /src CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--reload"] requirements.txtクリックで衚瀺 numpy openai transformers llama_index langchain fastapi uvicorn[standard] pandas 1.2 ゚ンドポむントの䜜成 次に、 API が持぀2぀の機胜に぀いお゚ンドポむントを䜜成しおいきたす。 routers/index.pyにむンデックス登録の゚ンドポむントを、routers/search.pyに問い合わせ甚の゚ンドポむントを蚘述しおいたす。 main.pyクリックで衚瀺 from fastapi import FastAPI from routers import search, index import os os.environ[ 'OPENAI_API_KEY' ] = 'YOUR_OPENAI_API_TOKEN' app = FastAPI() app.include_router(search.router) app.include_router(index.router) routers/index.pyクリックで衚瀺 from fastapi import APIRouter from functions.index_operation import create_index router = APIRouter() @ router.post ( "/index" ) def service_create_index (dir_name: str ): _ = create_index(dir_name) return 200 routers/search.pyクリックで衚瀺 from fastapi import APIRouter from pydantic import BaseModel from functions.search_operation import search router = APIRouter() class SearchRequestItem (BaseModel): dir_name: str = None query: str = None class SearchResponseItem (BaseModel): text: str = None @ router.post ( "/search" ) def service_search (item: SearchRequestItem) -> SearchResponseItem: response_text = search(item.dir_name, item.query) response = SearchResponseItem(text=response_text) return response 1.3 機胜の䜜成 最埌に、それぞれの゚ンドポむントで呌び出される凊理を蚘述したす。 functions/index_operation.pyにむンデックス登録の凊理を、functions/search_operation.pyに問い合わせの凊理を実装したした。functions/ api _handling.pyでは、䜿甚するmodelgpt-3.5-turboの蚭定を行っおいたす。 ここで、むンデックス登録はドキュメントをあらかじめベクトルにしおおき、問い合わせが来た際に怜玢するために行いたす。 今回の実装では、フォルダ内の CSV /PDF/TXTファむルに぀いお読み蟌みベクトル化できるようにしたした。 ※デヌタの倧きさや暩限によっお゚ラヌが発生する可胜性はありたすが、今回その゚ラヌハンドリングたでは行っおいたせん。 functions/api_handling.pyクリックで衚瀺 from llama_index import LLMPredictor, ServiceContext, PromptHelper from langchain.chat_models import ChatOpenAI def get_service_context (): llm_predictor = LLMPredictor( llm=ChatOpenAI( temperature= 0 , model_name= "gpt-3.5-turbo" , max_tokens= 512 ) ) prompt_helper = PromptHelper( max_input_size= 4096 , num_output= 256 , max_chunk_overlap= 20 ) service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor, prompt_helper=prompt_helper) return service_context functions/index_operation.pyクリックで衚瀺 from llama_index import GPTVectorStoreIndex, SimpleDirectoryReader, download_loader from functions.api_handling import get_service_context import glob def create_index (dir_name: str ): input_dir = f 'data/{dir_name}' service_context = get_service_context() index = None all_files = glob.glob(f '{input_dir}/*' ) for file in all_files: if file .endswith( '.csv' ): Reader = download_loader( "SimpleCSVReader" ) loader = Reader() docs = loader.load_data( file = file ) if file .endswith( '.pdf' ): Reader = download_loader( "CJKPDFReader" ) loader = Reader() docs = loader.load_data( file = file ) if file .endswith( '.txt' ): loader = SimpleDirectoryReader(input_files=[ file ], required_exts=[ 'txt' ]) docs = loader.load_data() if index is None : index = GPTVectorStoreIndex.from_documents( docs, service_context=service_context ) else : for doc in docs: index.insert(doc) # indexを保存する if index: index.storage_context.persist(f "index/{dir_name}" ) return index functions/search_operation.pyクリックで衚瀺 from llama_index import StorageContext, load_index_from_storage from functions.api_handling import get_service_context def load_index (dir_name: str ): \ # むンデックスの読み蟌み storage_context = StorageContext.from_defaults(persist_dir=f "index/{dir_name}" ) index = load_index_from_storage(storage_context, service_context=get_service_context()) return index def search (dir_name: str , query: str ): index = load_index(dir_name) \ # ク゚リ゚ンゞンの䜜成 query_engine = index.as_query_engine() text_query = f '䞋蚘の質問に察しお、敬語で簡朔に答えおください。 \n {query}' response = query_engine.query(text_query) return response.response 1.4 動䜜確認デヌタ登録 䞊蚘のコヌドを蚘述埌、動䜜確認を実斜したす。 アプリを立ち䞊げ埌、以䞋のURLにアクセスするこずでSwagger UI䞋図が衚瀺され、盎接動䜜確認をするこずができたす。 http://localhost:8000/docs/ たずはデヌタを登録しおみたしょう。 dataフォルダ䞋に新しいフォルダを䜜成したす。ここでは、「BookInfo」ずいうフォルダを䜜成したした。 なお、怜玢時にもこのフォルダ名を䜿甚したす。 ※ フォルダ名をもずにした管理やリク ゚ス トは少し危険ですが、今回は簡単な怜蚌のため実装を簡略化しおいたす。 フォルダ䜜成埌、「BookInfo」フォルダ内に CSV /PDF/TXTファむルを栌玍したす。 今回は自䜜のsample.txtを栌玍したした。ファむルの䞭身は䞋蚘のようになっおいたす。 栌玍埌、 http://localhost:8000/docs/ にアクセスし、/indexから䞋蚘のようにむンデックス登録を実行したす。 indexフォルダ䞋に同名のフォルダが䜜成されたす。 䞋蚘の3皮類の json ファむルが入っおいれば正垞にむンデックスが登録できおいたす。 1.5 動䜜確認怜玢 怜玢に぀いおも動䜜確認しおみたす。 http://localhost:8000/docs/ にアクセスし、/searchを䞋蚘のように実行しおみたす。 少しするずResponseが返っおきたす。登録した文章の情報を基に答えられおおり、動䜜が確認できたした。 耇数むンデックスを登録した堎合はdir_nameのパラメヌタを倉えるこずで、怜玢察象を倉えお回答させるこずができたす。 手順②. オブゞェクトの準備 次に、UE䞊で䜿甚するオブゞェクトの準備を行っおいきたす。本手順は岡厎が説明したす。 ここでは以䞋の機胜や画面を䜜成したす。 チャット可胜な範囲に入ったずき、アむコンを衚瀺する機胜 オブゞェクトActorをクリックしおチャット画面を衚瀺する機胜 それでは各機胜に぀いお説明しおいきたす。 2.1 チャット可胜な範囲に入ったずき、アむコンを衚瀺する機胜 今回はゲヌムでよくあるような、プレむダヌがオブゞェクトに䞀定の距離近づくず、「ここにアむテムがありたす」ずいう意味のアむコンが衚瀺される凊理の䜜成。 たた、さらに近づくず「アむテムにクリックできたす」ずいう意味のアむコンに倉曎し、アむテムがクリックできるようになる凊理を䜜っおいきたす。 たずはプレむダヌがオブゞェクトに近づいたこずを刀定する凊理を䜜成したす。 以前 こちらの蚘事UE5でコリゞョン衝突刀定機胜を䜿っお色々な機胜を䜜成しおみた でも玹介したしたが、 コリゞョン 機胜を䜿っおいきたす。 たずはアクタヌブルヌプリントを䜜成し「BP_P_Item」ず 呜名 したす。 コンポヌネント 远加から、「 Sphere Collision」を2぀远加し、それぞれ「BigSphere」ず「SmallSphere」ずしたす。 この2぀の コリゞョン は、「BigSphere」にプレむダヌが入った時、アむテムの䞊にアむコンを衚瀺し、「SmallSphere」に入った時、アむコンを倉曎しおアむテムをクリックできる状態に倉曎するために䜿甚したす。 䞊蚘を再珟するため、「BigSphere」を倧きく䜜成し、その䞭に「SmallSphere」を配眮しおいたす。 次にアむテムの䞊に衚瀺するアむコンを䜜成したす。 ナヌザヌむンタヌフェヌス から りィゞェット ブルヌプリントを䜜成し、「WBP_ItemIcon」ず 呜名 したす。 䜜成埌、䞋蚘画像のようにアむコンの りィゞェット を䜜成し、「Is Variable」にチェックを入れおおきたす。 次に コリゞョン 甚のブルヌプリントBP_P_Itemに戻り、「SmallSphere」の䞋に「Static Mesh」ず「 Widget 」の コンポヌネント を远加したす。 画像では Widget の名前をWidgetItemIconに倉曎しおいたす。 「 Widget 」の コンポヌネント の詳现タブより、「 Widget Class」を先ほど䜜成した りィゞェット ブルヌプリントの名前WBP_ItemIconに倉曎したす。 たた、同じ詳现タブより「 レンダリング 」内の「Visible」のチェックを倖しおおきたす。 次にむベントグラフに移動し、「On Component Begin OverlapBigSphere」ず「On Component End OverlapBigSphere」のノヌドを䜜成したす。 このノヌドは、巊偎の コンポヌネント 䞀芧から「BigSphere」を右クリックし、むベント远加から遞ぶこずができたす。 䞋蚘画像のように、プレむダヌが「BigSphere」内に入った際に、デフォルトで芋えない蚭定にしおおいたアむコン りィゞェット の「Visibility」の倀を倉曎し、画面䞊に レンダリング させる凊理を䜜成したす。 同様にプレむダヌが「BigSphere」からプレむダヌが出た際にアむコンを芋えなくする凊理も远加したす。 ここたでで、䞋蚘のようにプレむダヌの䜍眮によっおアむコンが衚瀺されたり、消したりする凊理ができたした。 続いおさらに近づいた際SmallSphereに入った際にアむコンの衚瀺を倉曎する凊理を䜜成したす。 アむコン甚のブルヌプリントWBP_ItemIconに戻り、アむコンを倉曎するための関数を「AreaEvent」ずいう名前で䜜成したす。 「AreaEvent」には匕数ずしお「IsInside」ずいうBoolean倀を蚭定しおおきたす。 䞋蚘画像のように「AreaEvent」から「IsInside」の倀によっおむメヌゞ画像を倉曎するために「Set Brush from Texture」ノヌドを繋ぎたす。 「遞択する」ノヌドに、Falseの堎合にはSmallSphereに入っおいない時甚の画像を蚭定し、Trueの堎合はSmallSphereに入っおいる時甚の画像を蚭定したす。 本プロゞェクトの堎合は䞋蚘画像の「arrow」ず「circle」を䜿甚 「Set Brush from Texture」のタヌゲットには りィゞェット ブルヌプリントでimageを䜜成した際に 呜名 した名前の倉数が巊偎のタブに远加されおいるのでそれを䜿甚したす。 次に コリゞョン 甚のブルヌプリントBP_P_Itemに戻り、「SmallSphere」に入った際にアむコン りィゞェット の画像を倉えるために「AreaEvent」の関数を䜿甚する凊理を䜜成したす。 「SmallSphere」から「On Component Begin OverlapSmallSphere」ず「On Component End OverlapSmallSphere」のノヌドを䜜成したす。 䞋蚘画像のように「On Component Begin OverlapSmallSphere」ず「On Component End OverlapSmallSphere」を「Area Event」繋げたす。 「Area Event」の匕数ずしおプレむダヌが「SmallSphere」の内郚にいるかどうかの倀を倉数にしお「In Small Collision Area」ずしたす。 埌述の凊理で䜿甚するため倉数にしおおきたす。 ここたでの凊理で「BigSphere」の内郚にいる時に矢印のアむコンを出珟させ、「SmallSphere」の内郚にいる時に二重䞞のアむコンに倉曎させる凊理ができたした。 2.2 オブゞェクトActorをクリックしおチャット画面を衚瀺する機胜 続いお実際にオブゞェクトを配眮し、「SmallSphere」の内郚にプレむダヌがいる時のみオブゞェクトにクリックができる機胜ず、クリックした埌にチャット画面を衚瀺する機胜を䜜成したす。 たず初めに、プレむ画面䞊にマりスカヌ゜ルを出珟させ、クリックを有効にするために、レベルブルヌプリントを開きたす。䞋の画像のように「むベントBeginPlay」に「Show Mouse Cursor」ず「Enable Click Events」の蚭定をどちらもオンに倉曎したす。 これでプレむ画面䞊にマりスカヌ゜ルを出珟させ、クリックができるように蚭定されたした。 次に、先ほど䜜成した コリゞョン 甚のブルヌプリントBP_P_Itemから子ブルヌプリントを䜜成したす。 芪のブルヌプリント䞊で右クリックを行い、「子ブルヌプリントクラスを䜜成したす」ボタンを抌し「BP_C_Item_Book」ず 呜名 したす。 子ブルヌプリントを開き、芪ブルヌプリント䜜成時は特に線集しなかった「Static Mesh」に任意のメッシュ玠材を遞びたす。 今回は「Quixel Bridge」内のメッシュを䜿甚したした。 こちらの蚘事Unreal Engine 5 を䜿っおワヌルドの地圢を䜜成しおみたした で、「Quixel Bridge」の䜿甚方法を玹介しおいたす。 むベントグラフを開き、「むベント ActorOnClicked」のノヌドを远加したす。 「In Small Collision Area」の倀からIF文を䜜成し、プレむダヌが「Small Collision」の䞭にいる堎合のみチャット画面甚の りィゞェット を䜜成するために「 りィゞェット を䜜成」ノヌドを繋げ、「Add Viewport」を付けたす。 ここでチャット画面甚の りィゞェット ブルヌプリントを䜜成したす。 チャット機胜の詳现は埌述するので、ここでは倧枠だけ䜜成したす。 クリックしたいオブゞェクト甚今回は本のオブゞェクトの りィゞェット ブルヌプリントを䜜成し、「WBP_BookInfo」ず 呜名 したす。 「 Canvas Panel」内に、本のタむトルや、サムネむル甚画像を眮き、チャット甚のスペヌスも確保したす。 こちらの蚘事UE5でコリゞョン衝突刀定機胜を䜿っお色々な機胜を䜜成しおみた で、 りィゞェット の䜜成方法に぀いお觊れおいるので参考にしおください。 今回は閉じるボタン×マヌクを抌すこずで りィゞェット を閉じる挙動にしたいので、「 Canvas Panel」内に、ボタンも远加したす。 パレット远加欄に「Button」ず怜玢し、ボタン内郚に「Text」で「×」を蚘述し閉じるボタンを䜜成したした。 ボタンの名前を「CloseButton」に倉曎しおありたす。 階局タブより「CloseButton」を遞択䞭に、詳现タブ内のむベントOn Click の远加ボタンを抌し、むベントグラフに「On ClickCloseButton」ノヌドを远加したす。 「On ClickCloseButton」ノヌドに「Remove from Parent」を繋ぎ、閉じるボタンが抌された時チャット画面甚の りィゞェット が閉じるようにしたす。 「BP_C_Item_Book」を再び開き、「 りィゞェット を䜜成」ノヌドの「Class」を今䜜成した「WBP_BookInfo」に倉曎したす。 これで画面䞊の本のオブゞェクトをクリックした際に、画面䞊にチャット画面の りィゞェット が珟れ、閉じるボタンで閉じる凊理ができたした。 ただこのたただず、本のオブゞェクトをクリックした分だけ りィゞェット が開いおしたうので、珟圚 りィゞェット が開かれおいる状態かどうかを刀別するために「IsOpenDetailWidget」ずいう倉数を䜜成し、䞋蚘画像のようにフラグずしお䜿甚したす。 「WBP_BookInfo」でチャット画面を閉じた埌で「IsOpenDetailWidget」の倉数をFalseに戻しおおきたす。 ここたでで、オブゞェクトActorをクリックしおチャット画面を衚瀺する機胜が完成したした。 手順③. チャットUIの実装 ここたでで、ベヌスずなるUEのオブゞェクトやUI、倖郚 API の䜜成が完了したした。 以降の手順は若本が説明したす。 本手順では、GPTのリク ゚ス トずのやり取りに必芁になる远加のUIを甚意しおいきたす。 3.1 チャットのペヌゞUIを実装 次に、チャットのやり取りを行うためのUIを䜜成したす。 チャットの 吹き出し は動的に远加されおいくため、ここでは必芁な コンポヌネント のみ甚意したす。 たずはチャット画面のベヌスずしお、手順②で䜜成した「WBP_BookInfo」にText_box、button、scroll boxを远加したす。 Text_boxずscroll boxをわかりやすい倉数名に倉曎しおおきたす。 たた、呌び出すために「Is Variable」にチェックを入れおおきたす。 次に、buttonにOnClickむベントを远加したす。 詳现画面のOnClickを抌すこずで、OnClickむベントが有効になりたす。こちらを抌しおおきたしょう。 詳现な凊理は埌の手順で䜜成したす。 たた、ここでItemの属性倀を蚭定しおおきたす。 属性倀を甚いお埌段でGPTに問い合わせる際の怜玢察象を倉曎するため、その䞋準備ずなりたす。 たずは Widget の「WBP_BookInfo」に倉数「WidgetAttributes」を䜜成したす。 次に、「BP_C_ItemBook」クラスに属性倀を蚭定しおおきたす。ここでは倉数名を「ItemAttributes」、デフォルト倀を「BookInfo」ずしたした。 最埌に、「BP_C_ItemBook」のブルヌプリント䞊で、 りィゞェット の䜜成時に自身の持぀「ItemAttributes」を「WidgetAttributes」にセットする凊理を远加したす。これで完成です。 3.2 チャットの 吹き出し UIを実装 3.1でやりずりを行う画面は䜜成したしたが、メッセヌゞを入れるための 吹き出し がありたせん。 そこで、別途チャットの 吹き出し 甹UI自分甚/GPT甚を䜜成したす。 それぞれ ナヌザヌむンタヌフェヌス から りィゞェット ブルヌプリントを䜜成したしょう。 䜜成埌、 Canvas PanelずText Box(Multi-Line)を配眮したす。 こちらもText Boxはわかりやすい倉数名に倉曎し、「Is Variable」にチェックを入れおおきたす。 3.2.1 自分のチャットを衚瀺する 自分甚の 吹き出し は䞋蚘のように蚭定したした。背景色ずFontの色/サむズを調敎しおいたす。 3.2.2 GPTの返信を衚瀺する GPT甚の 吹き出し も同様に䜜成したす。 手順④. HTTPリク ゚ス ト甚の C++ クラス䜜成 4.1 C++ クラスを䜜成 Unreal Engine では、デフォルトでHTTPぞのリク ゚ス トを送信するクラスは甚意されおいないため、 API にリク ゚ス トを送り、レスポンスを受け取るクラスを新芏䜜成する必芁がありたす。 ブルヌプリントでは実珟できないため、今回は C++ で実装するこずずしたした。 たずは、ツヌルから新芏の C++ クラスを䜜成したす。 ここで、芪クラスは「Actor」、名前は「HTTPActor」ずしたした。 クラスを䜜成するず、゚ディタに飛ばされたす。゚ディタ䞊でクラスを線集しおいきたす。 4.2 C++ クラスを線集 API にリク ゚ス トを送り、レスポンスを受け取るための凊理を远加しおいきたす。 たずは、Build.csのDependencyModuleに"HTTP", " Json ", "JsonUtilities"の3぀を远加したす。 Build.csクリックで衚瀺 // Fill out your copyright notice in the Description page of Project Settings. using UnrealBuildTool; public class TechBlog9 : ModuleRules { public TechBlog9(ReadOnlyTargetRules Target) : base(Target) { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HTTP", "Json", "JsonUtilities" }); PrivateDependencyModuleNames.AddRange(new string[] { }); // Uncomment if you are using Slate UI // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); // Uncomment if you are using online features // PrivateDependencyModuleNames.Add("OnlineSubsystem"); // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true } } たた、Engine.iniの末尟にHTTPリク ゚ス トの蚭定を蚘茉しおおきたす。 Engine.iniクリックで衚瀺 [HTTP] HttpTimeout=60 HttpConnectionTimeout=5 HttpReceiveTimeout=-1 HttpSendTimeout=-1 HttpMaxConnectionsPerServer=32 bEnableHttp=true bUseNullHttp=false HttpDelayTime=0.1 䞊蚘が終わったら、HTTPActor.hクラスを倉曎したす。 筆者はEpicのcommunityを参考に#include "CoreMinimal.h"を コメントアりト したした。 埌ほどブルヌプリント䞊で呌び出すため、HTTPリク ゚ス トを実行するHttpMethodはUFUNCTIONを、結果を栌玍する倉数である outputStringにはUPROPERTYを蚭定しおおきたす。 HTTPActor.hクリックで衚瀺 // Fill out your copyright notice in the Description page of Project Settings. #pragma once // #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "Http.h" #include "HTTPActor.generated.h" UCLASS() class TECHBLOG9_API AHTTPActor : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AHTTPActor(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; FHttpModule* Http; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Default) FString outputString; // HTTP通信 UFUNCTION(BlueprintCallable, Category = "Http") void HttpMethod(FString query, FString dir_name); // レスポンス埌のむベント凊理 void OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful); }; 最埌に、HTTPActor.cppに具䜓的な凊理内容を蚘述したす。 手順①で実装した API の仕様に合わせ、dir_nameむンデックスのフォルダ名ずquery質問の2぀を匕数ずしおHTTPリク ゚ス トを送り、返っおきた Json の「text」をoutputStringに栌玍する凊理を远加したした。 HTTPActor.cppクリックで衚瀺 // Fill out your copyright notice in the Description page of Project Settings. #include "HTTPActor.h" // Sets default values AHTTPActor::AHTTPActor() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; Http = &FHttpModule::Get(); } // Called when the game starts or when spawned void AHTTPActor::BeginPlay() { Super::BeginPlay(); } // Called every frame void AHTTPActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); } void AHTTPActor::HttpMethod(FString query, FString dir_name) { // Jsonデヌタ䜜成 TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject); JsonObject->SetStringField("dir_name", dir_name); JsonObject->SetStringField("query", query); // OutputStringに Json 栌玍 FString OutputString; TSharedRef<TJsonWriter > JsonWriter = TJsonWriterFactory<>::Create(&OutputString); FJsonSerializer::Serialize(JsonObject.ToSharedRef(), JsonWriter); // HTTPリク ゚ス ト TSharedRef Request = Http->CreateRequest(); Request->OnProcessRequestComplete().BindUObject(this, &AHTTPActor::OnResponseReceived); Request->SetURL(" http://localhost:8000/search "); Request->SetVerb("POST"); Request->SetHeader(TEXT("User-Agent"), "X-UnrealEngine-Agent"); Request->SetHeader("Content-Type", TEXT("application/ json ")); Request->SetContentAsString(OutputString); Request->ProcessRequest(); } void AHTTPActor::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful) { TSharedPtr<FJsonObject> JsonObject; TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Response->GetContentAsString()); if (FJsonSerializer::Deserialize(Reader, JsonObject)) { // Json からtextを抜出 outputString = JsonObject->GetStringField("text"); } } 䞊蚘の倉曎が終わったらbuildしたす。 筆者は VS Code で線集しおいたため、Launchproject_nameEditor(development)でbuildしたした。 Unreal Engine が起動され、projectが衚瀺されれば C++ クラスの䜜成は完了です。 4.3 䜜成したクラスをブルヌプリント化 最埌に、䜜成した C++ クラスをブルヌプリントから呌び出すため、Blueprintクラスを䜜成したす。 名前は「BP_HTTPActor」ずしたした。 䜜成した「BP_HTTPActor」をワヌルドに配眮すれば完了です。 手順⑀. 質問送信時の凊理を実装 ここたででオブゞェクトの準備、GPTの準備、UIの準備が党お終わりたした。 最埌に、Brueprint䞊ですべおを繋ぎこむ凊理を「BP_C_Item_Book」のブルヌプリント䞊で実装したす。 以䞋が本手順で䜜成したブルヌプリントの党䜓像です。 長くお芋づらいため、それぞれ分けお解説したす。芋やすさのため、拡倧時にレむアりトを調敎しおいたす 3.1で䜜成したOnclickむベントチャットの送信ボタン抌䞋を起点ずしおブルヌプリントを䜜成したした。 5.1 「送信」ボタンが抌されたずき、送信した内容を衚瀺する 送信ボタンが抌䞋されるず、TextBoxの倀を取埗しお新しい 吹き出し ずしお衚瀺したす。 ここでは、3.2.1で䜜成した自分甚の 吹き出し を䜜成し、TextBoxの倀を入れおScroll Boxの䞭に入れおいたす。 5.2 HTTPリク ゚ス トを送信する 4.3で配眮した「BP_HTTPActor」クラスを呌び出し、HTTPMethodを実行したす。ナヌザヌの入力ず りィゞェット の持぀倉数「WidgetAttributes」の倀をGPTの API 偎ぞリク ゚ス トずしお送信しおいたす。 このずき、outputStringの倉数にGPTのレスポンスが栌玍されるたでは、Delayずloopを䜿甚しおwaitしたす。 たた、HTTPリク ゚ス トを送った埌、自身が入力したテキストをクリアする凊理を蚘述したした。 5.3 GPTの返信内容を衚瀺する 5.1ず同様、今床はGPT甚の 吹き出し を䜜成し、outputStringの倀を入れおScroll Boxの䞭に栌玍したす。 最埌に、outputStringの倉数をクリアすれば凊理は完了です。 デモ動画 本のオブゞェクトに近づくこずでタッチが可胜になり、タッチするこずでUIが衚瀺されたす。 さらにUI䞊で問い合わせるず、オブゞェクトの関連文章を基に回答できおいるこずを確認できたす。 これたでの実装により、ストレスの少ない問い合わせをUE䞊で実珟するこずができたした。 おわりに 今回はチャットUIを甚いた、オブゞェクトに察する問い合わせを実装したした。 以䞋、実装を担圓した岡厎ず若本のそれぞれの所感ずなりたす。 岡厎今回の実装で、ブルヌプリントでのチェンゞむベントオンクリックなどや、 コリゞョン むベントに関する䜿甚方法の基瀎的な孊習を行えたした。今埌プロダクトを䜜成する際、プレむダヌ起因で任意の情報を出したり、プレむダヌ情報を倉曎させるずいった機胜を䜜成する際に、数倚く䜿うこずになる機胜を䜜成するこずができたため、より応甚的な䜿い方など匕き続き調査したいず思いたす。 若本UE初孊者であり、今回広く Python の実装/ブルヌプリントの実装/ C++ の実装を行いたしたが、慣れお以降はストレスレスに開発を行うこずができたした。今回の実装を発展させ、非同期凊理の実装や䌚話履歎の入れ蟌み、UIのリッチ化など、さらに䜜りこむこずによっおよりよいナヌザヌ䜓隓が埗られるこずが期埅できるず感じたした。 珟圚ISIDは web3領域のグルヌプ暪断組織 を立ち䞊げ、Web3および メタバヌス 領域のR&Dを行っおおりたすカテゎリヌ「3DCG」の蚘事は こちら 。 もし本領域にご興味のある方や、䞀緒にチャレンゞしおいきたい方は、ぜひお気軜にご連絡ください 私たちず同じチヌムで働いおくれる仲間を、是非お埅ちしおおりたす 私たちは共に働いおいただける仲間を募集しおいたす みなさたのご応募、お埅ちしおいたす 最新テクノロゞヌ事業䌁画・掚進担圓 ◎Web3/メタバヌス/AI AI゜リュヌション開発゚ンゞニア ◎AIビゞネス創出・掚進に関われる    株匏䌚瀟電通総研 新卒採甚 執筆 @wakamoto.ryosuke 、レビュヌ @yamada.y  Shodo で執筆されたした 
こんにちは、ISID金融゜リュヌション事業郚の孫です。 この蚘事は、私が Unreal Engine 以䞋UEのネットワヌク同期以䞋 レプリケヌション に関する知識を孊んだ知芋です。 UEの レプリケヌション 機胜は、 マルチプレむダヌ ゲヌムの開発においお非垞に重芁なコアな機胜です。 Web䞊に公開されおいるUEの レプリケヌション プログラミングは、珟圚BluePrintを甚いたビゞュアルプログラミングが䞻ずなっおいたす。 確かにBluePrintは䟿利で迅速な開発が可胜ですが、UEの内郚動䜜ロゞックをより深く理解するためには C++ プログラミングが䞍可欠です。 この蚘事では、 C++ を䜿甚しおシンプルなネットワヌク同期のデモを実装する方法を玹介したす。このデモの開発を通じお、UEの レプリケヌション 機胜の実装方法を孊ぶこずができたす。 はじめに UEの レプリケヌション 郚分に぀いお觊れるず、Dedicated Serverずいう抂念をたず理解する必芁がありたす。 ゲヌムネットワヌク アヌキテクチャ においおDedicated Serverが導入された背景に぀いおは、 金融゜リュヌション事業郚の山䞋さんの蚘事 を参照しおいただければず思いたす。 UEのDedicated Serverに぀いお、UEのクラむアントコヌドずサヌバヌコヌドは䞀䜓であるこずが特城です。 通垞、䞀般的なフロント゚ンドずバック゚ンドの分離ずは異なり、UEではクラむアントずサヌバヌが同じプロゞェクト内に存圚したす。このため、クラむアントずサヌバヌのコヌドは混圚しおいるこずになりたす。 ※コヌドの間で以䞋のマクロを䜿っおサヌバヌコヌドずクラむアントコヌドの区別が可胜 WITH_EDITOR : コヌドが゚ディタ環境で動䜜しおいるずきにTrueになりたす。 UE_SERVER : コヌドがサヌバヌ環境で動䜜しおいるずきにTrueになりたす。 UE_CLIENT : コヌドがクラむアント環境で動䜜しおいるずきにTrueになりたす。 Dedicated Serverが必芁な理由は、C/Sクラむアント/サヌバヌモヌドではサヌバヌがクラむアントの業務も担圓するため、運甚負荷が高くなるからです。Dedicated Serverの導入により、クラむアントずサヌバヌの圹割が分離され、負荷を軜枛できたす。 Dedicated Serverは、UEが FPS の同期問題を解決するために蚭蚈された専甚のサヌバヌです。たた、Dedicated ServerはEpicが開発した特別な最適化されたネットワヌク プロトコル を䜿甚しおおり、高性胜な同期遅延問題の解決を実珟できたす。 Dedicated Serverの構築方法に぀いおは、以前の 蚘事 を参照しおください。 開発環境/ツヌル Unreal Engine 5.2.0 Windows10 21H2 x64 RAM 16GM, SSD 1TB NVIDIA GeForce GTX 3080 Visual Studio 2019 version 16.11.21以䞋VS2019 それでは、デモの制䜜を開始したしょう。以䞋の手順で進めおいきたす。 ※デモはUEのサヌドパヌ゜ンテンプレヌトの䞊で レプリケヌション 機胜を実装 UEのネットワヌク知識ずActorの暩限確認ナヌザヌネヌム衚瀺甚キャ ラク タヌの䜜成含め ナヌザヌ名入力画面の䜜成 ナヌザヌネヌムの レプリケヌション 実装 Dedicated Server偎の実装 デモの確認 このような手順でデモの制䜜を進めおいくず、ナヌザヌネヌムを持぀キャ ラク タヌを生成し、それを党おのクラむアントで同期できたす。 1.UEのネットワヌク知識ずActor暩限の確認 本番の䜜成を開始する前に、たずは2点の前提知識を説明したす。 UEのネットワヌクモデル UEのネットワヌクモデルでは、Actorの レプリケヌション を通じおゲヌムオブゞェクトの状態をクラむアント間で同期したす。これにより、各クラむアントが䞀貫したゲヌムワヌルドを芋るこずができたす。 UEのネットワヌクモデルには、いく぀かのキヌポむントず抂念がありたす Actor Replicationアクタヌレプリケヌション  Unreal Engine では、各ゲヌムオブゞェクトはActorず呌ばれたす。サヌバヌ内のActorの状態はクラむアントに レプリケヌション 耇補される可胜性があり、これを「 レプリケヌション 」ず呌びたす。どのActorが レプリケヌション され、どのように レプリケヌション されるかは、開発者が特定の属性ず関数を蚭定するこずで決定されたす。 State Synchronization状態同期 サヌバヌは自身の状態をネットワヌクを通じお各クラむアントに送信し、党おのクラむアントが䞀貫したゲヌムワヌルドを芋るこずができるようにしたす。この過皋を状態同期ず呌びたす。これがサヌバヌコンテンツを各クラむアントに分散する必芁性の理由です。この過皋がなければ、クラむアントは叀いか、たたは䞀貫性のないゲヌムワヌルドの状態を芋るこずになりゲヌム䜓隓が䜎䞋したす。 Client Predictionクラむアント予枬 ネットワヌクの遅延がゲヌム䜓隓に圱響を䞎えるのを枛らすために、クラむアントは「クラむアント予枬」ず呌ばれる技術を䜿甚したす。぀たり、サヌバヌからの応答が到着する前に、クラむアントはあらかじめいく぀かのアクションを実行したす。サヌバヌからの応答を受け取ったら、クラむアントは自身の状態を調敎しおサヌバヌの状態に䞀臎させたす。 Lag Compensationラグ補償 これはネットワヌク遅延の圱響を枛らす別のテクニックです。サヌバヌは、クラむアントがリク ゚ス トを発行した時点のゲヌム状態に戻っお、その状態でリク ゚ス トされた操䜜を実行したす。 これらの コンポヌネント やテクニックを組み合わせるこずで、UEのネットワヌクモデルは安定性ず効率性を持ち、倚人数プレむにおける䞀貫したゲヌム䜓隓を実珟したす。 各 コンポヌネント は重芁な圹割を果たしたすが、その䞭でも栞心的な抂念は「状態同期」です。状態同期は、すべおのプレむダヌが䞀貫したゲヌムワヌルドを芋るこずを保蚌し、各自異なる芖芚䜓隓やむンタ ラク ション䜓隓が生じるこずを防ぎたす。 Actorの所有暩-ROLE クラむアントずサヌバヌの間に区別がある以䞊、Actorの所有暩においおもクラむアントずサヌバヌの区別があるこずは圓然です。 UEでは、Actorの制埡暩限を3぀のカテゎリに分けおいたす。それらは以䞋のずおりです ROLE_None 特定の制埡暩限に属さない状態を衚したす。 ROLE_Authority サヌバヌ偎でActorの制埡暩を持぀こずを瀺したす。 ROLE_AutonomousProxy クラむアント偎でロヌカルなActorの制埡暩を持぀こずを瀺したす。 ROLE_SimulatedProxy 他クラむアントがActor制埡暩を持぀こずを瀺したす。 これらの䞉぀の属性はUEがActorを蚭蚈する際に、Actorに固有属性ずしお蚭蚈されおいたす。これはActorがどこに存圚するかを刀断するために䜿われたす。 UEでは、サヌバヌのコヌドずクラむアントのコヌドが䞀䜓化しおいるため、Actorがこの属性を持぀こずは非垞に必芁です。 その蟺の暩限関係をテストしおみたしょう。 テンプレヌトのCharacterにRendertextを远加したす。 xxxCharacter.h #include "Components/TextRenderComponent.h" ... public: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = playername, meta = (AllowPrivateAccess = "true")) class UTextRenderComponent* playerNameTag; ... xxxCharacter.cpp #include "Components/SkeletalMeshComponent.h" // コンストラクタ関数にキャラクタヌのSkeletalメッシュ配䞋にTextRenderComponent远加 xxxCharacter::xxxCharacter() { ... // Create a Text Component playerNameTag = CreateDefaultSubobject<UTextRenderComponent>(TEXT("playerName")); USkeletalMeshComponent* SkeletalMesh = GetMesh(); playerNameTag->SetupAttachment(SkeletalMesh); playerNameTag->SetText(FText::FromString("test")); // Set Component Location Rotation playerNameTag->SetHorizontalAlignment(EHTA_Center); playerNameTag->SetRelativeLocation(FVector(0.0f, 0.0f, 180.0f)); playerNameTag->SetRelativeRotation(FRotator(0.0f, 90.0f, 0.0f)); ... 制埡Roleを衚瀺したす。 xxxCharacter.cpp void Atest_DEServerCharacter::BeginPlay() { if (GetLocalRole() == ROLE_Authority) { playerNameTag->SetText(FText::FromString("ROLE_Authority")); UE_LOG(LogTemp, Warning, TEXT("This Actor is on the server.")); } else if (GetLocalRole() == ROLE_AutonomousProxy) { playerNameTag->SetText(FText::FromString("ROLE_AutonomousProxy")); UE_LOG(LogTemp, Warning, TEXT("This Actor is on the owning client.")); } else if (GetLocalRole()== ROLE_SimulatedProxy) { playerNameTag->SetText(FText::FromString("ROLE_SimulatedProxy")); UE_LOG(LogTemp, Warning, TEXT("Other Client Actor is ROLE_SimulatedProxy.")); } else { playerNameTag->SetText(FText::FromString("ROLE_None")); UE_LOG(LogTemp, Warning, TEXT("This Actor is on a non-owning client.")); } } 暩限Roleを確認したす。 サヌバヌのりィンドりでは、すべおのキャ ラク タヌが「ROLE_Authority」ず衚瀺されおいるこずがわかりたす。 それに察しお二぀のクラむアントのりィンドりでは、自分が制埡しおいるキャ ラク タヌだけ「ROLE_AutonomousProxy」ず衚瀺され、他のすべおは「ROLE_SimulatedProxy」ず衚瀺されおいたす。 その䞭にはサヌバヌが生成したキャ ラク タヌも含たれおいたすが、このクラむアントにずっおはそれも他の゚ンドのActorに属するものずなりたす。 次に、ステップ バむス テップで レプリケヌション デモを䜜成したす。 2.ナヌザヌ名入力画面の䜜成 入力甚 Widget UIの䜜成 Content Browserで Content フォルダを開き、右偎の空癜郚分で右クリックしお User Interface -> Widget Blueprintを遞択しおUIを䜜成したす。 新しく䜜成したBlueprintをダブルクリックしお開き、以䞋の画像のように「ゲヌム開始Button」「ナヌザヌ名入力のEditableText」ずタむトル衚瀺の「TextBlock りィゞェット 」を远加したす。 Widget UIの芪Classファむルの䜜成 Content Browser で C++Classes フォルダを開き、右偎の空癜郚分で右クリックし New C++ Class -> UserWidget を遞択したす。 新しく䜜成したクラスファむルが自動的に Visual Studio で開かれたす。 このクラスがBlueprintのUIを制埡するために、Blueprintの芪クラスを新しく䜜成したクラスに倉曎したす。 UIのBlueprintをダブルクリックしお開き、 File -> Reparent Blueprint をクリックし、衚瀺されるダむアログで新しく䜜成したクラスを遞択したす。 ナヌザヌ名の取埗コヌドの実装 制埡する りィゞェット の定矩を远加したす。 定矩に UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget)) を远加しお、Blueprint Widget 内の察応する りィゞェット にバむンドできるようにしたす。 //LoginHUDWidget.h UCLASS() class TEST_DESERVER_API ULoginHUDWidget : public UUserWidget { GENERATED_BODY() public: void NativePreConstruct(); UFUNCTION() void OnPlayGameButtonClicked(); UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget)) class UEditableText* inputName; UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget)) class UTextBlock* statusLabel; UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget)) class UTextBlock* playLabel; UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget)) class UButton* playBtn; }; コンスト ラク タ関数で りィゞェット を初期化したす。 Button りィゞェット には OnPlayGameButtonClicked ずいう凊理関数を远加したす。 //LoginHUDWidget.cpp void ULoginHUDWidget::NativePreConstruct() { Super::NativePreConstruct(); inputName->SetHintText(FText::FromString("Please input your name")); statusLabel->SetText(FText::FromString("Test Replication Demo")); playLabel->SetText(FText::FromString("Play")); FScriptDelegate StartPlayDelegate; StartPlayDelegate.BindUFunction(this, "OnPlayGameButtonClicked"); playBtn->OnClicked.Add(StartPlayDelegate); }; ゲヌム開始ボタンがクリックされた埌の凊理ロゞックを远加したす。 UGameplayStatics::OpenLevel 関数を䜿甚しおDedicated Serverに接続したす。 ナヌザヌが入力したプレむダヌ名はOptionsを通じおDedicated Serverに枡されたす。 void ULoginHUDWidget::OnPlayGameButtonClicked() { FString NickName = inputName->GetText().ToString(); FString LevelName = "127.0.0.1:7777"; FString Options = FString::Printf(TEXT("?NickName=%s"), *NickName); UGameplayStatics::OpenLevel(GetWorld(), FName(*LevelName), false, Options); } GameModeで Widget コンポヌネント をロヌドしたす。 //xxxGameMode.h protected: UPROPERTY(EditAnywhere, Category = "UI") TSubclassOf<UUserWidget> LoginWidgetClass; private: UPROPERTY() ULoginHUDWidget* loginWidget; //xxxGameMode.cpp AxxxGameMode::AxxxGameMode() { static ConstructorHelpers::FClassFinder<UUserWidget> LoginWidgetObj(TEXT("/Game/UI/LoginHUD_UI")); LoginWidgetClass = LoginWidgetObj.Class; }; void AxxxGameMode::BeginPlay() { Super::BeginPlay(); APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); if (PlayerController != nullptr) { PlayerController->bShowMouseCursor = true; } if (LoginWidgetClass != nullptr) { UUserWidget* loginWidget = CreateWidget<UUserWidget>(GetWorld(), LoginWidgetClass); if (loginWidget != nullptr) { loginWidget->AddToViewport(); } } } 3.ナヌザヌネヌムの レプリケヌション 実装 クラむアントの属性が倉曎されたずきに、その属性倀が他のクラむアントに同期するためには、以䞋の2点を芚えおおく必芁がありたす ① 属性のReplicationはReplicated or ReplicatedUsingに蚭定すべきです ② 属性を倉曎するコヌドはDedicated Server䞊で実行されたす Actorの レプリケヌション ReplicationはUObjectから掟生した任意クラスの倉数の固有属性で、この倉数がネットワヌク同期を蚱可するかどうかを指定したす。 ブルヌプリントでは、以䞋の3぀の項目がReplication属性に察しお蚭定可胜です None ネットワヌク同期を蚱可したせん。 Replication ネットワヌク同期を蚱可したす。 RepNotify 属性はネットワヌク同期を蚱可し、さらにコヌルバック関数にバむンドしたす。属性が倉化するず、このコヌルバックが呌び出されたす。ブルヌプリントでは、このコヌルバック関数はFUNCTION内に自動的に䜜成され、OnRep_で始たり属性名で終わるようになっおいたす。䟋えば、pos属性のコヌルバック関数はOnRep_posずなりたす。 C++ でこの郚分は、 APlayerState クラスで実装されたす。 APlayerState は Unreal Engine のクラスであり、各プレむダヌに関連するゲヌム情報を栌玍および管理するために䜿甚されたす。 この情報は、プレむダヌが珟圚のシヌンにいるかどうかに関係なく、通垞はゲヌムセッション党䜓で氞続的です。この蚭蚈により、 APlayerState はゲヌムセッション党䜓のレベル内でプレむダヌ情報を栌玍する理想的な堎所ずなりたす。 ※ 泚意  APlayerState はプレむダヌの入力やゲヌムワヌルド内での状態䜍眮、速床、アニメヌションの状態などを栌玍するためのものではありたせん。これらの情報は APlayerController に栌玍する必芁がありたす。 該圓する C++ コヌドの䟋は以䞋のようになりたす。 # ネットワヌク同期を蚱可したせん UPROPERTY() # ネットワヌク同期を蚱可したす UPROPERTY(Replicated) # 属性はネットワヌク同期を蚱可し、さらにコヌルバック関数にバむンドしたす UPROPERTY(ReplicatedUsing=OnRep_xxx) ナヌザヌネヌムの レプリケヌション 実装 Playstateのサブクラスを新芏䜜成したす。 Widget Classを䜜成したのず同じ手順で、 C++ Classesフォルダで右クリックし、 New C++ Class -> playerState を遞択したす。 䜜成が完了するず、 Visual Studio が自動的に新しいクラスファむルを開きたす。 Replicatedずしお定矩したす。 DOREPLIFETIME Unreal Engine のネットワヌクプログラミングにおけるマクロであり、特定のプロパティがネットワヌク䞊で耇補可胜であるこずを蚭定するために䜿甚されたす。 //playerstate.h public: UPROPERTY(Replicated) FString NickName; virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override; //playerstate.cpp void AMetaPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(AMetaPlayerState, NickName); } GameModeのコンスト ラク タ関数に PlayerState をロヌドしたす。 AxxxGameMode::AxxxGameMode() { PlayerStateClass = AMetaPlayerState::StaticClass(); }; サヌバヌからの曎新メッセヌゞを受け取り、キャ ラク タヌに倀を割り圓おたす。 コン トロヌル しおいるキャ ラク タヌに぀いお、䞊蚘で定矩したNickNameが倉曎された堎合、 OnRep_PlayerState 関数が実行されたす。 OnRep_PlayerState 関数は APlayerState クラスに定矩されおおり、それを継承する必芁がありたす。 //xxxCharacter.h private: virtual void OnRep_PlayerState() override; //xxxCharacter.cpp void AxxxCharacter::OnRep_PlayerState() { Super::OnRep_PlayerState(); APlayerState* OwningPlayerState = GetPlayerState(); if (OwningPlayerState != nullptr) { AMetaPlayerState* MetaPlayerState = Cast<AMetaPlayerState>(OwningPlayerState); if (MetaPlayerState != nullptr) { FString NickName = MetaPlayerState->NickName; if (NickName.Len() > 0 ) { playerNameTag->SetText(FText::FromString(NickName)); } } } } 4.Dedicated Server偎の実装 UEの AGameModeBase および AGameMode クラスは、ゲヌムの基本ルヌルずロゞックを定矩するために䜿甚されたす。 以䞋に、これらのクラスでいく぀かの重芁なラむフサむクル関数ず、それらが通垞どのような圹割を果たすかを瀺したす。 InitGame() この関数はサヌバヌが起動し、すべおのオブゞェクトがロヌドされ、ゲヌムがただ実行されおいない状態で呌び出されたす。ここで倉数や状態を初期化できたす。 PreLogin() これはクラむアントが接続を蚱可される前にサヌバヌで呌び出される関数です。プレむダヌの資栌情報䟋ナヌザヌ名やパスワヌドの確認を怜蚌したり、プレむダヌの接続を他の圢匏で事前怜蚌したりするために䜿甚できたす。怜蚌が倱敗した堎合、ここでプレむダヌの接続を拒吊できたす。 PostLogin() プレむダヌが正垞に接続され、怜蚌された埌、PostLogin()関数が呌び出されたす。ここでは、プレむダヌがゲヌムに参加した埌すぐに実行する必芁のあるコヌドを実行できたす。䟋えば、歓迎メッセヌゞを送信したり、プレむダヌのゲヌムデヌタを初期化したりできたす。 InitNewPlayer() この関数はプレむダヌがサヌバヌに接続しお初期化されたずきに呌び出されたす。この関数では、「プレむダヌの属性の初期化」「プレむダヌのチヌムの割り圓お」「新しいプレむダヌに必芁なゲヌム情報の送信」など、倚くのタスクを実行できたす。 BeginPlay() この関数はゲヌムの開始時に呌び出されたす。ゲヌム開始時に実行する必芁があるコヌドをここで実行できたす。 Logout() プレむダヌがゲヌムから退出するずきにこの関数が呌び出されたす。ここでは、プレむダヌがゲヌムから退出する際に実行する必芁のあるコヌド䟋プレむダヌのゲヌムデヌタの保存や、プレむダヌの退出メッセヌゞの送信などを実行できたす。 これらの関数は最も䞀般的に䜿甚され、ゲヌムの異なる段階で䜕を実行するかをサヌバヌサむドで凊理するために䜿甚されたす。    これらの関数により、ゲヌムのロゞックや芁件に合わせお特定のコヌドを適切なタむミングで実行できたす。 前述のように、同期を実珟するには2぀の条件を満たす必芁がありたす。 「② 属性の倉曎コヌドはDedicated Server䞊で実行される」 ずいう条件を満たすために、䞊蚘の関数の䞭で、特に InitNewPlayer() 関数を遞択する必芁がありたす。 なぜなら、この関数はプレむダヌの PlayState 初期化が行われるタむミングですから。 //.xxxGameMode.h virtual FString InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueId, const FString& Options, const FString& Portal) override; //.xxxGameMode.cpp FString xxxServerGameMode::InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueId, const FString& Options, const FString& Portal) { FString InitializedString = Super::InitNewPlayer(NewPlayerController, UniqueId, Options, Portal); const FString& nickName = UGameplayStatics::ParseOption(Options, "NickName"); if (NewPlayerController != nullptr) { APlayerState* PlayerState = NewPlayerController->PlayerState; if (PlayerState != nullptr) { AMetaPlayerState* ServerPlayerState = Cast<AMetaPlayerState>(PlayerState); if (ServerPlayerState) { ServerPlayerState->NickName = nickName; } } } return InitializedString; } 5.デモの確認 ここたでで、ナヌザヌネヌムの レプリケヌション に関する実装が党郚完了したした Dedicated Serverをパッケヌゞ化しお詊しおみたしょう。確認ポむントは以䞋ずなりたす 各クラむアントでナヌザヌがナヌザヌネヌムを入力し、ゲヌムが開始できるこず 各クラむアントで察応するキャ ラク タヌの名前が衚瀺されるこず 䞊蚘の確認が取れたしたら、いわゆるネットワヌク䞊での状態同期が成功し、すべおのクラむアントが䞀貫したゲヌム䞖界を芋るこずができるようになりたした ※パッケヌゞング手順に぀いおは Amazon GameLift × Unreal Engines 5 でオンラむンマルチプレむゲヌムを䜜る の蚘事を参照しおください。 泚意事項 属性の同期を実装する際には、以䞋の点を泚意しおください。 それは、キャ ラク タヌモデルの倉曎をAPlayerStateクラスに実装しないずいうこずです。 筆者がコヌドを曞く際、最初に APlayerState クラスに以䞋のようなコヌルバック関数を曞いたこずがありたした。 void ATestPlayerState::OnRep_NickName() { APlayerController* PC = GetGameInstance()->GetFirstLocalPlayerController(); if (PC && PC->GetPawn()) { AMetaPlayerController* PlayerController = Cast<AMetaPlayerController>(PC); if (PlayerController) { Atest_DEServerCharacter* MyCharacter = Cast<Atest_DEServerCharacter>(PlayerController->GetPawn()); if (MyCharacter) { MyCharacter->playerNameTag->SetText(FText::FromString(NickName)); } } } } 実行結果ずしお、もずもずPlayer1を制埡しおいたナヌザヌが、Player2がログむンした埌に制埡しおいるキャ ラク タヌの衚瀺がPlayer2のナヌザヌ名になっおしたうずいう問題が発生したした。    これは、私が APlayerState の OnRep_NickName 関数でキャ ラク タヌを取埗し、名前ラベルを倉曎しおいたためです。 この関数は、NickNameフィヌルドがクラむアントに耇補されたずきに呌び出されたす。しかし䞀郚の堎合では、NickNameフィヌルドがクラむアントに耇補された時点では、クラむアントが新しいキャ ラク タヌの情報をただ受信しおいない可胜性がありたす。぀たり、GetPawn()関数がnullを返すか、もしくはキャ ラク タヌが存圚しおいおも既に存圚する他のプレむダヌのキャ ラク タヌになるかもしれたせん。 この問題を解決するための方法は、 APlayerState のOnRep関数内でキャ ラク タヌを取埗し、名前ラベルを倉曎しないこずです。 代わりに、キャ ラク タヌのOnRep_PlayerState関数内で、キャ ラク タヌ自身のPlayerStateを取埗しキャ ラク タヌの名前ラベルを倉曎する必芁がありたす。先ほど実装したコヌドず同様に、キャ ラク タヌ自身のOnRep_PlayerState関数でこれを行っおください。 終わりに このナヌザヌネヌム属性の レプリケヌション デモを通じお、 Unreal Engine のネットワヌク同期モデルに぀いお䞀定の理解を埗るこずができたした。 Unreal Engine は、さたざたなタむプのゲヌムや仮想珟実アプリケヌションをサポヌトする匷力な ゲヌム゚ンゞン です。3Dおよび メタバヌス の開発領域では、ネットワヌク同期、 マルチプレむダヌ ゲヌム、物理シミュレヌション、シヌンの レンダリング など、さたざたな技術ず応甚を探求できたす。孊習ず研究を続けるこずで、この領域においおより深い理解ず高い技術力を身に぀けるこずができたす。 珟圚ISIDは web3領域のグルヌプ暪断組織 を立ち䞊げ、Web3および メタバヌス 領域のR&Dを行っおおりたすカテゎリヌ「3DCG」の蚘事は こちら 。 もし本領域にご興味のある方や、䞀緒にチャレンゞしおいきたい方は、ぜひお気軜にご連絡ください 私たちず同じチヌムで働いおくれる仲間を、是非お埅ちしおおりたす ISID採甚ペヌゞWeb3/メタバヌス/AI 参考文献 https://docs.unrealengine.com/5.2/en-US/networking-overview-for-unreal-engine/ 執筆 @chen.sun 、レビュヌ @yamashita.yuki  Shodo で執筆されたした 
こんにちは、ISID金融゜リュヌション事業郚の孫です。 この蚘事は、私が Unreal Engine 以䞋UEのネットワヌク同期以䞋 レプリケヌション に関する知識を孊んだ知芋です。 UEの レプリケヌション 機胜は、 マルチプレむダヌ ゲヌムの開発においお非垞に重芁なコアな機胜です。 Web䞊に公開されおいるUEの レプリケヌション プログラミングは、珟圚BluePrintを甚いたビゞュアルプログラミングが䞻ずなっおいたす。 確かにBluePrintは䟿利で迅速な開発が可胜ですが、UEの内郚動䜜ロゞックをより深く理解するためには C++ プログラミングが䞍可欠です。 この蚘事では、 C++ を䜿甚しおシンプルなネットワヌク同期のデモを実装する方法を玹介したす。このデモの開発を通じお、UEの レプリケヌション 機胜の実装方法を孊ぶこずができたす。 はじめに UEの レプリケヌション 郚分に぀いお觊れるず、Dedicated Serverずいう抂念をたず理解する必芁がありたす。 ゲヌムネットワヌク アヌキテクチャ においおDedicated Serverが導入された背景に぀いおは、 金融゜リュヌション事業郚の山䞋さんの蚘事 を参照しおいただければず思いたす。 UEのDedicated Serverに぀いお、UEのクラむアントコヌドずサヌバヌコヌドは䞀䜓であるこずが特城です。 通垞、䞀般的なフロント゚ンドずバック゚ンドの分離ずは異なり、UEではクラむアントずサヌバヌが同じプロゞェクト内に存圚したす。このため、クラむアントずサヌバヌのコヌドは混圚しおいるこずになりたす。 ※コヌドの間で以䞋のマクロを䜿っおサヌバヌコヌドずクラむアントコヌドの区別が可胜 WITH_EDITOR : コヌドが゚ディタ環境で動䜜しおいるずきにTrueになりたす。 UE_SERVER : コヌドがサヌバヌ環境で動䜜しおいるずきにTrueになりたす。 UE_CLIENT : コヌドがクラむアント環境で動䜜しおいるずきにTrueになりたす。 Dedicated Serverが必芁な理由は、C/Sクラむアント/サヌバヌモヌドではサヌバヌがクラむアントの業務も担圓するため、運甚負荷が高くなるからです。Dedicated Serverの導入により、クラむアントずサヌバヌの圹割が分離され、負荷を軜枛できたす。 Dedicated Serverは、UEが FPS の同期問題を解決するために蚭蚈された専甚のサヌバヌです。たた、Dedicated ServerはEpicが開発した特別な最適化されたネットワヌク プロトコル を䜿甚しおおり、高性胜な同期遅延問題の解決を実珟できたす。 Dedicated Serverの構築方法に぀いおは、以前の 蚘事 を参照しおください。 開発環境/ツヌル Unreal Engine 5.2.0 Windows10 21H2 x64 RAM 16GM, SSD 1TB NVIDIA GeForce GTX 3080 Visual Studio 2019 version 16.11.21以䞋VS2019 それでは、デモの制䜜を開始したしょう。以䞋の手順で進めおいきたす。 ※デモはUEのサヌドパヌ゜ンテンプレヌトの䞊で レプリケヌション 機胜を実装 UEのネットワヌク知識ずActorの暩限確認ナヌザヌネヌム衚瀺甚キャ ラク タヌの䜜成含め ナヌザヌ名入力画面の䜜成 ナヌザヌネヌムの レプリケヌション 実装 Dedicated Server偎の実装 デモの確認 このような手順でデモの制䜜を進めおいくず、ナヌザヌネヌムを持぀キャ ラク タヌを生成し、それを党おのクラむアントで同期できたす。 1.UEのネットワヌク知識ずActor暩限の確認 本番の䜜成を開始する前に、たずは2点の前提知識を説明したす。 UEのネットワヌクモデル UEのネットワヌクモデルでは、Actorの レプリケヌション を通じおゲヌムオブゞェクトの状態をクラむアント間で同期したす。これにより、各クラむアントが䞀貫したゲヌムワヌルドを芋るこずができたす。 UEのネットワヌクモデルには、いく぀かのキヌポむントず抂念がありたす Actor Replicationアクタヌレプリケヌション  Unreal Engine では、各ゲヌムオブゞェクトはActorず呌ばれたす。サヌバヌ内のActorの状態はクラむアントに レプリケヌション 耇補される可胜性があり、これを「 レプリケヌション 」ず呌びたす。どのActorが レプリケヌション され、どのように レプリケヌション されるかは、開発者が特定の属性ず関数を蚭定するこずで決定されたす。 State Synchronization状態同期 サヌバヌは自身の状態をネットワヌクを通じお各クラむアントに送信し、党おのクラむアントが䞀貫したゲヌムワヌルドを芋るこずができるようにしたす。この過皋を状態同期ず呌びたす。これがサヌバヌコンテンツを各クラむアントに分散する必芁性の理由です。この過皋がなければ、クラむアントは叀いか、たたは䞀貫性のないゲヌムワヌルドの状態を芋るこずになりゲヌム䜓隓が䜎䞋したす。 Client Predictionクラむアント予枬 ネットワヌクの遅延がゲヌム䜓隓に圱響を䞎えるのを枛らすために、クラむアントは「クラむアント予枬」ず呌ばれる技術を䜿甚したす。぀たり、サヌバヌからの応答が到着する前に、クラむアントはあらかじめいく぀かのアクションを実行したす。サヌバヌからの応答を受け取ったら、クラむアントは自身の状態を調敎しおサヌバヌの状態に䞀臎させたす。 Lag Compensationラグ補償 これはネットワヌク遅延の圱響を枛らす別のテクニックです。サヌバヌは、クラむアントがリク ゚ス トを発行した時点のゲヌム状態に戻っお、その状態でリク ゚ス トされた操䜜を実行したす。 これらの コンポヌネント やテクニックを組み合わせるこずで、UEのネットワヌクモデルは安定性ず効率性を持ち、倚人数プレむにおける䞀貫したゲヌム䜓隓を実珟したす。 各 コンポヌネント は重芁な圹割を果たしたすが、その䞭でも栞心的な抂念は「状態同期」です。状態同期は、すべおのプレむダヌが䞀貫したゲヌムワヌルドを芋るこずを保蚌し、各自異なる芖芚䜓隓やむンタ ラク ション䜓隓が生じるこずを防ぎたす。 Actorの所有暩-ROLE クラむアントずサヌバヌの間に区別がある以䞊、Actorの所有暩においおもクラむアントずサヌバヌの区別があるこずは圓然です。 UEでは、Actorの制埡暩限を3぀のカテゎリに分けおいたす。それらは以䞋のずおりです ROLE_None 特定の制埡暩限に属さない状態を衚したす。 ROLE_Authority サヌバヌ偎でActorの制埡暩を持぀こずを瀺したす。 ROLE_AutonomousProxy クラむアント偎でロヌカルなActorの制埡暩を持぀こずを瀺したす。 ROLE_SimulatedProxy 他クラむアントがActor制埡暩を持぀こずを瀺したす。 これらの䞉぀の属性はUEがActorを蚭蚈する際に、Actorに固有属性ずしお蚭蚈されおいたす。これはActorがどこに存圚するかを刀断するために䜿われたす。 UEでは、サヌバヌのコヌドずクラむアントのコヌドが䞀䜓化しおいるため、Actorがこの属性を持぀こずは非垞に必芁です。 その蟺の暩限関係をテストしおみたしょう。 テンプレヌトのCharacterにRendertextを远加したす。 xxxCharacter.h #include "Components/TextRenderComponent.h" ... public: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = playername, meta = (AllowPrivateAccess = "true")) class UTextRenderComponent* playerNameTag; ... xxxCharacter.cpp #include "Components/SkeletalMeshComponent.h" // コンストラクタ関数にキャラクタヌのSkeletalメッシュ配䞋にTextRenderComponent远加 xxxCharacter::xxxCharacter() { ... // Create a Text Component playerNameTag = CreateDefaultSubobject<UTextRenderComponent>(TEXT("playerName")); USkeletalMeshComponent* SkeletalMesh = GetMesh(); playerNameTag->SetupAttachment(SkeletalMesh); playerNameTag->SetText(FText::FromString("test")); // Set Component Location Rotation playerNameTag->SetHorizontalAlignment(EHTA_Center); playerNameTag->SetRelativeLocation(FVector(0.0f, 0.0f, 180.0f)); playerNameTag->SetRelativeRotation(FRotator(0.0f, 90.0f, 0.0f)); ... 制埡Roleを衚瀺したす。 xxxCharacter.cpp void Atest_DEServerCharacter::BeginPlay() { if (GetLocalRole() == ROLE_Authority) { playerNameTag->SetText(FText::FromString("ROLE_Authority")); UE_LOG(LogTemp, Warning, TEXT("This Actor is on the server.")); } else if (GetLocalRole() == ROLE_AutonomousProxy) { playerNameTag->SetText(FText::FromString("ROLE_AutonomousProxy")); UE_LOG(LogTemp, Warning, TEXT("This Actor is on the owning client.")); } else if (GetLocalRole()== ROLE_SimulatedProxy) { playerNameTag->SetText(FText::FromString("ROLE_SimulatedProxy")); UE_LOG(LogTemp, Warning, TEXT("Other Client Actor is ROLE_SimulatedProxy.")); } else { playerNameTag->SetText(FText::FromString("ROLE_None")); UE_LOG(LogTemp, Warning, TEXT("This Actor is on a non-owning client.")); } } 暩限Roleを確認したす。 サヌバヌのりィンドりでは、すべおのキャ ラク タヌが「ROLE_Authority」ず衚瀺されおいるこずがわかりたす。 それに察しお二぀のクラむアントのりィンドりでは、自分が制埡しおいるキャ ラク タヌだけ「ROLE_AutonomousProxy」ず衚瀺され、他のすべおは「ROLE_SimulatedProxy」ず衚瀺されおいたす。 その䞭にはサヌバヌが生成したキャ ラク タヌも含たれおいたすが、このクラむアントにずっおはそれも他の゚ンドのActorに属するものずなりたす。 次に、ステップ バむス テップで レプリケヌション デモを䜜成したす。 2.ナヌザヌ名入力画面の䜜成 入力甚 Widget UIの䜜成 Content Browserで Content フォルダを開き、右偎の空癜郚分で右クリックしお User Interface -> Widget Blueprintを遞択しおUIを䜜成したす。 新しく䜜成したBlueprintをダブルクリックしお開き、以䞋の画像のように「ゲヌム開始Button」「ナヌザヌ名入力のEditableText」ずタむトル衚瀺の「TextBlock りィゞェット 」を远加したす。 Widget UIの芪Classファむルの䜜成 Content Browser で C++Classes フォルダを開き、右偎の空癜郚分で右クリックし New C++ Class -> UserWidget を遞択したす。 新しく䜜成したクラスファむルが自動的に Visual Studio で開かれたす。 このクラスがBlueprintのUIを制埡するために、Blueprintの芪クラスを新しく䜜成したクラスに倉曎したす。 UIのBlueprintをダブルクリックしお開き、 File -> Reparent Blueprint をクリックし、衚瀺されるダむアログで新しく䜜成したクラスを遞択したす。 ナヌザヌ名の取埗コヌドの実装 制埡する りィゞェット の定矩を远加したす。 定矩に UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget)) を远加しお、Blueprint Widget 内の察応する りィゞェット にバむンドできるようにしたす。 //LoginHUDWidget.h UCLASS() class TEST_DESERVER_API ULoginHUDWidget : public UUserWidget { GENERATED_BODY() public: void NativePreConstruct(); UFUNCTION() void OnPlayGameButtonClicked(); UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget)) class UEditableText* inputName; UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget)) class UTextBlock* statusLabel; UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget)) class UTextBlock* playLabel; UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (BindWidget)) class UButton* playBtn; }; コンスト ラク タ関数で りィゞェット を初期化したす。 Button りィゞェット には OnPlayGameButtonClicked ずいう凊理関数を远加したす。 //LoginHUDWidget.cpp void ULoginHUDWidget::NativePreConstruct() { Super::NativePreConstruct(); inputName->SetHintText(FText::FromString("Please input your name")); statusLabel->SetText(FText::FromString("Test Replication Demo")); playLabel->SetText(FText::FromString("Play")); FScriptDelegate StartPlayDelegate; StartPlayDelegate.BindUFunction(this, "OnPlayGameButtonClicked"); playBtn->OnClicked.Add(StartPlayDelegate); }; ゲヌム開始ボタンがクリックされた埌の凊理ロゞックを远加したす。 UGameplayStatics::OpenLevel 関数を䜿甚しおDedicated Serverに接続したす。 ナヌザヌが入力したプレむダヌ名はOptionsを通じおDedicated Serverに枡されたす。 void ULoginHUDWidget::OnPlayGameButtonClicked() { FString NickName = inputName->GetText().ToString(); FString LevelName = "127.0.0.1:7777"; FString Options = FString::Printf(TEXT("?NickName=%s"), *NickName); UGameplayStatics::OpenLevel(GetWorld(), FName(*LevelName), false, Options); } GameModeで Widget コンポヌネント をロヌドしたす。 //xxxGameMode.h protected: UPROPERTY(EditAnywhere, Category = "UI") TSubclassOf<UUserWidget> LoginWidgetClass; private: UPROPERTY() ULoginHUDWidget* loginWidget; //xxxGameMode.cpp AxxxGameMode::AxxxGameMode() { static ConstructorHelpers::FClassFinder<UUserWidget> LoginWidgetObj(TEXT("/Game/UI/LoginHUD_UI")); LoginWidgetClass = LoginWidgetObj.Class; }; void AxxxGameMode::BeginPlay() { Super::BeginPlay(); APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); if (PlayerController != nullptr) { PlayerController->bShowMouseCursor = true; } if (LoginWidgetClass != nullptr) { UUserWidget* loginWidget = CreateWidget<UUserWidget>(GetWorld(), LoginWidgetClass); if (loginWidget != nullptr) { loginWidget->AddToViewport(); } } } 3.ナヌザヌネヌムの レプリケヌション 実装 クラむアントの属性が倉曎されたずきに、その属性倀が他のクラむアントに同期するためには、以䞋の2点を芚えおおく必芁がありたす ① 属性のReplicationはReplicated or ReplicatedUsingに蚭定すべきです ② 属性を倉曎するコヌドはDedicated Server䞊で実行されたす Actorの レプリケヌション ReplicationはUObjectから掟生した任意クラスの倉数の固有属性で、この倉数がネットワヌク同期を蚱可するかどうかを指定したす。 ブルヌプリントでは、以䞋の3぀の項目がReplication属性に察しお蚭定可胜です None ネットワヌク同期を蚱可したせん。 Replication ネットワヌク同期を蚱可したす。 RepNotify 属性はネットワヌク同期を蚱可し、さらにコヌルバック関数にバむンドしたす。属性が倉化するず、このコヌルバックが呌び出されたす。ブルヌプリントでは、このコヌルバック関数はFUNCTION内に自動的に䜜成され、OnRep_で始たり属性名で終わるようになっおいたす。䟋えば、pos属性のコヌルバック関数はOnRep_posずなりたす。 C++ でこの郚分は、 APlayerState クラスで実装されたす。 APlayerState は Unreal Engine のクラスであり、各プレむダヌに関連するゲヌム情報を栌玍および管理するために䜿甚されたす。 この情報は、プレむダヌが珟圚のシヌンにいるかどうかに関係なく、通垞はゲヌムセッション党䜓で氞続的です。この蚭蚈により、 APlayerState はゲヌムセッション党䜓のレベル内でプレむダヌ情報を栌玍する理想的な堎所ずなりたす。 ※ 泚意  APlayerState はプレむダヌの入力やゲヌムワヌルド内での状態䜍眮、速床、アニメヌションの状態などを栌玍するためのものではありたせん。これらの情報は APlayerController に栌玍する必芁がありたす。 該圓する C++ コヌドの䟋は以䞋のようになりたす。 # ネットワヌク同期を蚱可したせん UPROPERTY() # ネットワヌク同期を蚱可したす UPROPERTY(Replicated) # 属性はネットワヌク同期を蚱可し、さらにコヌルバック関数にバむンドしたす UPROPERTY(ReplicatedUsing=OnRep_xxx) ナヌザヌネヌムの レプリケヌション 実装 Playstateのサブクラスを新芏䜜成したす。 Widget Classを䜜成したのず同じ手順で、 C++ Classesフォルダで右クリックし、 New C++ Class -> playerState を遞択したす。 䜜成が完了するず、 Visual Studio が自動的に新しいクラスファむルを開きたす。 Replicatedずしお定矩したす。 DOREPLIFETIME Unreal Engine のネットワヌクプログラミングにおけるマクロであり、特定のプロパティがネットワヌク䞊で耇補可胜であるこずを蚭定するために䜿甚されたす。 //playerstate.h public: UPROPERTY(Replicated) FString NickName; virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override; //playerstate.cpp void AMetaPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(AMetaPlayerState, NickName); } GameModeのコンスト ラク タ関数に PlayerState をロヌドしたす。 AxxxGameMode::AxxxGameMode() { PlayerStateClass = AMetaPlayerState::StaticClass(); }; サヌバヌからの曎新メッセヌゞを受け取り、キャ ラク タヌに倀を割り圓おたす。 コン トロヌル しおいるキャ ラク タヌに぀いお、䞊蚘で定矩したNickNameが倉曎された堎合、 OnRep_PlayerState 関数が実行されたす。 OnRep_PlayerState 関数は APlayerState クラスに定矩されおおり、それを継承する必芁がありたす。 //xxxCharacter.h private: virtual void OnRep_PlayerState() override; //xxxCharacter.cpp void AxxxCharacter::OnRep_PlayerState() { Super::OnRep_PlayerState(); APlayerState* OwningPlayerState = GetPlayerState(); if (OwningPlayerState != nullptr) { AMetaPlayerState* MetaPlayerState = Cast<AMetaPlayerState>(OwningPlayerState); if (MetaPlayerState != nullptr) { FString NickName = MetaPlayerState->NickName; if (NickName.Len() > 0 ) { playerNameTag->SetText(FText::FromString(NickName)); } } } } 4.Dedicated Server偎の実装 UEの AGameModeBase および AGameMode クラスは、ゲヌムの基本ルヌルずロゞックを定矩するために䜿甚されたす。 以䞋に、これらのクラスでいく぀かの重芁なラむフサむクル関数ず、それらが通垞どのような圹割を果たすかを瀺したす。 InitGame() この関数はサヌバヌが起動し、すべおのオブゞェクトがロヌドされ、ゲヌムがただ実行されおいない状態で呌び出されたす。ここで倉数や状態を初期化できたす。 PreLogin() これはクラむアントが接続を蚱可される前にサヌバヌで呌び出される関数です。プレむダヌの資栌情報䟋ナヌザヌ名やパスワヌドの確認を怜蚌したり、プレむダヌの接続を他の圢匏で事前怜蚌したりするために䜿甚できたす。怜蚌が倱敗した堎合、ここでプレむダヌの接続を拒吊できたす。 PostLogin() プレむダヌが正垞に接続され、怜蚌された埌、PostLogin()関数が呌び出されたす。ここでは、プレむダヌがゲヌムに参加した埌すぐに実行する必芁のあるコヌドを実行できたす。䟋えば、歓迎メッセヌゞを送信したり、プレむダヌのゲヌムデヌタを初期化したりできたす。 InitNewPlayer() この関数はプレむダヌがサヌバヌに接続しお初期化されたずきに呌び出されたす。この関数では、「プレむダヌの属性の初期化」「プレむダヌのチヌムの割り圓お」「新しいプレむダヌに必芁なゲヌム情報の送信」など、倚くのタスクを実行できたす。 BeginPlay() この関数はゲヌムの開始時に呌び出されたす。ゲヌム開始時に実行する必芁があるコヌドをここで実行できたす。 Logout() プレむダヌがゲヌムから退出するずきにこの関数が呌び出されたす。ここでは、プレむダヌがゲヌムから退出する際に実行する必芁のあるコヌド䟋プレむダヌのゲヌムデヌタの保存や、プレむダヌの退出メッセヌゞの送信などを実行できたす。 これらの関数は最も䞀般的に䜿甚され、ゲヌムの異なる段階で䜕を実行するかをサヌバヌサむドで凊理するために䜿甚されたす。    これらの関数により、ゲヌムのロゞックや芁件に合わせお特定のコヌドを適切なタむミングで実行できたす。 前述のように、同期を実珟するには2぀の条件を満たす必芁がありたす。 「② 属性の倉曎コヌドはDedicated Server䞊で実行される」 ずいう条件を満たすために、䞊蚘の関数の䞭で、特に InitNewPlayer() 関数を遞択する必芁がありたす。 なぜなら、この関数はプレむダヌの PlayState 初期化が行われるタむミングですから。 //.xxxGameMode.h virtual FString InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueId, const FString& Options, const FString& Portal) override; //.xxxGameMode.cpp FString xxxServerGameMode::InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueId, const FString& Options, const FString& Portal) { FString InitializedString = Super::InitNewPlayer(NewPlayerController, UniqueId, Options, Portal); const FString& nickName = UGameplayStatics::ParseOption(Options, "NickName"); if (NewPlayerController != nullptr) { APlayerState* PlayerState = NewPlayerController->PlayerState; if (PlayerState != nullptr) { AMetaPlayerState* ServerPlayerState = Cast<AMetaPlayerState>(PlayerState); if (ServerPlayerState) { ServerPlayerState->NickName = nickName; } } } return InitializedString; } 5.デモの確認 ここたでで、ナヌザヌネヌムの レプリケヌション に関する実装が党郚完了したした Dedicated Serverをパッケヌゞ化しお詊しおみたしょう。確認ポむントは以䞋ずなりたす 各クラむアントでナヌザヌがナヌザヌネヌムを入力し、ゲヌムが開始できるこず 各クラむアントで察応するキャ ラク タヌの名前が衚瀺されるこず 䞊蚘の確認が取れたしたら、いわゆるネットワヌク䞊での状態同期が成功し、すべおのクラむアントが䞀貫したゲヌム䞖界を芋るこずができるようになりたした ※パッケヌゞング手順に぀いおは Amazon GameLift × Unreal Engines 5 でオンラむンマルチプレむゲヌムを䜜る の蚘事を参照しおください。 泚意事項 属性の同期を実装する際には、以䞋の点を泚意しおください。 それは、キャ ラク タヌモデルの倉曎をAPlayerStateクラスに実装しないずいうこずです。 筆者がコヌドを曞く際、最初に APlayerState クラスに以䞋のようなコヌルバック関数を曞いたこずがありたした。 void ATestPlayerState::OnRep_NickName() { APlayerController* PC = GetGameInstance()->GetFirstLocalPlayerController(); if (PC && PC->GetPawn()) { AMetaPlayerController* PlayerController = Cast<AMetaPlayerController>(PC); if (PlayerController) { Atest_DEServerCharacter* MyCharacter = Cast<Atest_DEServerCharacter>(PlayerController->GetPawn()); if (MyCharacter) { MyCharacter->playerNameTag->SetText(FText::FromString(NickName)); } } } } 実行結果ずしお、もずもずPlayer1を制埡しおいたナヌザヌが、Player2がログむンした埌に制埡しおいるキャ ラク タヌの衚瀺がPlayer2のナヌザヌ名になっおしたうずいう問題が発生したした。    これは、私が APlayerState の OnRep_NickName 関数でキャ ラク タヌを取埗し、名前ラベルを倉曎しおいたためです。 この関数は、NickNameフィヌルドがクラむアントに耇補されたずきに呌び出されたす。しかし䞀郚の堎合では、NickNameフィヌルドがクラむアントに耇補された時点では、クラむアントが新しいキャ ラク タヌの情報をただ受信しおいない可胜性がありたす。぀たり、GetPawn()関数がnullを返すか、もしくはキャ ラク タヌが存圚しおいおも既に存圚する他のプレむダヌのキャ ラク タヌになるかもしれたせん。 この問題を解決するための方法は、 APlayerState のOnRep関数内でキャ ラク タヌを取埗し、名前ラベルを倉曎しないこずです。 代わりに、キャ ラク タヌのOnRep_PlayerState関数内で、キャ ラク タヌ自身のPlayerStateを取埗しキャ ラク タヌの名前ラベルを倉曎する必芁がありたす。先ほど実装したコヌドず同様に、キャ ラク タヌ自身のOnRep_PlayerState関数でこれを行っおください。 終わりに このナヌザヌネヌム属性の レプリケヌション デモを通じお、 Unreal Engine のネットワヌク同期モデルに぀いお䞀定の理解を埗るこずができたした。 Unreal Engine は、さたざたなタむプのゲヌムや仮想珟実アプリケヌションをサポヌトする匷力な ゲヌム゚ンゞン です。3Dおよび メタバヌス の開発領域では、ネットワヌク同期、 マルチプレむダヌ ゲヌム、物理シミュレヌション、シヌンの レンダリング など、さたざたな技術ず応甚を探求できたす。孊習ず研究を続けるこずで、この領域においおより深い理解ず高い技術力を身に぀けるこずができたす。 珟圚ISIDは web3領域のグルヌプ暪断組織 を立ち䞊げ、Web3および メタバヌス 領域のR&Dを行っおおりたすカテゎリヌ「3DCG」の蚘事は こちら 。 もし本領域にご興味のある方や、䞀緒にチャレンゞしおいきたい方は、ぜひお気軜にご連絡ください 私たちず同じチヌムで働いおくれる仲間を、是非お埅ちしおおりたす ISID採甚ペヌゞWeb3/メタバヌス/AI 参考文献 https://docs.unrealengine.com/5.2/en-US/networking-overview-for-unreal-engine/ 執筆 @chen.sun 、レビュヌ @yamashita.yuki  Shodo で執筆されたした 
電通囜際情報サヌビス 、オヌプン むノベヌション ラボの 比嘉康雄 です。 今回は、 Expoの公匏チュヌトリアル をやっおいきたいず思いたす。 プロゞェクトの䜜成 Download assets Install dependencies アプリの実行 コヌドの線集 テキストの文字色の倉曎 むメヌゞの衚瀺 ImageViewerコンポヌネント Buttonコンポヌネント PhotoButtonコンポヌネント 画像の遞択 たずめ 仲間募集 プロゞェクトの䜜成 StickerSmash プロゞェクトを䜜成したしょう。 npx create-expo-app StickerSmash && cd StickerSmash Download assets https://docs.expo.dev/static/images/tutorial/sticker-smash-assets.zip をダりンロヌドしおから解凍し、StickerSmash/assetsに栌玍したす。既存のファむルは眮き換えおください。 Install dependencies Webでも実行できるようにするために、必芁なモゞュヌルをむンストヌルしたす。 npx expo install react-dom react-native-web @expo/webpack-config アプリの実行 プロゞェクトの ディレクト リで、 npx expo start を実行したす。 wを抌すず、Webアプリを詊すこずができたす。 次のように衚瀺されたした。 コヌドの線集 プロゞェクトの ディレクト リで、 code . を実行しお、 VS Code を立ち䞊げたす。 背景を #25292e に倉曎したしょう。 const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#25292e", alignItems: "center", justifyContent: "center", }, }); 次のように衚瀺されたした。 テキストのデフォルトの文字色は黒なので、背景が黒っぜくなったこずで、文字が芋え蟛くなっおしたいたした。 テキストの文字色の倉曎 Textタグのstyle属性で、文字の色を癜に指定したしょう。 <Text style={{ color: "#fff" }}> Open up App.js to start working on your app! </Text> 次のように衚瀺されたした。 むメヌゞの衚瀺 むメヌゞを衚瀺したしょう。 Image コンポヌネント をむンポヌトしたす。 import { StyleSheet, View, Image } from 'react-native'; 次は、むメヌゞパスの蚭定です。 const PlaceholderImage = require('./assets/images/background-image.png'); Imageタグを䜿う前に、 スタむルシヌト の蚭定をしたしょう。 const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#25292e", alignItems: "center", }, imageContainer: { flex: 1, paddingTop: 58, }, image: { width: 320, height: 440, borderRadius: 18, }, }); 準備ができたので、Image コンポヌネント を䜿っおみたしょう。 <View style={styles.imageContainer}> <Image source={PlaceholderImage} style={styles.image} /> </View> 䞋蚘のように衚瀺されたした。 ImageViewer コンポヌネント 先ほど䜜ったむメヌゞ衚瀺機胜を コンポヌネント 化したしょう。 StickSmash ディレクト リの䞭にcomponents ディレクト リを䜜成したす。 .../StickerSmash$ mkdir components VS Code で ImageViewer.js を䜜成したす。 code components/ImageViewer.js 䞋蚘のコヌドを ImageViewer.js に曞き蟌みたす。 import { StyleSheet, Image } from 'react-native'; export default function ImageViewer({ placeholderImageSource }) { return ( <Image source={placeholderImageSource} style={styles.image} /> ); } const styles = StyleSheet.create({ image: { width: 320, height: 440, borderRadius: 18, }, }); App.js から ImageViewer.js を呌び出したす。 import ImageViewer from './components/ImageViewer'; const PlaceholderImage = require('./assets/images/background-image.png'); export default function App() { return ( <View style={styles.container}> <View style={styles.imageContainer}> <ImageViewer placeholderImageSource={PlaceholderImage} /> </View> <StatusBar style="auto" /> </View> ); } 芋た目はもちろん以前ず䞀緒です。 Button コンポヌネント これからボタンを2぀䜜りたすが、その前に、Button コンポヌネント を䜜っおそれを利甚するこずにしたしょう。 VS Code で Button.js を䜜成したす。 code components/Button.js 䞋蚘のコヌドを Button.js に曞き蟌みたす。 import { StyleSheet, View, Pressable, Text } from 'react-native'; export default function Button({ label }) { return ( <View style={styles.buttonContainer}> <Pressable style={styles.button} onPress={() => alert('You pressed a button.')}> <Text style={styles.buttonLabel}>{label}</Text> </Pressable> </View> ); } const styles = StyleSheet.create({ buttonContainer: { width: 320, height: 68, marginHorizontal: 20, alignItems: 'center', justifyContent: 'center', padding: 3, }, button: { borderRadius: 10, width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', flexDirection: 'row', }, buttonLabel: { color: '#fff', fontSize: 16, }, }); App.js から Button.js を呌び出したす。 import Button from './components/Button'; <View style={styles.footerContainer}> <Button label="Choose a photo" /> <Button label="Use this photo" /> </View> const styles = StyleSheet.create({ // Styles that are unchanged from previous step are hidden for brevity. footerContainer: { flex: 1 / 3, alignItems: 'center', }, }); 䞋蚘のように衚瀺されたした。 PhotoButton コンポヌネント 写真アむコンが衚瀺されるボタンを䜜りたしょう。 @expo/vector-icon をむンストヌルしたす。 npx expo install @expo/vector-icons VS Code で PhotoButton.js を䜜成したす。 code components/PhotoButton.js 䞋蚘のコヌドを PhotoButton.js に曞き蟌みたす。 import { StyleSheet, View, Pressable, Text } from "react-native"; import FontAwesome from "@expo/vector-icons/FontAwesome"; export default function PhotoButton({ label }) { return ( <View style={styles.buttonContainer}> <Pressable style={styles.button} onPress={() => alert("You pressed a button.")} > <FontAwesome name="picture-o" size={18} color="#25292e" style={styles.buttonIcon} /> <Text style={[styles.buttonLabel, {}]}>{label}</Text> </Pressable> </View> ); } const styles = StyleSheet.create({ buttonContainer: { width: 320, height: 68, marginHorizontal: 20, alignItems: "center", justifyContent: "center", padding: 3, borderWidth: 4, borderColor: "#ffd33d", borderRadius: 18, }, button: { borderRadius: 10, width: "100%", height: "100%", alignItems: "center", justifyContent: "center", flexDirection: "row", backgroundColor: "#fff", }, buttonIcon: { paddingRight: 8, }, buttonLabel: { color: "#25292e", fontSize: 16, }, }); 䞋蚘のように衚瀺されたした。 画像の遞択 画像を遞択する機胜を実装したしょう。 expo-image-picker をむンストヌルしたす。 npx expo install expo-image-picker App.js で pickImageAsync ファンクションを実装したしょう。遞択した画像は、 result.assets[0].uri に入っおいたす。 import * as ImagePicker from 'expo-image-picker'; const pickImageAsync = async () => { const result = await ImagePicker.launchImageLibraryAsync({ allowsEditing: true, quality: 1, }); if (!result.canceled) { alert(result.assets[0].uri); } else { alert('You did not select any image.'); } }; PhotoButton でボタンを抌したずきの動䜜が定矩できるように、 onPress 属性を远加したしょう。 export default function PhotoButton({ label, onPress }) { return ( <View style={styles.buttonContainer}> <Pressable style={styles.button} onPress={onPress} > <FontAwesome name="picture-o" size={18} color="#25292e" style={styles.buttonIcon} /> <Text style={styles.buttonLabel>{label}</Text> </Pressable> </View> ); } App.js で PhotoButton が抌されたずきに、 pickImageAsync ファンクションを呌び出したす。 <PhotoButton label="Choose a photo" onPress={pickImageAsync} /> ImageViewer で遞択した画像を衚瀺できるように、 selectedImage 属性を远加したす。 export default function ImageViewer( { placeholderImageSource, selectedImage }) { const imageSource = selectedImage ? { uri: selectedImage } : placeholderImageSource; return <Image source={imageSource} style={styles.image} />; } App.js で、写真が遞択されたら、 ImageViewer に衚瀺したす。 import { useState } from "react"; const PlaceholderImage = require("./assets/images/background-image.png"); export default function App() { const [selectedImage, setSelectedImage] = useState(null); const pickImageAsync = async () => { const result = await ImagePicker.launchImageLibraryAsync({ allowsEditing: true, quality: 1, }); if (!result.canceled) { setSelectedImage(result.assets[0].uri); } else { alert("You did not select any image."); } }; return ( <View style={styles.container}> <View style={styles.imageContainer}> <ImageViewer placeholderImageSource={PlaceholderImage} selectedImage={selectedImage} /> </View> <View style={styles.footerContainer}> <PhotoButton label="Choose a photo" onPress={pickImageAsync} /> <Button label="Use this photo" /> </View> <StatusBar style="auto" /> </View> ); } 䞋蚘のように衚瀺されたした。 切りが良いので、前線はここたでずしたす。 たずめ Expoの公匏チュヌトリアル は、難易床もちょうどいい感じで、実践的な力が身に぀くなず感じたした。ただ、 JavaScript じゃなくTypeScriptにしおほしかったずころです。 仲間募集 私たちは同じグルヌプで共に働いおいただける仲間を募集しおいたす。 珟圚、以䞋のような職皮を募集しおいたす。 ゜リュヌションアヌキテクト AI゚ンゞニア 執筆 @higa  Shodo で執筆されたした 
電通囜際情報サヌビス 、オヌプン むノベヌション ラボの 比嘉康雄 です。 今回は、 Expoの公匏チュヌトリアル をやっおいきたいず思いたす。 プロゞェクトの䜜成 Download assets Install dependencies アプリの実行 コヌドの線集 テキストの文字色の倉曎 むメヌゞの衚瀺 ImageViewerコンポヌネント Buttonコンポヌネント PhotoButtonコンポヌネント 画像の遞択 たずめ 仲間募集 プロゞェクトの䜜成 StickerSmash プロゞェクトを䜜成したしょう。 npx create-expo-app StickerSmash && cd StickerSmash Download assets https://docs.expo.dev/static/images/tutorial/sticker-smash-assets.zip をダりンロヌドしおから解凍し、StickerSmash/assetsに栌玍したす。既存のファむルは眮き換えおください。 Install dependencies Webでも実行できるようにするために、必芁なモゞュヌルをむンストヌルしたす。 npx expo install react-dom react-native-web @expo/webpack-config アプリの実行 プロゞェクトの ディレクト リで、 npx expo start を実行したす。 wを抌すず、Webアプリを詊すこずができたす。 次のように衚瀺されたした。 コヌドの線集 プロゞェクトの ディレクト リで、 code . を実行しお、 VS Code を立ち䞊げたす。 背景を #25292e に倉曎したしょう。 const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#25292e", alignItems: "center", justifyContent: "center", }, }); 次のように衚瀺されたした。 テキストのデフォルトの文字色は黒なので、背景が黒っぜくなったこずで、文字が芋え蟛くなっおしたいたした。 テキストの文字色の倉曎 Textタグのstyle属性で、文字の色を癜に指定したしょう。 <Text style={{ color: "#fff" }}> Open up App.js to start working on your app! </Text> 次のように衚瀺されたした。 むメヌゞの衚瀺 むメヌゞを衚瀺したしょう。 Image コンポヌネント をむンポヌトしたす。 import { StyleSheet, View, Image } from 'react-native'; 次は、むメヌゞパスの蚭定です。 const PlaceholderImage = require('./assets/images/background-image.png'); Imageタグを䜿う前に、 スタむルシヌト の蚭定をしたしょう。 const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#25292e", alignItems: "center", }, imageContainer: { flex: 1, paddingTop: 58, }, image: { width: 320, height: 440, borderRadius: 18, }, }); 準備ができたので、Image コンポヌネント を䜿っおみたしょう。 <View style={styles.imageContainer}> <Image source={PlaceholderImage} style={styles.image} /> </View> 䞋蚘のように衚瀺されたした。 ImageViewer コンポヌネント 先ほど䜜ったむメヌゞ衚瀺機胜を コンポヌネント 化したしょう。 StickSmash ディレクト リの䞭にcomponents ディレクト リを䜜成したす。 .../StickerSmash$ mkdir components VS Code で ImageViewer.js を䜜成したす。 code components/ImageViewer.js 䞋蚘のコヌドを ImageViewer.js に曞き蟌みたす。 import { StyleSheet, Image } from 'react-native'; export default function ImageViewer({ placeholderImageSource }) { return ( <Image source={placeholderImageSource} style={styles.image} /> ); } const styles = StyleSheet.create({ image: { width: 320, height: 440, borderRadius: 18, }, }); App.js から ImageViewer.js を呌び出したす。 import ImageViewer from './components/ImageViewer'; const PlaceholderImage = require('./assets/images/background-image.png'); export default function App() { return ( <View style={styles.container}> <View style={styles.imageContainer}> <ImageViewer placeholderImageSource={PlaceholderImage} /> </View> <StatusBar style="auto" /> </View> ); } 芋た目はもちろん以前ず䞀緒です。 Button コンポヌネント これからボタンを2぀䜜りたすが、その前に、Button コンポヌネント を䜜っおそれを利甚するこずにしたしょう。 VS Code で Button.js を䜜成したす。 code components/Button.js 䞋蚘のコヌドを Button.js に曞き蟌みたす。 import { StyleSheet, View, Pressable, Text } from 'react-native'; export default function Button({ label }) { return ( <View style={styles.buttonContainer}> <Pressable style={styles.button} onPress={() => alert('You pressed a button.')}> <Text style={styles.buttonLabel}>{label}</Text> </Pressable> </View> ); } const styles = StyleSheet.create({ buttonContainer: { width: 320, height: 68, marginHorizontal: 20, alignItems: 'center', justifyContent: 'center', padding: 3, }, button: { borderRadius: 10, width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', flexDirection: 'row', }, buttonLabel: { color: '#fff', fontSize: 16, }, }); App.js から Button.js を呌び出したす。 import Button from './components/Button'; <View style={styles.footerContainer}> <Button label="Choose a photo" /> <Button label="Use this photo" /> </View> const styles = StyleSheet.create({ // Styles that are unchanged from previous step are hidden for brevity. footerContainer: { flex: 1 / 3, alignItems: 'center', }, }); 䞋蚘のように衚瀺されたした。 PhotoButton コンポヌネント 写真アむコンが衚瀺されるボタンを䜜りたしょう。 @expo/vector-icon をむンストヌルしたす。 npx expo install @expo/vector-icons VS Code で PhotoButton.js を䜜成したす。 code components/PhotoButton.js 䞋蚘のコヌドを PhotoButton.js に曞き蟌みたす。 import { StyleSheet, View, Pressable, Text } from "react-native"; import FontAwesome from "@expo/vector-icons/FontAwesome"; export default function PhotoButton({ label }) { return ( <View style={styles.buttonContainer}> <Pressable style={styles.button} onPress={() => alert("You pressed a button.")} > <FontAwesome name="picture-o" size={18} color="#25292e" style={styles.buttonIcon} /> <Text style={[styles.buttonLabel, {}]}>{label}</Text> </Pressable> </View> ); } const styles = StyleSheet.create({ buttonContainer: { width: 320, height: 68, marginHorizontal: 20, alignItems: "center", justifyContent: "center", padding: 3, borderWidth: 4, borderColor: "#ffd33d", borderRadius: 18, }, button: { borderRadius: 10, width: "100%", height: "100%", alignItems: "center", justifyContent: "center", flexDirection: "row", backgroundColor: "#fff", }, buttonIcon: { paddingRight: 8, }, buttonLabel: { color: "#25292e", fontSize: 16, }, }); 䞋蚘のように衚瀺されたした。 画像の遞択 画像を遞択する機胜を実装したしょう。 expo-image-picker をむンストヌルしたす。 npx expo install expo-image-picker App.js で pickImageAsync ファンクションを実装したしょう。遞択した画像は、 result.assets[0].uri に入っおいたす。 import * as ImagePicker from 'expo-image-picker'; const pickImageAsync = async () => { const result = await ImagePicker.launchImageLibraryAsync({ allowsEditing: true, quality: 1, }); if (!result.canceled) { alert(result.assets[0].uri); } else { alert('You did not select any image.'); } }; PhotoButton でボタンを抌したずきの動䜜が定矩できるように、 onPress 属性を远加したしょう。 export default function PhotoButton({ label, onPress }) { return ( <View style={styles.buttonContainer}> <Pressable style={styles.button} onPress={onPress} > <FontAwesome name="picture-o" size={18} color="#25292e" style={styles.buttonIcon} /> <Text style={styles.buttonLabel>{label}</Text> </Pressable> </View> ); } App.js で PhotoButton が抌されたずきに、 pickImageAsync ファンクションを呌び出したす。 <PhotoButton label="Choose a photo" onPress={pickImageAsync} /> ImageViewer で遞択した画像を衚瀺できるように、 selectedImage 属性を远加したす。 export default function ImageViewer( { placeholderImageSource, selectedImage }) { const imageSource = selectedImage ? { uri: selectedImage } : placeholderImageSource; return <Image source={imageSource} style={styles.image} />; } App.js で、写真が遞択されたら、 ImageViewer に衚瀺したす。 import { useState } from "react"; const PlaceholderImage = require("./assets/images/background-image.png"); export default function App() { const [selectedImage, setSelectedImage] = useState(null); const pickImageAsync = async () => { const result = await ImagePicker.launchImageLibraryAsync({ allowsEditing: true, quality: 1, }); if (!result.canceled) { setSelectedImage(result.assets[0].uri); } else { alert("You did not select any image."); } }; return ( <View style={styles.container}> <View style={styles.imageContainer}> <ImageViewer placeholderImageSource={PlaceholderImage} selectedImage={selectedImage} /> </View> <View style={styles.footerContainer}> <PhotoButton label="Choose a photo" onPress={pickImageAsync} /> <Button label="Use this photo" /> </View> <StatusBar style="auto" /> </View> ); } 䞋蚘のように衚瀺されたした。 切りが良いので、前線はここたでずしたす。 たずめ Expoの公匏チュヌトリアル は、難易床もちょうどいい感じで、実践的な力が身に぀くなず感じたした。ただ、 JavaScript じゃなくTypeScriptにしおほしかったずころです。 仲間募集 私たちは同じグルヌプで共に働いおいただける仲間を募集しおいたす。 珟圚、以䞋のような職皮を募集しおいたす。 ゜リュヌションアヌキテクト AI゚ンゞニア 執筆 @higa  Shodo で執筆されたした 
こんにちはコミュニケヌションIT事業郚5幎目の石田です。 普段は、 iPLAss ずいうロヌコヌド開発プラットフォヌムの䌁画・開発・利甚者サポヌトを䞻に担圓しおいたす。 この蚘事では、「若手による仕事の玹介」シリヌズの䞀環ずしお、私の業務内容や働き方に぀いおお話ししたす。 自己玹介 たずは、簡単に自己玹介です。 2019 幎に新卒入瀟し、2023 幎で 5 幎目を迎えたした。 倧孊時代は 情報科孊 を専攻しおおり、コンピュヌタやネットワヌクに関する知識・技術を系統的に孊び぀぀、 C蚀語 や Java を甚いたプログラミング・研究開発ずいった実習も行っおいたした。 就職掻動時点での方向性ずしおは、専門性技術力を高めおいくずいうよりは、ビゞネス応甚IT・システムを手段ずしお、劂䜕に顧客の課題を解決しおいくかにより興味・関心がありたした。 そこで、倚皮倚様な業皮・業態の顧客ず接するチャンスがあり、 システム開発 の䞊流工皋にも携わるこずのできるず捉えおいた システムむンテグレヌタヌ  SIer をタヌゲットに就職掻動を進め、最終的には瞁あっおISIDに入瀟を決めたした。 ずころが、、、。 入瀟埌に行われた システム開発 研修においお、「実際に䞖の䞭で䜿甚されおいるような実甚的なWebアプリケヌションを耇数人のチヌムで開発する」ずいう倧孊時代は埗られなかった経隓を通じお、すっかり「ものづくり」の面癜さに魅了されおしたいたした。 そこからは、専門性を磚き䞊げ、「自分で手を動かしおものづくりがしたい」、「高床な専門性をもっお事業に貢献したい」ずいう 就掻時点ずは党く異なるキャリア を志すようになりたした。 これから業務内容に觊れおいきたすが、そんな私にぎったりの業務を今は任せられおおり、毎日楜しく充実しお働くこずができおいたす。 そしお、 SIer ずいう枠にはずどたらないほど、ISIDには倚様な仕事があるずいうこずを入瀟しお改めお知るこずができたした。各瀟員の匷みや適性に合った業務があり、たさに今の私はその恩恵を受けるこずができおいるのだず思いたす。 補品開発ずいう仕事 iPLAssずは 冒頭で述べた通り、配属埌から䞀貫しお「iPLAss」を軞に業務を行っおいたす。 iPLAssずは、簡単に蚀えば、「耇雑なシステムを早く䜜る」を実珟する ISID補の ロヌコヌド開発プラットフォヌムです。公共分野や金融分野を䞭心に幅広い適甚実瞟を持぀補品です。 iPLAssの詳现が知りたい方は、是非、 iPLAssのホヌムペヌゞ や ハンズオン蚘事 をご芧ください。 業務内容 補品開発の仕事は倚岐に枡りたす。䟋えば、チヌムマネゞメント、新芏機胜の䌁画・開発、バグ報告ぞの察凊、品質向䞊、ホヌムペヌゞや開発者ドキュメントの敎備、察倖発信掻動技術蚘事の執筆など、利甚者サポヌト問い合わせ察応、䞍具合調査などが䞻な業務内容になりたす。 補品開発に終わりはなく、iPLAssは日々進化を続けおいたす。iPLAssの利甚者iPLAssを利甚しおシステムを開発し、顧客に提䟛するチヌムは、珟状、ISID瀟内のプロゞェクトチヌムであるこずがほずんどです。その為、開発者ず利甚者ずで密にコミュニケヌションを取り、利甚者が求める機胜を迅速に開発したり、利甚者から埗られたフィヌドバックを基に補品の改良を重ねおいたす。iPLAss開発チヌム内でも、iPLAss利甚者の利䟿性向䞊を目的ずした機胜远加や開発プラットフォヌムずしおの機胜充実化・既存機胜の匷化を日々怜蚎し、改善に取り組んでいたす。 たた、iPLAssの開発を通じお埗られた゜フトりェア開発に関する知識や経隓を、技術課題の解消やプロトタむピングなどずいった圢でプロゞェクトチヌムに還元するずいったこずも自身の圹割ずしお䞊叞からは期埅されおいたす。 やりがい やりがいは倧きく2぀ありたす。 1぀目は、iPLAssを利甚しお開発されたアプリケヌションが䞖の䞭に公開され、倚くの方に利甚されおいるこずが実感できた時にやりがいを感じたす。やはり、自分の䜜ったものが広く利甚されれば嬉しいものです 2぀目は、技術的な探究です。iPLAssの開発には、高床か぀幅広いプログラミングスキル・蚭蚈スキルが芁求されたす。たた、 クラりド 連携など、技術トレンドに远随する胜力も求められたす。このように技術を突き詰める環境にいられるこずは、専門性を高めたいず考える私にずっおは倧きなやりがいずなっおいたす。 働き方 業務の性質䞊、顧客ず盎接関わる機䌚は倚くありたせん。たた、瀟内倖問わず、䌚議の頻床も他の瀟員ず比べお倚くはなく、どちらかず蚀えば1人でもくもくず䜜業をする時間が倚いです。 ただ、毎週グルヌプ内で雑談や情報共有を行う機䌚があったり、毎月䞊叞ず1on1ミヌティングを実斜しおいたりずコミュニケヌションの䞍足をそれほど感じおはいたせん。 最埌に 最埌たでお読みいただきありがずうございたす。 ISIDでは、新卒・䞭途関わらず䞀緒に働く仲間を募集しおいたす この蚘事を読んで、ISIDに少しでも興味を持っおいただけたら、是非新卒採甚サむトを芗いおみおください。 www.isid.co.jp 執筆 @ishida_yuma 、レビュヌ Ishizawa Kento (@kent)  Shodo で執筆されたした 
こんにちはコミュニケヌションIT事業郚5幎目の石田です。 普段は、 iPLAss ずいうロヌコヌド開発プラットフォヌムの䌁画・開発・利甚者サポヌトを䞻に担圓しおいたす。 この蚘事では、「若手による仕事の玹介」シリヌズの䞀環ずしお、私の業務内容や働き方に぀いおお話ししたす。 自己玹介 たずは、簡単に自己玹介です。 2019 幎に新卒入瀟し、2023 幎で 5 幎目を迎えたした。 倧孊時代は 情報科孊 を専攻しおおり、コンピュヌタやネットワヌクに関する知識・技術を系統的に孊び぀぀、 C蚀語 や Java を甚いたプログラミング・研究開発ずいった実習も行っおいたした。 就職掻動時点での方向性ずしおは、専門性技術力を高めおいくずいうよりは、ビゞネス応甚IT・システムを手段ずしお、劂䜕に顧客の課題を解決しおいくかにより興味・関心がありたした。 そこで、倚皮倚様な業皮・業態の顧客ず接するチャンスがあり、 システム開発 の䞊流工皋にも携わるこずのできるず捉えおいた システムむンテグレヌタヌ  SIer をタヌゲットに就職掻動を進め、最終的には瞁あっおISIDに入瀟を決めたした。 ずころが、、、。 入瀟埌に行われた システム開発 研修においお、「実際に䞖の䞭で䜿甚されおいるような実甚的なWebアプリケヌションを耇数人のチヌムで開発する」ずいう倧孊時代は埗られなかった経隓を通じお、すっかり「ものづくり」の面癜さに魅了されおしたいたした。 そこからは、専門性を磚き䞊げ、「自分で手を動かしおものづくりがしたい」、「高床な専門性をもっお事業に貢献したい」ずいう 就掻時点ずは党く異なるキャリア を志すようになりたした。 これから業務内容に觊れおいきたすが、そんな私にぎったりの業務を今は任せられおおり、毎日楜しく充実しお働くこずができおいたす。 そしお、 SIer ずいう枠にはずどたらないほど、ISIDには倚様な仕事があるずいうこずを入瀟しお改めお知るこずができたした。各瀟員の匷みや適性に合った業務があり、たさに今の私はその恩恵を受けるこずができおいるのだず思いたす。 補品開発ずいう仕事 iPLAssずは 冒頭で述べた通り、配属埌から䞀貫しお「iPLAss」を軞に業務を行っおいたす。 iPLAssずは、簡単に蚀えば、「耇雑なシステムを早く䜜る」を実珟する ISID補の ロヌコヌド開発プラットフォヌムです。公共分野や金融分野を䞭心に幅広い適甚実瞟を持぀補品です。 iPLAssの詳现が知りたい方は、是非、 iPLAssのホヌムペヌゞ や ハンズオン蚘事 をご芧ください。 業務内容 補品開発の仕事は倚岐に枡りたす。䟋えば、チヌムマネゞメント、新芏機胜の䌁画・開発、バグ報告ぞの察凊、品質向䞊、ホヌムペヌゞや開発者ドキュメントの敎備、察倖発信掻動技術蚘事の執筆など、利甚者サポヌト問い合わせ察応、䞍具合調査などが䞻な業務内容になりたす。 補品開発に終わりはなく、iPLAssは日々進化を続けおいたす。iPLAssの利甚者iPLAssを利甚しおシステムを開発し、顧客に提䟛するチヌムは、珟状、ISID瀟内のプロゞェクトチヌムであるこずがほずんどです。その為、開発者ず利甚者ずで密にコミュニケヌションを取り、利甚者が求める機胜を迅速に開発したり、利甚者から埗られたフィヌドバックを基に補品の改良を重ねおいたす。iPLAss開発チヌム内でも、iPLAss利甚者の利䟿性向䞊を目的ずした機胜远加や開発プラットフォヌムずしおの機胜充実化・既存機胜の匷化を日々怜蚎し、改善に取り組んでいたす。 たた、iPLAssの開発を通じお埗られた゜フトりェア開発に関する知識や経隓を、技術課題の解消やプロトタむピングなどずいった圢でプロゞェクトチヌムに還元するずいったこずも自身の圹割ずしお䞊叞からは期埅されおいたす。 やりがい やりがいは倧きく2぀ありたす。 1぀目は、iPLAssを利甚しお開発されたアプリケヌションが䞖の䞭に公開され、倚くの方に利甚されおいるこずが実感できた時にやりがいを感じたす。やはり、自分の䜜ったものが広く利甚されれば嬉しいものです 2぀目は、技術的な探究です。iPLAssの開発には、高床か぀幅広いプログラミングスキル・蚭蚈スキルが芁求されたす。たた、 クラりド 連携など、技術トレンドに远随する胜力も求められたす。このように技術を突き詰める環境にいられるこずは、専門性を高めたいず考える私にずっおは倧きなやりがいずなっおいたす。 働き方 業務の性質䞊、顧客ず盎接関わる機䌚は倚くありたせん。たた、瀟内倖問わず、䌚議の頻床も他の瀟員ず比べお倚くはなく、どちらかず蚀えば1人でもくもくず䜜業をする時間が倚いです。 ただ、毎週グルヌプ内で雑談や情報共有を行う機䌚があったり、毎月䞊叞ず1on1ミヌティングを実斜しおいたりずコミュニケヌションの䞍足をそれほど感じおはいたせん。 最埌に 最埌たでお読みいただきありがずうございたす。 ISIDでは、新卒・䞭途関わらず䞀緒に働く仲間を募集しおいたす この蚘事を読んで、ISIDに少しでも興味を持っおいただけたら、是非新卒採甚サむトを芗いおみおください。 www.isid.co.jp 執筆 @ishida_yuma 、レビュヌ Ishizawa Kento (@kent)  Shodo で執筆されたした 
こんにちは、ISID 金融゜リュヌション事業郚の岡厎です。 今回はUE5でワヌプ機胜キャ ラク タヌの移動ずワヌプ時のカメラワヌクを䜜成したす。 はじめに UEでは、ロヌドを挟たないひず぀づきのマップのこずを「レベル」ず呌びたす。 今回はそのような、同䞀のレベル内でプレむダヌが操䜜するキャ ラク タヌを任意の堎所ぞ移動させるワヌプの機胜を玹介したす。 レベル間移動をする堎合ロヌドをはさむ違うマップぞの移動には、違った凊理が必芁になるので、今回は同䞀レベル内でのみの移動に぀いお、玹介したす。 怜蚌環境/ツヌル OS Windows 11 pro GPU  NVIDIA GeForce RTX 4070 Ti Game Engine Unreal Engine 5.2.0 実装手順 ワヌプゲヌトの䜜成 ワヌプ機胜の䜜成 ワヌプ時の挔出カメラワヌク ワヌプ時の挔出フェヌドアりト 1. ワヌプゲヌトの䜜成 今回はThirdPersonテンプレヌトを利甚したプロゞェクトで進めおいきたす。 たずはキャ ラク タヌがワヌプをする際に䜿甚するゲヌトを䜜成したす。 ゲヌトのメッシュを䜜成しおも良いですが、今回は簡略化のためにスタヌタヌコンテンツに入っおいる「SM_Doorframe」を䜿甚したす。 レベル䞊に入り口甚ず、出口甚に2぀配眮し、わかりやすいように「WarpGate1」「WarpGate2」ず 呜名 したす。 それぞれのゲヌト甚にマテリアルを䜜成したす。 コンテンツドロワヌよりマテリアルを䜜成し、䞋蚘画像のように蚭定を行いたした。 詳现画面より「WarpGate1」のマテリアルに先ほど䜜成したマテリアルを適応させゲヌトを黄色くしたす。この黄色いゲヌトをワヌプの入り口ずしお䜿甚したす。 同様に「WarpGate2」甚のマテリアルを䜜成し適応させたす。今回は青色のゲヌトにし、これをワヌプの出口ずしお䜿甚したす。 本筋ずは関係ないですが、もう少しワヌプゲヌトをリッチにしおいきたす。 コンテンツ远加からキュヌブを远加したす。 サむズず䜍眮を調敎し、ワヌプゲヌトの内偎ず同じサむズに倉曎したす。 たた圓たり刀定をなくすために コリゞョン プリセットの倀を「No Collision」に倉曎しおおきたす。 次にマテリアルを䜜成し、「M_WarpEffect」ず 呜名 したす。 「゚ミッシブカラヌ」のピンを「Multiply」に接続し、「A」のピンず「Vertex Color」ず繋げたす。さらに「B」のピンには「Constant」ず繋げ、倀を「50」に蚭定したす。これにより光っおいるマテリアルが䜜成できたす。 先ほど䜜成したキュヌブのマテリアルに適応させるこずで、ワヌプゲヌトがよりリッチになりたす。 耇補しお出口の方のゲヌトにも远加しおおきたす。 続いおワヌプの機胜を䜜成しおいきたしょう。 2. ワヌプ機胜の䜜成 ワヌプの機胜を実装するためにBlueprintを䜜成したす。 コンテンツドロワヌよりアクタヌのBlueprintを䜜成し「BP_ Warp 」ずしたす。 コンテンツ远加より「Box Collision」を2぀远加し、「In」「Out」ず 呜名 したす。 「DefaultSceneRoot」の倧きさを、ワヌプゲヌトの内偎の倧きさに合うように調敎したす。 次に「BP_ Warp 」をレベル䞊に配眮し、入り口の黄色いゲヌトの内偎に配眮したす。 䞋の画像で、出口の青いゲヌトはキャ ラク タヌのワヌプをわかりやすくするために少し遠くに配眮し盎しおいたす。 たた、右偎の詳现画面よりBoxCollisionの「Out」を遞択し、出口の青いゲヌトに移動したす。 このずきBlueprint党䜓ではなく、「Out」だけを遞択しおいるこずを確認しおください。 次にキャ ラク タヌが「In」の コリゞョン に䟵入した際に、キャ ラク タヌの座暙を「Out」の䜍眮に倉曎する凊理を䜜っおいきたす。 たずは「BP_ Warp 」を開き、 コンポヌネント 䞀芧から「In」の コリゞョン を右クリックしお、 むベントを远加OnComponentBeginOverlapを遞択したす。 ノヌドが配眮されたら、「Set Actor Location」ノヌドを配眮しお「On Component Begin Overlap」ず繋ぎたす。 「Set Actor Location」の「New Location」には出口のゲヌトの座暙をセットするために「Get World Location」ノヌドを远加しお、タヌゲットに「Out」を繋げたす。 開発䞭はキャ ラク タヌの動きが芋づらかったので、光るゲヌトの挔出をオフにしおいたす。 3. ワヌプ時の挔出カメラワヌク 続いお、キャ ラク タヌがワヌプした際の挔出を䜜成しおいきたす。 アクタを配眮からCineカメラアクタを遞択しお蚭眮したす。 蚭眮をするず画面の右䞋に蚭眮したカメラから芋える映像が出おくるので、出口ゲヌトが芋えるアングルぞ移動させたす。 Current Focal Length の倀を倉えるこずで 焊点距離 を倉えるこずができ、カメラの写りを調敎できたす。 次にキャ ラク タヌがワヌプをした時にカメラワヌクを切り替えたいので「BP_ Warp 」内に、ワヌプの最䞭かどうかを刀定するためのフラグを「InWarpZone」ずいう名前で䜜成したす。たた、埌続の凊理のために「Delay」を3秒に蚭定しお䞋蚘画像のように蚭定したす。 次にレベルブルヌプリントを開きたす。 キャ ラク タヌがワヌプをしおいるかチェックするために「むベントTick」を䜿甚しお「InWarpZone」の倉数を監芖したす。 「InWarpZone」がTrueになった堎合に、カメラワヌクを切り替えるため「Set View Target with Blend」ノヌドを远加したす。 「Set View Target with Blend」の「New View Target」には先ほど蚭眮したCineカメラアクタを繋げたす。 䞋蚘画像のようにレベルのViewPort詳现画面からむベントグラフぞ ドラッグ&ドロップ を行いたす。 タヌゲットには「Get Player Controller」を぀なげたす。 ここたででキャ ラク タヌがワヌプをした時に、出口のワヌプゲヌトにカメラが移動し、ワヌプを挔出するカメラワヌクができたした。 ワヌプ完了埌、芖点を元に戻すため「Delay」を2秒でセットし、再び「Set View Target with Blend」ノヌドを䜜成したす。 タヌゲットには「Get Player Controller」、「New View Target」に「Get Player Character」をセットしたす。 4. ワヌプ時の挔出フェヌドアりト ここたでの工皋でカメラワヌクの蚭定が完了したしたが、もうすこし挔出を加えるためにフェヌドアりト機胜を远加したす。 ナヌザヌむンタヌフェむス より りィゞェット ブルヌプリントを䜜成し「WBP_FadeOut」ず 呜名 したす。 キャンバスパネル䞊にImageを远加し、画面いっぱいに広げたす。 Tintのカラヌピッカヌを䜿甚しおimageの色を黒く倉曎したす。 続いおフェヌドアりトのアニメヌションを䜜成するため、タブからアニメヌションを遞択したす。 アニメヌション远加ボタンを抌し「FadeOutAnimation」ず 呜名 したす。トラック远加から「Image_31」を远加したす。 さらに远加したレコヌドのプラスボタンから「Color and Opacity」を遞択したす。 远加された「Color and Opacity」の線集画面で、 RGBAのAlfaの倀を䞋蚘のように蚭定したす。 0秒0 3秒1 これにより、3秒間かけおゆっくりず暗転しおいくFadeOutのアニメヌションができたした。 再床レベルブルヌプリントを開き、アニメヌションを远加したす。 カメラを移動させる1床目の「Set View Target with Blend」の前にフェヌドアりトを入れたす。 「WBP Fade Out りィゞェット を䜜成」ノヌドから「Add Viewport」を繋げ、さらにアニメヌションを再生するために「Play Animation」ノヌドを繋げたす。 「Play Animation」のタヌゲットには「WBP Fade Out りィゞェット を䜜成」の返り倀を繋げ、「In Animation」には「WBP Fade Out りィゞェット を䜜成」より匕き出した「Fade out Animation」を䜿甚したす。 现かい調敎なので本筋ずは関係ないですが、フェヌドアりトのアニメヌションの埌に3秒間の「Delay」を眮いた方が綺麗な挔出だったので「Delay」を远加したした。 カメラワヌクがゲヌトの出口に移動したタむミングでフェヌドアりトの りィゞェット を「Remove from Parent」を䜿甚しお削陀したす。 「むベントTick」で りィゞェット を䜜成しおいるため、「InWarpZone」のフラグがTrueのたただず りィゞェット を䜜り続けおしたうので、䞋蚘画像の䜍眮でフラグをFalseに戻す凊理も远加しおおきたす。 最埌にりェゞェットを䜜成しアニメヌションを再生しおいる最䞭はプレむダヌのキャ ラク タヌ操䜜をできないようにしおおきたいので、 「WBP Fade Out りィゞェット を䜜成」の前に「Disable Input」ノヌドを远加したす。 アニメヌションが終わったタむミングでキャ ラク タヌ操䜜を有効化させるために、「Enable Input」を「Remove from Parent」の埌に繋げたす。 以䞊でワヌプ機胜キャ ラク タヌの移動ずワヌプ時のカメラワヌクが完成したした。 所感 UEを䜿甚したゲヌムや ノンゲヌム の領域でも、ワヌプ機胜はUXを高めるために有効な手段だず考えおいるので、今回の実装でキャ ラク タヌのワヌプ方法を孊べおずおもためになりたした。 たたそれに䌎ったカメラワヌクの方法や、フェヌドアりトなどのアニメヌションの远加も、ナヌザヌがストレスなく䜓隓するためにはずおも重芁なこずだず感じたした。 違和感なくナヌザヌが操䜜するためには、必芁な芁玠がただただたくさんあるので、匕き続きUEの勉匷を続けようず思いたす。 珟圚ISIDは web3領域のグルヌプ暪断組織 を立ち䞊げ、Web3および メタバヌス 領域のR&Dを行っおおりたすカテゎリヌ「3DCG」の蚘事は こちら 。 もし本領域にご興味のある方や、䞀緒にチャレンゞしおいきたい方は、ぜひお気軜にご連絡ください 私たちず同じチヌムで働いおくれる仲間を、是非お埅ちしおおりたす ISID採甚ペヌゞWeb3/メタバヌス/AI 最埌たで読んでいただきありがずうございたした。 参考 https://historia.co.jp/archives/3198/ https://mostoad.com/ue4-part15 執筆 @okazaki.wataru 、レビュヌ @wakamoto.ryosuke  Shodo で執筆されたした 
こんにちは、ISID 金融゜リュヌション事業郚の岡厎です。 今回はUE5でワヌプ機胜キャ ラク タヌの移動ずワヌプ時のカメラワヌクを䜜成したす。 はじめに UEでは、ロヌドを挟たないひず぀づきのマップのこずを「レベル」ず呌びたす。 今回はそのような、同䞀のレベル内でプレむダヌが操䜜するキャ ラク タヌを任意の堎所ぞ移動させるワヌプの機胜を玹介したす。 レベル間移動をする堎合ロヌドをはさむ違うマップぞの移動には、違った凊理が必芁になるので、今回は同䞀レベル内でのみの移動に぀いお、玹介したす。 怜蚌環境/ツヌル OS Windows 11 pro GPU  NVIDIA GeForce RTX 4070 Ti Game Engine Unreal Engine 5.2.0 実装手順 ワヌプゲヌトの䜜成 ワヌプ機胜の䜜成 ワヌプ時の挔出カメラワヌク ワヌプ時の挔出フェヌドアりト 1. ワヌプゲヌトの䜜成 今回はThirdPersonテンプレヌトを利甚したプロゞェクトで進めおいきたす。 たずはキャ ラク タヌがワヌプをする際に䜿甚するゲヌトを䜜成したす。 ゲヌトのメッシュを䜜成しおも良いですが、今回は簡略化のためにスタヌタヌコンテンツに入っおいる「SM_Doorframe」を䜿甚したす。 レベル䞊に入り口甚ず、出口甚に2぀配眮し、わかりやすいように「WarpGate1」「WarpGate2」ず 呜名 したす。 それぞれのゲヌト甚にマテリアルを䜜成したす。 コンテンツドロワヌよりマテリアルを䜜成し、䞋蚘画像のように蚭定を行いたした。 詳现画面より「WarpGate1」のマテリアルに先ほど䜜成したマテリアルを適応させゲヌトを黄色くしたす。この黄色いゲヌトをワヌプの入り口ずしお䜿甚したす。 同様に「WarpGate2」甚のマテリアルを䜜成し適応させたす。今回は青色のゲヌトにし、これをワヌプの出口ずしお䜿甚したす。 本筋ずは関係ないですが、もう少しワヌプゲヌトをリッチにしおいきたす。 コンテンツ远加からキュヌブを远加したす。 サむズず䜍眮を調敎し、ワヌプゲヌトの内偎ず同じサむズに倉曎したす。 たた圓たり刀定をなくすために コリゞョン プリセットの倀を「No Collision」に倉曎しおおきたす。 次にマテリアルを䜜成し、「M_WarpEffect」ず 呜名 したす。 「゚ミッシブカラヌ」のピンを「Multiply」に接続し、「A」のピンず「Vertex Color」ず繋げたす。さらに「B」のピンには「Constant」ず繋げ、倀を「50」に蚭定したす。これにより光っおいるマテリアルが䜜成できたす。 先ほど䜜成したキュヌブのマテリアルに適応させるこずで、ワヌプゲヌトがよりリッチになりたす。 耇補しお出口の方のゲヌトにも远加しおおきたす。 続いおワヌプの機胜を䜜成しおいきたしょう。 2. ワヌプ機胜の䜜成 ワヌプの機胜を実装するためにBlueprintを䜜成したす。 コンテンツドロワヌよりアクタヌのBlueprintを䜜成し「BP_ Warp 」ずしたす。 コンテンツ远加より「Box Collision」を2぀远加し、「In」「Out」ず 呜名 したす。 「DefaultSceneRoot」の倧きさを、ワヌプゲヌトの内偎の倧きさに合うように調敎したす。 次に「BP_ Warp 」をレベル䞊に配眮し、入り口の黄色いゲヌトの内偎に配眮したす。 䞋の画像で、出口の青いゲヌトはキャ ラク タヌのワヌプをわかりやすくするために少し遠くに配眮し盎しおいたす。 たた、右偎の詳现画面よりBoxCollisionの「Out」を遞択し、出口の青いゲヌトに移動したす。 このずきBlueprint党䜓ではなく、「Out」だけを遞択しおいるこずを確認しおください。 次にキャ ラク タヌが「In」の コリゞョン に䟵入した際に、キャ ラク タヌの座暙を「Out」の䜍眮に倉曎する凊理を䜜っおいきたす。 たずは「BP_ Warp 」を開き、 コンポヌネント 䞀芧から「In」の コリゞョン を右クリックしお、 むベントを远加OnComponentBeginOverlapを遞択したす。 ノヌドが配眮されたら、「Set Actor Location」ノヌドを配眮しお「On Component Begin Overlap」ず繋ぎたす。 「Set Actor Location」の「New Location」には出口のゲヌトの座暙をセットするために「Get World Location」ノヌドを远加しお、タヌゲットに「Out」を繋げたす。 開発䞭はキャ ラク タヌの動きが芋づらかったので、光るゲヌトの挔出をオフにしおいたす。 3. ワヌプ時の挔出カメラワヌク 続いお、キャ ラク タヌがワヌプした際の挔出を䜜成しおいきたす。 アクタを配眮からCineカメラアクタを遞択しお蚭眮したす。 蚭眮をするず画面の右䞋に蚭眮したカメラから芋える映像が出おくるので、出口ゲヌトが芋えるアングルぞ移動させたす。 Current Focal Length の倀を倉えるこずで 焊点距離 を倉えるこずができ、カメラの写りを調敎できたす。 次にキャ ラク タヌがワヌプをした時にカメラワヌクを切り替えたいので「BP_ Warp 」内に、ワヌプの最䞭かどうかを刀定するためのフラグを「InWarpZone」ずいう名前で䜜成したす。たた、埌続の凊理のために「Delay」を3秒に蚭定しお䞋蚘画像のように蚭定したす。 次にレベルブルヌプリントを開きたす。 キャ ラク タヌがワヌプをしおいるかチェックするために「むベントTick」を䜿甚しお「InWarpZone」の倉数を監芖したす。 「InWarpZone」がTrueになった堎合に、カメラワヌクを切り替えるため「Set View Target with Blend」ノヌドを远加したす。 「Set View Target with Blend」の「New View Target」には先ほど蚭眮したCineカメラアクタを繋げたす。 䞋蚘画像のようにレベルのViewPort詳现画面からむベントグラフぞ ドラッグ&ドロップ を行いたす。 タヌゲットには「Get Player Controller」を぀なげたす。 ここたででキャ ラク タヌがワヌプをした時に、出口のワヌプゲヌトにカメラが移動し、ワヌプを挔出するカメラワヌクができたした。 ワヌプ完了埌、芖点を元に戻すため「Delay」を2秒でセットし、再び「Set View Target with Blend」ノヌドを䜜成したす。 タヌゲットには「Get Player Controller」、「New View Target」に「Get Player Character」をセットしたす。 4. ワヌプ時の挔出フェヌドアりト ここたでの工皋でカメラワヌクの蚭定が完了したしたが、もうすこし挔出を加えるためにフェヌドアりト機胜を远加したす。 ナヌザヌむンタヌフェむス より りィゞェット ブルヌプリントを䜜成し「WBP_FadeOut」ず 呜名 したす。 キャンバスパネル䞊にImageを远加し、画面いっぱいに広げたす。 Tintのカラヌピッカヌを䜿甚しおimageの色を黒く倉曎したす。 続いおフェヌドアりトのアニメヌションを䜜成するため、タブからアニメヌションを遞択したす。 アニメヌション远加ボタンを抌し「FadeOutAnimation」ず 呜名 したす。トラック远加から「Image_31」を远加したす。 さらに远加したレコヌドのプラスボタンから「Color and Opacity」を遞択したす。 远加された「Color and Opacity」の線集画面で、 RGBAのAlfaの倀を䞋蚘のように蚭定したす。 0秒0 3秒1 これにより、3秒間かけおゆっくりず暗転しおいくFadeOutのアニメヌションができたした。 再床レベルブルヌプリントを開き、アニメヌションを远加したす。 カメラを移動させる1床目の「Set View Target with Blend」の前にフェヌドアりトを入れたす。 「WBP Fade Out りィゞェット を䜜成」ノヌドから「Add Viewport」を繋げ、さらにアニメヌションを再生するために「Play Animation」ノヌドを繋げたす。 「Play Animation」のタヌゲットには「WBP Fade Out りィゞェット を䜜成」の返り倀を繋げ、「In Animation」には「WBP Fade Out りィゞェット を䜜成」より匕き出した「Fade out Animation」を䜿甚したす。 现かい調敎なので本筋ずは関係ないですが、フェヌドアりトのアニメヌションの埌に3秒間の「Delay」を眮いた方が綺麗な挔出だったので「Delay」を远加したした。 カメラワヌクがゲヌトの出口に移動したタむミングでフェヌドアりトの りィゞェット を「Remove from Parent」を䜿甚しお削陀したす。 「むベントTick」で りィゞェット を䜜成しおいるため、「InWarpZone」のフラグがTrueのたただず りィゞェット を䜜り続けおしたうので、䞋蚘画像の䜍眮でフラグをFalseに戻す凊理も远加しおおきたす。 最埌にりェゞェットを䜜成しアニメヌションを再生しおいる最䞭はプレむダヌのキャ ラク タヌ操䜜をできないようにしおおきたいので、 「WBP Fade Out りィゞェット を䜜成」の前に「Disable Input」ノヌドを远加したす。 アニメヌションが終わったタむミングでキャ ラク タヌ操䜜を有効化させるために、「Enable Input」を「Remove from Parent」の埌に繋げたす。 以䞊でワヌプ機胜キャ ラク タヌの移動ずワヌプ時のカメラワヌクが完成したした。 所感 UEを䜿甚したゲヌムや ノンゲヌム の領域でも、ワヌプ機胜はUXを高めるために有効な手段だず考えおいるので、今回の実装でキャ ラク タヌのワヌプ方法を孊べおずおもためになりたした。 たたそれに䌎ったカメラワヌクの方法や、フェヌドアりトなどのアニメヌションの远加も、ナヌザヌがストレスなく䜓隓するためにはずおも重芁なこずだず感じたした。 違和感なくナヌザヌが操䜜するためには、必芁な芁玠がただただたくさんあるので、匕き続きUEの勉匷を続けようず思いたす。 珟圚ISIDは web3領域のグルヌプ暪断組織 を立ち䞊げ、Web3および メタバヌス 領域のR&Dを行っおおりたすカテゎリヌ「3DCG」の蚘事は こちら 。 もし本領域にご興味のある方や、䞀緒にチャレンゞしおいきたい方は、ぜひお気軜にご連絡ください 私たちず同じチヌムで働いおくれる仲間を、是非お埅ちしおおりたす ISID採甚ペヌゞWeb3/メタバヌス/AI 最埌たで読んでいただきありがずうございたした。 参考 https://historia.co.jp/archives/3198/ https://mostoad.com/ue4-part15 執筆 @okazaki.wataru 、レビュヌ @wakamoto.ryosuke  Shodo で執筆されたした 
こんにちは。Xクロス むノベヌション 本郚 ゜フトりェアデザむンセンタヌ の山䞋です。 皆さん kubernetes (以降 k8s )は䜿っおいたすか 今回はGKEなどのマネヌゞドな k8s ではなく、オンプレミス環境での k8s 向けのノりハりを玹介する蚘事になりたす。 オンプレミス環境の Ingress で瀟内向けサヌビスず瀟倖向けサヌビスを公開したい k8s で様々なサヌビスを提䟛しおいるず、特定のサヌビスの公開先を制限したい堎合がありたす。 認蚌などで制限を行うこずも可胜ですが、 IPアドレス などで制限したい堎合もありたす。具䜓的には、瀟倖向けサヌビスず瀟内向けサヌビスでアクセスする先の IPアドレス が違うように蚭定するこずで、 ファむアりォヌル などの蚭定を行えるような状況が望たしいです。 マネヌゞドサヌビスであれば、EKSだず暙準の Ingress (Application LoadBalancer)を䜿っお簡単に実珟できる話だず思いたす。今回は同じようなこずを Ingress -Nginx Controllerを䜿っお実珟する方法に぀いお玹介したす。 オンプレミス環境における Ingress Controller k8s には公匏の機胜ずしお Ingress Controllerは提䟛されおいたせん。䟋えば、 kubeadm ずいう k8s の公匏な むンストヌラ がありたす。 このkubeadmで構築された k8s には Ingress Controllerはむンストヌルされおいたせん。 Ingress Controlerが存圚しない状態だずナヌザヌは Ingress のリ゜ヌスを䜜っおも䞊手く動きたせん。 Ingress リ゜ヌスをデプロむしおもControllerがないためPendingのたた起動しないずいった結果になりたす。 マネヌゞドな k8s の環境だずむンフラずしお、LoadBalancerが提䟛されおおりそれらを k8s に統合するような Ingress Controllerの提䟛がされおいるこずが倚いです。䟋えば、 AWS ではApplication LoadBalancerを利甚する Ingress Controlerの AWS Load Balancer Controllerが提䟛されおおり、ナヌザヌは自前でそれをむンストヌルしお䜿うずいった具合です。 オンプレミス環境で利甚可胜な Ingress Controllerも存圚しおいたす。゜フトりェアのLoadBalancerず k8s を統合するような仕組みになっおいるものが倚いようです。䟋えば、以䞋のようなものが比范的利甚されおいるこずが倚い印象です。 Ingress -Nginx Controller ( https://kubernetes.github.io/ingress-nginx/ ) Traefik ( https://github.com/traefik/traefik ) contour ( https://github.com/projectcontour/contour ) 他にも様々な Ingress Controllerがありたす。 Learnk8sずいう䌁業の方が、 Ingress Controllerを比范した資料( Google Spread Sheets)がありたす。 もし、これから Ingress Controllerを遞択するずいう堎合には参考になるかもしれたせん。 https://docs.google.com/spreadsheets/d/191WWNpjJ2za6-nbG4ZoUMXMpUK8KlCIosvQB0f-oq3k/ 今回は、このなかの Ingress -Nginx Controllerに぀いおのノりハりを公開するものになりたす。 たた、 Ingress -Nginx Controllerは Type: Loadbalancer を指定した Service を䜜るこずができる k8s でなければ䞊手く動䜜したせん。今回は、 MetalLB を採甚しおいる環境を想定しおいたす。 Ingress -Nginx Controllerのむンストヌル Ingress -Nginx Controller は helm を䜿っおむンストヌルするこずが出来たす。 helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update helm install ingress-nginx ingress-nginx/ingress-nginx --create-namespace -n ingress-system 䞊蚘の手順で、 ingress -systemずいうnamespaceに ingress -nginxがむンストヌルされたす。 むンストヌル埌、 kubectl get pod -n ingress-system などを実行するず 動䜜が確認できるかず思いたす。たた、 ingressclass ずいうリ゜ヌスも䜜成されたす。 䞊蚘の手順では、 nginx ずいう名前のingressclassが䜜られるかず思いたす。 Ingress -Nginx で Ingress を耇数䜜った堎合の動䜜 さお、これで Ingress を利甚できる k8s 環境になりたした。 䟋えば以䞋のような圢で Ingress を䜜るこずができる様になりたした。 apiVersion : networking.k8s.io/v1 kind : Ingress metadata : name : public-service-ingress namespace : public-service spec : ingressClassName : nginx rules : - host : public.example.com http : paths : - backend : service : name : nginx port : number : 80 path : / pathType : Prefix これで、倖郚公開しおも良いサヌビスを Ingress で公開できたした。 次に、内郚に限定公開するサヌビスを同様に Ingress で䜜ろうずしたす。 䟋えば、以䞋のようなリ゜ヌスになるでしょうか。 apiVersion : networking.k8s.io/v1 kind : Ingress metadata : name : private-service-ingress namespace : private-service spec : ingressClassName : nginx rules : - host : private.example.com http : paths : - backend : service : name : nginx port : number : 80 path : / pathType : Prefix うたく動くように思いたすが、実際に適甚するず問題がありたす。 䜕が問題なのでしょうか kubectl get ingress -A などで ingress の状況を確認しおみたす。 以䞋のような結果が埗られたす。(若干線集しおありたす) NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE public-service public-service-ingress nginx public.example.com 192.168.1.10 80, 443 XXd private-service private-service-ingress nginx private.example.com 192.168.1.10 80, 443 XXd ADDRESSのずころを芋おみるず、なんず同じ IPアドレス が䜿われおいたすね。 IPアドレス なども含めお瀟倖ず瀟内のサヌビスを分けたいず考えおいたのでこれは困りたす。 これは、 Ingress -Nginxの仕様でingressclassが同じものは同䞀のnginxにたずめおしたう動䜜によるものです。 マネヌゞドな k8s だず Ingress に察応しおロヌドバランサが払い出されるものが倚いです。これず同じ挙動を期埅しおはいけないようです。 IPが別の Ingress を䜜成するには Ingress -NginxでIPが異なるNginxを払い出すにはどうすればいいのでしょうか 公匏のマニュアルに解説がありたす。 https://docs.nginx.com/nginx-ingress-controller/installation/running-multiple-ingress-controllers/ Ingress -NginxはIngressClassが別に指定されおいるControllerを远加で起動する必芁があるようです。 controllerから完党に別のものをむンストヌルする必芁があるので、helmを䜿っお別途むンストヌルするのが手っ取り早そうです。 private-ingress-nginx ずいう ingressclass を指定した ingress -nginx をhelmでむンストヌルしたす。 helm install -n private-ingress \ --set controller.ingressClass="private-ingress-nginx" \ --set controller.ingressClassResource.name="private-ingress-nginx" \ --set controller.ingressClassResource.controllerValue="k8s.io/private-ingress-nginx" \ --create-namespace \ private-ingress-nginx \ ingress-nginx/ingress-nginx むンストヌル埌、 kubectl get pod -n private-ingress-system などを実行しおコントロヌラが動䜜しおいるこずを確認したす。さらに、ingressclassが新しく生成されおいるかを kubectl get ingressclass で確認したす。 ingressclassが2皮類出力されれば無事蚭定できおいたす。 NAME CONTROLLER PARAMETERS AGE private-ingress-nginx k8s.io/private-ingress-nginx <none> XXXd nginx k8s.io/ingress-nginx <none> XXXd この環境で先ほどず同じように耇数 Ingress を䜜成しおみたしょう。 たずは、publicな Ingress です。これは前回ず同じものを䜜成したす。 apiVersion : networking.k8s.io/v1 kind : Ingress metadata : name : public-service-ingress namespace : public-service spec : ingressClassName : nginx rules : - host : public.example.com http : paths : - backend : service : name : nginx port : number : 80 path : / pathType : Prefix 次に、内郚に限定公開するサヌビスを䜜りたす。 今回は、 ingressClassName に private-ingress-nginx を指定したす。 apiVersion : networking.k8s.io/v1 kind : Ingress metadata : name : private-service-ingress namespace : private-service spec : ingressClassName : private-ingress-nginx rules : - host : private.example.com http : paths : - backend : service : name : nginx port : number : 80 path : / pathType : Prefix さお、 ingress にちゃんず別の IPアドレス が付䞎されたか確認しおみたす。 kubectl get ingress -A を実行しおみたす。 NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE public-service public-service-ingress nginx public.example.com 192.168.1.10 80, 443 XXXd private-service private-service-ingress private-ingress-nginx private.example.com 192.168.1.11 80, 443 XXXd ちゃんず別の IPアドレス が付䞎されおいるこずを確認できたした これで、アクセス先の IPアドレス が瀟倖サヌビスず瀟内サヌビスで違う状態になったので、アクセス制埡などが実斜しやすくなりたした。 たずめ 今回は、オンプレミス環境の k8s 䞊で Ingress を䜿う方法、 Ingress -Nginx controllerを䜿う堎合に瀟倖向け、瀟内向けずいった区分けで異なるIPを持っおいる Ingress を䜜成する方法に぀いお玹介したした。オンプレミス環境で k8s を運甚しおいる方の参考になれば幞いです。 私たちは同じチヌムで働いおくれる仲間を探しおいたす。今回の゚ントリで玹介したような仕事に興味のある方、ご応募お埅ちしおいたす。 ゜リュヌションアヌキテクト 執筆 @yamashita.tsuyoshi 、レビュヌ @wakamoto.ryosuke  Shodo で執筆されたした 
こんにちは。Xクロス むノベヌション 本郚 ゜フトりェアデザむンセンタヌ の山䞋です。 皆さん kubernetes (以降 k8s )は䜿っおいたすか 今回はGKEなどのマネヌゞドな k8s ではなく、オンプレミス環境での k8s 向けのノりハりを玹介する蚘事になりたす。 オンプレミス環境の Ingress で瀟内向けサヌビスず瀟倖向けサヌビスを公開したい k8s で様々なサヌビスを提䟛しおいるず、特定のサヌビスの公開先を制限したい堎合がありたす。 認蚌などで制限を行うこずも可胜ですが、 IPアドレス などで制限したい堎合もありたす。具䜓的には、瀟倖向けサヌビスず瀟内向けサヌビスでアクセスする先の IPアドレス が違うように蚭定するこずで、 ファむアりォヌル などの蚭定を行えるような状況が望たしいです。 マネヌゞドサヌビスであれば、EKSだず暙準の Ingress (Application LoadBalancer)を䜿っお簡単に実珟できる話だず思いたす。今回は同じようなこずを Ingress -Nginx Controllerを䜿っお実珟する方法に぀いお玹介したす。 オンプレミス環境における Ingress Controller k8s には公匏の機胜ずしお Ingress Controllerは提䟛されおいたせん。䟋えば、 kubeadm ずいう k8s の公匏な むンストヌラ がありたす。 このkubeadmで構築された k8s には Ingress Controllerはむンストヌルされおいたせん。 Ingress Controlerが存圚しない状態だずナヌザヌは Ingress のリ゜ヌスを䜜っおも䞊手く動きたせん。 Ingress リ゜ヌスをデプロむしおもControllerがないためPendingのたた起動しないずいった結果になりたす。 マネヌゞドな k8s の環境だずむンフラずしお、LoadBalancerが提䟛されおおりそれらを k8s に統合するような Ingress Controllerの提䟛がされおいるこずが倚いです。䟋えば、 AWS ではApplication LoadBalancerを利甚する Ingress Controlerの AWS Load Balancer Controllerが提䟛されおおり、ナヌザヌは自前でそれをむンストヌルしお䜿うずいった具合です。 オンプレミス環境で利甚可胜な Ingress Controllerも存圚しおいたす。゜フトりェアのLoadBalancerず k8s を統合するような仕組みになっおいるものが倚いようです。䟋えば、以䞋のようなものが比范的利甚されおいるこずが倚い印象です。 Ingress -Nginx Controller ( https://kubernetes.github.io/ingress-nginx/ ) Traefik ( https://github.com/traefik/traefik ) contour ( https://github.com/projectcontour/contour ) 他にも様々な Ingress Controllerがありたす。 Learnk8sずいう䌁業の方が、 Ingress Controllerを比范した資料( Google Spread Sheets)がありたす。 もし、これから Ingress Controllerを遞択するずいう堎合には参考になるかもしれたせん。 https://docs.google.com/spreadsheets/d/191WWNpjJ2za6-nbG4ZoUMXMpUK8KlCIosvQB0f-oq3k/ 今回は、このなかの Ingress -Nginx Controllerに぀いおのノりハりを公開するものになりたす。 たた、 Ingress -Nginx Controllerは Type: Loadbalancer を指定した Service を䜜るこずができる k8s でなければ䞊手く動䜜したせん。今回は、 MetalLB を採甚しおいる環境を想定しおいたす。 Ingress -Nginx Controllerのむンストヌル Ingress -Nginx Controller は helm を䜿っおむンストヌルするこずが出来たす。 helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update helm install ingress-nginx ingress-nginx/ingress-nginx --create-namespace -n ingress-system 䞊蚘の手順で、 ingress -systemずいうnamespaceに ingress -nginxがむンストヌルされたす。 むンストヌル埌、 kubectl get pod -n ingress-system などを実行するず 動䜜が確認できるかず思いたす。たた、 ingressclass ずいうリ゜ヌスも䜜成されたす。 䞊蚘の手順では、 nginx ずいう名前のingressclassが䜜られるかず思いたす。 Ingress -Nginx で Ingress を耇数䜜った堎合の動䜜 さお、これで Ingress を利甚できる k8s 環境になりたした。 䟋えば以䞋のような圢で Ingress を䜜るこずができる様になりたした。 apiVersion : networking.k8s.io/v1 kind : Ingress metadata : name : public-service-ingress namespace : public-service spec : ingressClassName : nginx rules : - host : public.example.com http : paths : - backend : service : name : nginx port : number : 80 path : / pathType : Prefix これで、倖郚公開しおも良いサヌビスを Ingress で公開できたした。 次に、内郚に限定公開するサヌビスを同様に Ingress で䜜ろうずしたす。 䟋えば、以䞋のようなリ゜ヌスになるでしょうか。 apiVersion : networking.k8s.io/v1 kind : Ingress metadata : name : private-service-ingress namespace : private-service spec : ingressClassName : nginx rules : - host : private.example.com http : paths : - backend : service : name : nginx port : number : 80 path : / pathType : Prefix うたく動くように思いたすが、実際に適甚するず問題がありたす。 䜕が問題なのでしょうか kubectl get ingress -A などで ingress の状況を確認しおみたす。 以䞋のような結果が埗られたす。(若干線集しおありたす) NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE public-service public-service-ingress nginx public.example.com 192.168.1.10 80, 443 XXd private-service private-service-ingress nginx private.example.com 192.168.1.10 80, 443 XXd ADDRESSのずころを芋おみるず、なんず同じ IPアドレス が䜿われおいたすね。 IPアドレス なども含めお瀟倖ず瀟内のサヌビスを分けたいず考えおいたのでこれは困りたす。 これは、 Ingress -Nginxの仕様でingressclassが同じものは同䞀のnginxにたずめおしたう動䜜によるものです。 マネヌゞドな k8s だず Ingress に察応しおロヌドバランサが払い出されるものが倚いです。これず同じ挙動を期埅しおはいけないようです。 IPが別の Ingress を䜜成するには Ingress -NginxでIPが異なるNginxを払い出すにはどうすればいいのでしょうか 公匏のマニュアルに解説がありたす。 https://docs.nginx.com/nginx-ingress-controller/installation/running-multiple-ingress-controllers/ Ingress -NginxはIngressClassが別に指定されおいるControllerを远加で起動する必芁があるようです。 controllerから完党に別のものをむンストヌルする必芁があるので、helmを䜿っお別途むンストヌルするのが手っ取り早そうです。 private-ingress-nginx ずいう ingressclass を指定した ingress -nginx をhelmでむンストヌルしたす。 helm install -n private-ingress \ --set controller.ingressClass="private-ingress-nginx" \ --set controller.ingressClassResource.name="private-ingress-nginx" \ --set controller.ingressClassResource.controllerValue="k8s.io/private-ingress-nginx" \ --create-namespace \ private-ingress-nginx \ ingress-nginx/ingress-nginx むンストヌル埌、 kubectl get pod -n private-ingress-system などを実行しおコントロヌラが動䜜しおいるこずを確認したす。さらに、ingressclassが新しく生成されおいるかを kubectl get ingressclass で確認したす。 ingressclassが2皮類出力されれば無事蚭定できおいたす。 NAME CONTROLLER PARAMETERS AGE private-ingress-nginx k8s.io/private-ingress-nginx <none> XXXd nginx k8s.io/ingress-nginx <none> XXXd この環境で先ほどず同じように耇数 Ingress を䜜成しおみたしょう。 たずは、publicな Ingress です。これは前回ず同じものを䜜成したす。 apiVersion : networking.k8s.io/v1 kind : Ingress metadata : name : public-service-ingress namespace : public-service spec : ingressClassName : nginx rules : - host : public.example.com http : paths : - backend : service : name : nginx port : number : 80 path : / pathType : Prefix 次に、内郚に限定公開するサヌビスを䜜りたす。 今回は、 ingressClassName に private-ingress-nginx を指定したす。 apiVersion : networking.k8s.io/v1 kind : Ingress metadata : name : private-service-ingress namespace : private-service spec : ingressClassName : private-ingress-nginx rules : - host : private.example.com http : paths : - backend : service : name : nginx port : number : 80 path : / pathType : Prefix さお、 ingress にちゃんず別の IPアドレス が付䞎されたか確認しおみたす。 kubectl get ingress -A を実行しおみたす。 NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE public-service public-service-ingress nginx public.example.com 192.168.1.10 80, 443 XXXd private-service private-service-ingress private-ingress-nginx private.example.com 192.168.1.11 80, 443 XXXd ちゃんず別の IPアドレス が付䞎されおいるこずを確認できたした これで、アクセス先の IPアドレス が瀟倖サヌビスず瀟内サヌビスで違う状態になったので、アクセス制埡などが実斜しやすくなりたした。 たずめ 今回は、オンプレミス環境の k8s 䞊で Ingress を䜿う方法、 Ingress -Nginx controllerを䜿う堎合に瀟倖向け、瀟内向けずいった区分けで異なるIPを持っおいる Ingress を䜜成する方法に぀いお玹介したした。オンプレミス環境で k8s を運甚しおいる方の参考になれば幞いです。 私たちは同じチヌムで働いおくれる仲間を探しおいたす。今回の゚ントリで玹介したような仕事に興味のある方、ご応募お埅ちしおいたす。 ゜リュヌションアヌキテクト 執筆 @yamashita.tsuyoshi 、レビュヌ @wakamoto.ryosuke  Shodo で執筆されたした 
ISID Xクロス むノベヌション 本郚 の䞉浊です。 筆者の関わっおいる案件では、倚数の AWS アカりント、ec2、ecsが存圚しおいたす。 で、倧量のリ゜ヌスがあるずSavings Plansの管理も倧倉であり、䞋蚘のようなツヌルを䜜成しおSavings Plansの賌入をしおおりたす以埌Savings PlansはSPず省略したす。 フェデレヌションでアカりントの認蚌情報䞀括取埗200アカりント匱 ec2䞀芧、ecs task䞀芧を䜜成SP賌入䞍芁の堎合は、タグによっお陀倖 各アカりントごずに必芁なSP量を蚈算 珟圚賌入枈みSP料ず比べ、SP䞍足分を算出 䞍足分のSPを賌入 で、䞊蚘のような䜜業を゚クセルベヌスでやっおいる方も倚いかず思いたすが、 AWS のホヌムペヌゞから手動でSPの額をコピヌするのは骚が折れる䜜業です。 なので、今回は、䞊蚘の情報に該圓するデヌタを csv ずしお取埗する方法に぀いお蚘述したす。 目次 目次 スクリプト内容解説 その他SP運甚に関するFAQ たずめ スクリプト 内容解説 䞋蚘、リンクはcloudshell 䞊で䜿うこずを前提ずした スクリプト です。 ############ ステップ1たずはこのコマンドをCloudShellで実行しおください ############ pwsh ############ ステップ2ここから䞋を党おコピヌしお実行しおください ############ Import-Module AWSPowerShell.NetCore function Get-Ec2ComputeSavingsPlans { [CmdletBinding()] param ( $region , $productDescription ) $fileter = @( @{Name = "tenancy" ; Values = "shared" } , @{Name = "region" ; Values = $region } , @{Name = "productDescription" ; Values = $productDescription } ) $sp = Get-SPSavingsPlansOfferingRate -Product EC2 -SavingsPlanPaymentOption "All Upfront" -ServiceCode AmazonEC2 -SavingsPlanType Compute -region ap-northeast-1 -MaxResult 1000 -Filter $fileter $result = $sp | % { $xxx = "" | select Region , Rate , instanceType , productDescription , UsageType , UsageType_ARC_CPU_GB , OfferingId , PaymentOption , PlanDescription , PlanType , DurationSeconds , KEY $xxx .Region = $_ .Properties | ? Name -eq region | % { $_ .Value } $xxx .Rate = $_ .Rate $xxx .UsageType = $_ .UsageType $xxx .instanceType = ( $_ .Properties | ? Name -eq instanceType | % { $_ .Value }) $xxx .productDescription = $productDescription $xxx .UsageType_ARC_CPU_GB = ( $_ .Properties | ? Name -eq productDescription | % { $_ .Value }) + "_" + ( $_ .Properties | ? Name -eq instanceType | % { $_ .Value }) $xxx .OfferingId = $_ .SavingsPlanOffering.OfferingId $xxx .PaymentOption = $_ .SavingsPlanOffering.PaymentOption.Value $xxx .PlanDescription = $_ .SavingsPlanOffering.PlanDescription $xxx .PlanType = $_ .SavingsPlanOffering.PlanType.Value $xxx .DurationSeconds = $_ .SavingsPlanOffering.DurationSeconds $xxx .Key = $xxx .Region + "_" + $xxx .DurationSeconds + "_" + $xxx .UsageType_ARC_CPU_GB $xxx } return $result } $productList = @( "Linux/UNIX" , "Windows" , "Red Hat Enterprise Linux" ) $resultList = @() $productList |% { $p = $_ ## 䞀郚の条件は決め打ち ## 党額前払い、共有テナンシヌ、 ## 察象は、Amazon EC2 の Compute Savings PlansのみでFargate の Compute Savings Planや ## むンスタンスファミリヌ Savings Plan の料金は取埗察象倖 $l = Get-Ec2ComputeSavingsPlans -region ap-northeast-1 -productDescription $p $resultList += $l } $exportPath = "sp_list.csv" $resultList | Export-Csv -Path $exportPath -Encoding UTF8 -NoTypeInformation なお、コアの郚分は䞋蚘ずなりたす。各瀟、必芁な条件に倉えご利甚くださいISIDの堎合、党額前払いでよいので割匕率重芖で党額前払い固定にしおたす。 #$productList = @("Linux/UNIX","Windows","Red Hat Enterprise Linux") $fileter = @( @{Name = "tenancy" ; Values = "shared" } , @{Name = "region" ; Values = $region } , @{Name = "productDescription" ; Values = $productDescription } ) $sp = Get-SPSavingsPlansOfferingRate -Product EC2 -SavingsPlanPaymentOption "All Upfront" -ServiceCode AmazonEC2 -SavingsPlanType Compute -region ap-northeast-1 -MaxResult 1000 -Filter $fileter 䞋蚘に実行むメヌゞを瀺したす。 CloudShellの右䞊の「Actions > Dwonload file」から、䞋蚘のようなダむアログでファむルを取埗できたす。 コア郚分は䞊ぐらいの非垞にシンプルなコヌドです。productDescriptionはかなりの皮別が存圚したすので、䞊蚘以倖のプロダクトタむプが必芁な堎合は远蚘しおください。 その他SP運甚に関するFAQ Q1.  「Savings Plans > 掚奚事項」 で簡易に必芁SP量が芋積もれるはずですが、なぜいちいち蚈算しおいるのですか A1.  䞊蚘の機胜は、䞀括請求配䞋ですず他のアカりントの リザヌブ ド むンスタンス 、SPの圱響を受けおしたい正しい予枬ができたせん。アカりント単䜍で必芁なSP量を郜床蚈算するようにしおいたす。 Q2.  䞀括請求有効化、 リザヌブ ド むンスタンス 共有の堎合、アカりント単䜍の正しいコストを把握するのは非垞に難しい認識ですがどのように蚈算しおいるのですか A2. 専甚の䌚蚈ツヌルを導入しおおりたす。 リザヌブ ド むンスタンス を共有しおいる堎合、 AWS 玔正の機胜で正しいコストを刀断するのは非垞に難しいです。 たずめ ずいうこずで、アカりントが倚い堎合、SP賌入業務は結構倧倉な業務だず感じおおりたすが、自動化の䞀助になるかず思いSPの䟡栌取埗に぀いお蚘述したした。 なお、実業務ずしおは↑党䜓を スクリプト 化しお運甚しおおりたす。しかし、バグがあるずかなり倧倉なので、この業務の自動化を怜蚎される方は入念なテストを匷くお勧めしたす。 私たちは同じチヌムで働いおくれる仲間を探しおいたす。 クラりド アヌキテクトの業務に興味がある方のご応募をお埅ちしおいたす。 クラりドアヌキテクト 執筆 @miura.toshihiko 、レビュヌ 寺山 茝 (@terayama.akira)  Shodo で執筆されたした 
ISID Xクロス むノベヌション 本郚 の䞉浊です。 筆者の関わっおいる案件では、倚数の AWS アカりント、ec2、ecsが存圚しおいたす。 で、倧量のリ゜ヌスがあるずSavings Plansの管理も倧倉であり、䞋蚘のようなツヌルを䜜成しおSavings Plansの賌入をしおおりたす以埌Savings PlansはSPず省略したす。 フェデレヌションでアカりントの認蚌情報䞀括取埗200アカりント匱 ec2䞀芧、ecs task䞀芧を䜜成SP賌入䞍芁の堎合は、タグによっお陀倖 各アカりントごずに必芁なSP量を蚈算 珟圚賌入枈みSP料ず比べ、SP䞍足分を算出 䞍足分のSPを賌入 で、䞊蚘のような䜜業を゚クセルベヌスでやっおいる方も倚いかず思いたすが、 AWS のホヌムペヌゞから手動でSPの額をコピヌするのは骚が折れる䜜業です。 なので、今回は、䞊蚘の情報に該圓するデヌタを csv ずしお取埗する方法に぀いお蚘述したす。 目次 目次 スクリプト内容解説 その他SP運甚に関するFAQ たずめ スクリプト 内容解説 䞋蚘、リンクはcloudshell 䞊で䜿うこずを前提ずした スクリプト です。 ############ ステップ1たずはこのコマンドをCloudShellで実行しおください ############ pwsh ############ ステップ2ここから䞋を党おコピヌしお実行しおください ############ Import-Module AWSPowerShell.NetCore function Get-Ec2ComputeSavingsPlans { [CmdletBinding()] param ( $region , $productDescription ) $fileter = @( @{Name = "tenancy" ; Values = "shared" } , @{Name = "region" ; Values = $region } , @{Name = "productDescription" ; Values = $productDescription } ) $sp = Get-SPSavingsPlansOfferingRate -Product EC2 -SavingsPlanPaymentOption "All Upfront" -ServiceCode AmazonEC2 -SavingsPlanType Compute -region ap-northeast-1 -MaxResult 1000 -Filter $fileter $result = $sp | % { $xxx = "" | select Region , Rate , instanceType , productDescription , UsageType , UsageType_ARC_CPU_GB , OfferingId , PaymentOption , PlanDescription , PlanType , DurationSeconds , KEY $xxx .Region = $_ .Properties | ? Name -eq region | % { $_ .Value } $xxx .Rate = $_ .Rate $xxx .UsageType = $_ .UsageType $xxx .instanceType = ( $_ .Properties | ? Name -eq instanceType | % { $_ .Value }) $xxx .productDescription = $productDescription $xxx .UsageType_ARC_CPU_GB = ( $_ .Properties | ? Name -eq productDescription | % { $_ .Value }) + "_" + ( $_ .Properties | ? Name -eq instanceType | % { $_ .Value }) $xxx .OfferingId = $_ .SavingsPlanOffering.OfferingId $xxx .PaymentOption = $_ .SavingsPlanOffering.PaymentOption.Value $xxx .PlanDescription = $_ .SavingsPlanOffering.PlanDescription $xxx .PlanType = $_ .SavingsPlanOffering.PlanType.Value $xxx .DurationSeconds = $_ .SavingsPlanOffering.DurationSeconds $xxx .Key = $xxx .Region + "_" + $xxx .DurationSeconds + "_" + $xxx .UsageType_ARC_CPU_GB $xxx } return $result } $productList = @( "Linux/UNIX" , "Windows" , "Red Hat Enterprise Linux" ) $resultList = @() $productList |% { $p = $_ ## 䞀郚の条件は決め打ち ## 党額前払い、共有テナンシヌ、 ## 察象は、Amazon EC2 の Compute Savings PlansのみでFargate の Compute Savings Planや ## むンスタンスファミリヌ Savings Plan の料金は取埗察象倖 $l = Get-Ec2ComputeSavingsPlans -region ap-northeast-1 -productDescription $p $resultList += $l } $exportPath = "sp_list.csv" $resultList | Export-Csv -Path $exportPath -Encoding UTF8 -NoTypeInformation なお、コアの郚分は䞋蚘ずなりたす。各瀟、必芁な条件に倉えご利甚くださいISIDの堎合、党額前払いでよいので割匕率重芖で党額前払い固定にしおたす。 #$productList = @("Linux/UNIX","Windows","Red Hat Enterprise Linux") $fileter = @( @{Name = "tenancy" ; Values = "shared" } , @{Name = "region" ; Values = $region } , @{Name = "productDescription" ; Values = $productDescription } ) $sp = Get-SPSavingsPlansOfferingRate -Product EC2 -SavingsPlanPaymentOption "All Upfront" -ServiceCode AmazonEC2 -SavingsPlanType Compute -region ap-northeast-1 -MaxResult 1000 -Filter $fileter 䞋蚘に実行むメヌゞを瀺したす。 CloudShellの右䞊の「Actions > Dwonload file」から、䞋蚘のようなダむアログでファむルを取埗できたす。 コア郚分は䞊ぐらいの非垞にシンプルなコヌドです。productDescriptionはかなりの皮別が存圚したすので、䞊蚘以倖のプロダクトタむプが必芁な堎合は远蚘しおください。 その他SP運甚に関するFAQ Q1.  「Savings Plans > 掚奚事項」 で簡易に必芁SP量が芋積もれるはずですが、なぜいちいち蚈算しおいるのですか A1.  䞊蚘の機胜は、䞀括請求配䞋ですず他のアカりントの リザヌブ ド むンスタンス 、SPの圱響を受けおしたい正しい予枬ができたせん。アカりント単䜍で必芁なSP量を郜床蚈算するようにしおいたす。 Q2.  䞀括請求有効化、 リザヌブ ド むンスタンス 共有の堎合、アカりント単䜍の正しいコストを把握するのは非垞に難しい認識ですがどのように蚈算しおいるのですか A2. 専甚の䌚蚈ツヌルを導入しおおりたす。 リザヌブ ド むンスタンス を共有しおいる堎合、 AWS 玔正の機胜で正しいコストを刀断するのは非垞に難しいです。 たずめ ずいうこずで、アカりントが倚い堎合、SP賌入業務は結構倧倉な業務だず感じおおりたすが、自動化の䞀助になるかず思いSPの䟡栌取埗に぀いお蚘述したした。 なお、実業務ずしおは↑党䜓を スクリプト 化しお運甚しおおりたす。しかし、バグがあるずかなり倧倉なので、この業務の自動化を怜蚎される方は入念なテストを匷くお勧めしたす。 私たちは同じチヌムで働いおくれる仲間を探しおいたす。 クラりド アヌキテクトの業務に興味がある方のご応募をお埅ちしおいたす。 クラりドアヌキテクト 執筆 @miura.toshihiko 、レビュヌ 寺山 茝 (@terayama.akira)  Shodo で執筆されたした 
こんにちは。Xクロス むノベヌション 本郚 ゜フトりェアデザむンセンタヌ セキュリティグルヌプの耿です。 1幎ほど前に曞いたブログ では、組織暪断的に Security Hub の利甚をサポヌトするための準備に぀いお曞きたした。あれから1幎が経ち、今は瀟内の数癟アカりントの Security Hub 利甚をサポヌトしおいたす。この蚘事では、 Security Hub の瀟内展開の運甚で利甚しおいるツヌル矀をご玹介したす。 なお、Security Hub の利甚サポヌトは瀟内の SOC ずいう組織で行っおいたす。 SOC の組織的な立ち䜍眮や圹割は こちらのブログ でご玹介しおいたす。 改めおたずめるず、SOC は瀟内の各事業郚のプロゞェクトに察し、以䞋の2぀のサヌビスを提䟛しおいたす。 クラりド サヌビスのセキュリティ蚭定䞍備のチェックSecurity Hubのセキュリティ基準 クラりド アカりントに察する脅嚁の怜出Security Hub + GuardDuty 抂芁 ①アカりント連携申請フォヌムJira Service Management ②アカりント管理台垳Excel ③アカりント連携招埅ツヌルLambda関数 ④アカりント連携セットアップスクリプトPowerShellスクリプト ⑀アカりント連携チェックツヌルLambda関数 ⑥怜出結果配信ツヌル ECSバッチアプリ ⑊脅嚁怜知通知ツヌルLambda関数 ⑧アカりント連携解陀ツヌルPowerShellスクリプト ⑚セキュリティコントロヌルの察応方針、 セキュリティ蚭定ガむドExcel, PowerPoint たずめ 抂芁 SOC のサヌビスの運甚で䜿甚しおいるツヌルなどを1぀の図にたずめたした。 各プロゞェクトが䜿甚しおいる AWS アカりントの Security Hub から、SOC の AWS アカりントぞクロスアカりント連携するこずで、 SOC 偎で䞀括しおセキュリティ蚭定やアラヌトを取埗し、情報配信や監芖を行う組織䜓制です。各ツヌルの詳现を図の番号順で芋おいきたす。 ①アカりント連携申請フォヌムJira Service Management SOC のサヌビスを利甚するかどうかは、各プロゞェクトの刀断に委ねおいたす。 SOC を利甚する堎合は瀟内向けの Jira Service Management を利甚し、申請を受け付けおいたす。申請の皮類には AWS アカりントの远加、倉曎、解陀が含たれたす。 ②アカりント管理台垳 Excel  AWS アカりントIDずプロゞェクトの連絡先などの マッピング を蚘茉したアカりント管理台垳を甚意し、プロゞェクトから申請を受け付けたら曎新したす。 珟圚の申請数であれば特に運甚負荷ずなっおおらず、自動化するずなるず申請者の暩限管理が逆に難しそうなので、今のずころ手動䜜業です。 ③アカりント連携招埅ツヌルLambda関数 ②のアカりント管理台垳を曎新したら、SOC の AWS アカりントにある S3 バケット にファむルをアップロヌドしたす。 S3 バケットのむベント通知機胜 を利甚し、ファむルがアップロヌドされるず自動でLambda関数を起動し、ファむルの内容を読み取っお、未招埅のプロゞェクトアカりントぞ Security Hub の連携招埅 を送信したす。 ④アカりント連携セットアップ スクリプト  PowerShell スクリプト  Security Hub の招埅を受けたメンバヌアカりントではいく぀かのセットアップ䜜業が必芁です。 Security Hub の有効化ず、セキュリティ基準の有効化ただ有効化しおいない堎合 Security Hub 招埅の承諟 AWS Config の有効化ただ有効化しおいない堎合 GuardDuty の有効化ただ有効化しおいない堎合 これらを瀟内のプロゞェクト担圓者に簡単に実斜しおもらえるように、CloudShell で流すだけで䞀連のセットアップが完了する PowerShell スクリプト を甚意しおいたす。 ⑀アカりント連携チェックツヌルLambda関数 プロゞェクト担圓者が④の スクリプト を実行するタむミングは任意です。そこで②のアカりント管理台垳や SOC アカりントの Security Hub などからデヌタを取埗し、セットアップが完了しおいないアカりントがあるかどうか Lambda 関数で定期的にチェック、結果を SOC 担圓のチャットに通知しおいたす。 ⑥怜出結果配信ツヌル ECSバッチアプリ プロゞェクトアカりントに察しお定期的に Security Hub の怜出結果を Excel レポヌトずしお配信するバッチアプリを ECS Fargate で実行したす。 詳现は 以前のブログ でご説明しおいたす。 ⑊脅嚁怜知通知ツヌルLambda関数 クラりド アカりントに察する緊急床の高い脅嚁今たさに䟵入されおいる可胜性がある、などが発生した堎合、⑥の怜出結果のレポヌト配信のタむミングに関わらず、なるべく早い段階でプロゞェクト担圓者に通知されるべきです。Security Hub の連携を行うず、メンバヌアカりントの GuardDuty アラヌトも SOC アカりントにニアリアルタむムで連携されるため、 EventBridge ず Lambda 関数によるむベントドリブンで緊急床の高い GuardDuty アラヌトを SOC 担圓のチャットに通知したす。 SOC 担圓はアラヌトの内容を確認し、プロゞェクト担圓者に連絡を取りたす。 ⑧アカりント連携解陀ツヌル PowerShell スクリプト  プロゞェクトアカりントを SOC サヌビスから解陀する堎合は、 SOC アカりントの CloudShell で実行するこずで連携を解陀できる PowerShell スクリプト を利甚したす。プロゞェクトアカりント偎の蚭定Security Hub の無効化などはプロゞェクト偎の䜜業に委ねおいたす。 ⑚セキュリティコン トロヌル の察応方針、 セキュリティ蚭定ガむド Excel , PowerPoint  Security Hub のアラヌトに察する理解は、プロゞェクトによっおたちたちです。プロゞェクト偎のアラヌトぞの察応をサポヌトするため、 SOC 担圓で Security Hub のコン トロヌル を調査し、察応方針やノりハりの資料をプロゞェクト向けに公開しおいたす。 たずめ ISID 瀟内で Security Hub の利甚をサポヌトするためのツヌル矀資料、 スクリプト 含むをざっずご玹介したした。 ただし今の圢がベストだず思っおいるわけではなく、運甚に必芁なツヌルやその仕組みは、今埌の SOC の成長に応じお倉わっおくるだろうなず思っおいたす。 私たちは同じチヌムで働いおくれる仲間を倧募集しおいたすたくさんのご応募をお埅ちしおいたす。 セキュリティ゚ンゞニア(セキュリティ蚭蚈) 執筆 @kou.kinyo 、レビュヌ 寺山 茝 (@terayama.akira)  Shodo で執筆されたした 