🏘️

【VRChat】Unity初心者が2週間でワールドを公開した話

に公開

はじめに

VRChatで初めてワールドを公開しました。
本記事では、Unity初心者である私が、どのような経緯でワールド制作に至ったのか、公開までの過程、そして制作物について紹介します。

公開したワールドはこちら

https://vrchat.com/home/launch?worldId=wrld_4af42284-d314-4eab-b322-e89b399738f5


今回、サンプルワールドを基に改変・公開したワールド

筆者のスペック

ワールドのコンセプト決定や制作時間の参考に、スキルセットを簡単にまとめます。

  • VRChat
    • プレイ時間:2800時間以上
    • 主にVR睡眠(以下「V睡」)用途
  • Unity
    • アバターの改変が可能
    • 過去に2Dゲームを制作したことがあるが、知識はほぼ忘却
    • 3Dオブジェクトの扱いは完全初心者
  • Blender
    • 完全初心者
    • 今回の制作では利用しなかった
  • その他
    • Web系のプログラミングおよびインフラ構築が可能
VR睡眠とは?

ベッドや布団が設置されたワールドで、VRゴーグルを装着したまま就寝する行為。
健康に悪い。
本記事では「V睡」と略します。


実際の体はゴーグルをつけたまま朝まで寝ている

どんなワールドを作るのか?

VRChatを長くプレイし、そろそろクリエイター側に回りたいなあと思っていた矢先に、長期間の休みが突然降ってきたためワールド制作に挑戦してみることにしました。
そこで、今回は以下の方針でワールド制作を進めることにしました。

  • 制作期間は2週間以内
    • 色々タイミングが重なり、偶然出現した長期休み(4月下旬+GW)を活用し、技術キャッチアップと開発を含めて、短期間で完成させる。
      • ->販売されているサンプルワールドを基に制作する
  • V睡に利用可能
    • 私のVRChatの利用目的の大半が「V睡」であり、自分が実際に使いたくなることが必須条件。
  • 独自機能の実装
    • 販売されている既存のワールドを基として開発するので、未販売の独自機能を追加したい。

独自機能について

前述の通り私はモデリングのスキルがないため、自分の得意分野であるWebアプリ開発を基にAPIを軸に工夫することにしました。具体的には、独自に制作したAPIから情報を取得し、それをVRChatのワールド内で掲示板のような形式で表示するという機能です。

さらに、私は普段あまりニュースをチェックしない生活を送っており、世界情勢にも疎い状態でした。
そこで、「最新ニュースが一目で分かるアセット」をワールドに組み込もうと考えました。

つまりこのワールドの独自機能について、以下の2点に取り組みました。

  • 世界の最新のニュースを取得できる独自APIの開発
  • APIから取得したニュースをワールド内に表示する仕組みの実装
APIとは?

APIとは?

API(エーピーアイ)は「Application Programming Interface(アプリケーション・プログラミング・インターフェース)」の略で、「決められた質問を送ると、決められた答えが返ってくる仕組み」です。


実際のAPIの例

クリックすると、WebブラウザでAPIからのレスポンス結果が表示されます(クリックがAPIへのリクエスト)。

1. 郵便番号API(日本の住所情報を取得)

郵便番号から住所を調べるAPI:
https://zipcloud.ibsnet.co.jp/api/search?zipcode=1000001

→ 東京都千代田区千代田の情報が取得できます。

2. 天気API(世界の天気)

Open-Meteo:
https://api.open-meteo.com/v1/forecast?latitude=35.6812&longitude=139.7671&current_weather=true

→ 東京駅(緯度35.6812, 経度139.7671)の現在の天気情報が取得できます。

独自機能の作成

ワールド内に、世界情勢に関するニュースを約5件表示する機能を実装しました。

この実現のために行ったことは以下のとおりです:

  • API作成
    • 外部のニュースAPIから最新情報を取得
    • 生成AIで重要なニュースを抽出・要約・日本語化し保存
    • VRChatから要約したニュースを取得できる機能の実装
  • VRChatワールド内に表示するための掲示板アセットの作成

API実装

アーキテクチャ

サーバーレス構成で実装し、使用するクラウドは慣れ親しんだAWSを選択しました。
構築にあたり、IaCとしてAWS Serverless Application Modelを用いました。


ニュース生成〜取得までのデータフローと構成図

ニュース取得元:The New York Times API

無料で世界の最新のニュースを取得できるサービスとしてThe New York Timesの公開しているAPI(NYT)を選択しました。商用利用はできません
ニュースを得ることができるサービスは複数あるのですが、無料利用の場合、最新のニュースを得ることができるサービスはごくわずかでした(というより、国内ニュース、世界のニュース含めThe New York Times以外見つからなかった)。

The New York TimesのAPIはHPに掲示されている情報を取得できます

HPから閲覧できる情報

APIから取得できる情報

HPで表示されているデータが得られる

{
    "status": "OK",
    "copyright": "Copyright (c) 2025 The New York Times Company. All Rights Reserved.",
    "section": "World News",
    "last_updated": "2025-05-05T06:34:41-04:00",
    "num_results": 37,
    "results": [
        {
            "title": "A New Trend in Global Elections: The Anti-Trump Bump",
            "abstract": "In voting in Canada and Australia, right-wing parties that borrowed from the MAGA playbook were punished. Elsewhere, President Trump is having a more complex impact.",
            "url": "https://www.nytimes.com/2025/05/04/world/canada/global-elections-trump.html",
            "byline": "By Matina Stevis-Gridneff",
            "published_date": "2025-05-04T19:34:52-04:00"
        },
        {
            "title": "Australia’s Election Wasn’t About Trump. An Anti-Trump Wave Swept It Anyway.",
            "abstract": "The global turmoil wreaked by President Trump’s policies made him a factor in the election, bolstering the re-election of Prime Minister Anthony Albanese.",
            "url": "https://www.nytimes.com/2025/05/04/world/australia/albanese-labor-election-trump.html",
            "byline": "By Victoria Kim and Yan Zhuang",
            "published_date": "2025-05-04T05:51:05-04:00"
        },
        {
            "title": "Netanyahu Says Pounding Gaza Again Will Finish Hamas. Not Everyone Agrees.",
            "abstract": "It is not clear how the Israeli prime minister’s plan to add tens of thousands of soldiers will fundamentally alter a dynamic seen over 18 months of conflict.",
            "url": "https://www.nytimes.com/2025/05/05/world/europe/israel-buildup-soldiers-hamas-gaza.html",
            "byline": "By Michael D. Shear",
            "published_date": "2025-05-05T06:11:26-04:00"
        },
        {
            "title": "China’s Garment Factories Face a Tipping Point After New Tariffs",
            "abstract": "As a U.S. tax loophole ends, the apparel makers that sell to America are forced to consider alternative markets or cheaper locations in and outside China.",
            "url": "https://www.nytimes.com/2025/05/05/business/china-tariffs-de-minimis-guangzhou.html",
            "byline": "By Meaghan Tobin",
            "published_date": "2025-05-05T00:01:07-04:00"
        },
        {
            "title": "Bombed by Russia, Odesa Now Wages a Cultural Battle",
            "abstract": "A push to rename streets and remove statues associated with imperial Russia is dividing Odesa, whose identity is tied up in its history.",
            "url": "https://www.nytimes.com/2025/05/05/world/europe/odesa-ukraine-russia-culture.html",
            "byline": "By Constant Méheut and Daria Mitiuk",
            "published_date": "2025-05-05T05:00:30-04:00"
        },
        ...
    ]
}

ニュース作成(Lambda)

FaaSであるLambdaを用い、The New York Times(NYT)から12時間毎にニュースを取得しAI SDKとBedrockを用いてニュースを要約し、DynamoDBに保存しました。

ニュース要約

NYTから取得できるニュースは英語であり、そのまま文章をVRChatのワールドに公開するのは不便でした。そこで、LLM(大規模言語モデル, ChatGPTみたいなやつ)利用サービスであるBedrockを用い、NYTから取得した多くの英語ニュースを基に(1)重大なニュースを5件ピックアップすること, (2)ニュースを適切な分量で日本語に要約することを行いました。
構造化データとしてLLMの生成結果を取得したかったのでAI SDKを用い整形しました(参考1, 参考2)。

AWS Bedrockによるニュース要約例

[
  {
    "title": "米中貿易戦争、交渉の見通し立たず",
    "content": "米中間の貿易戦争が長期化の様相。交渉条件や交渉の有無をめぐり両国が対立し、経済的な闘いが続く見通し。フェンタニル規制を中国側が交渉カードとして利用する可能性も。",
    "published_date": "2025-05-02",
    "created_at": "2025-05-05T09:00:34.514Z"
  },
  {
    "title": "印パ緊張、カシミールで再燃",
    "content": "4月22日のカシミールでのテロ攻撃により、インドとパキスタンの長年の対立が再燃。軍事衝突の可能性が高まっている。パキスタン軍トップも強硬姿勢を示し、事態は予断を許さない状況だ。",
    "published_date": "2025-05-05",
    "created_at": "2025-05-05T09:00:34.514Z"
  }
   ...
]
プロンプト

あまりこだわってませんが参考までに。
LLMのモデルはClaude Sonnet 3.5、${articleStrings}にはNYTから取得した英語の記事一覧(30個程度)が代入されます。

<input>
${articleStrings}
</input>

<instructions>
あなたは優秀なニュースエディターです。与えられた情報源から、世界の重要なニュースを要約・編集する専門家として振る舞ってください。

以下のタスクを実行してください:
1. <input>タグ内に提供されたニュース情報を分析してください
2. 世界中から最も重要かつ注目すべき5件のニュースを選定してください
3. 各ニュースについて、以下の形式で構成してください:
   - title: 全角22文字以内で簡潔に
   - content: 全角108文字以内で簡潔に
   - published_date: 発行日を "yyyy-MM-dd" 形式で記述
4. 内容は自然な日本語で、読者が世界情勢を効率的に把握できるよう構成してください
5. 地政学、経済、社会問題など様々な分野から、バランスよく選定してください
6. 最終的な成果物は厳密に指定されたJSON形式で出力してください

特に以下の点に注意してください:
- 事実に基づいた報道を心がけ、誇張や偏りのない中立的な表現を使用すること
- 複雑な問題も理解しやすく説明すること
- 地域的な偏りがないよう、多様な地域からのニュースを含めること
- グローバルな視点で重要性の高いニュースを優先すること
</instructions>

<strict_rules>
- 先頭にも末尾にも説明文やコードブロック記号を付けず、JSONだけを返してください
- content字段内で改行が必要な場合は "\n" としてエスケープしてください(例: "○○○○\\n△△△△")
- articles配列は必ず5要素を含めてください
</strict_rules>

ニュースの保存(DynamoDB)

生成したニュースはNoSQL データベースサービスであるDynamoDBに保存しています。
RDSなどのリレーショナルDBに比べ、インスタンス料金が発生せず、使用量に応じた課金のためコスト効率が良いです。
また、データ取得の効率性を考慮し、グローバルセカンダリインデックスをニュース生成日をインデックスキーとして設定し、最新のニュースを日付順で取得できるようにしています。

ニュース取得(Lambda)

API Gatewayを介し、DynamoDBから最新のデータを取得しリクエスト元に返す機能です。

アセット作成

Unity上で、UdonSharp を用いて「APIから最新ニュースを取得し表示する掲示板」を作成しました。

学習

Unityで本格的にオブジェクトを制作するのは今回が初めてだったので、基礎から勉強して実装に取り組みました。

Boothに販売されていた以下の教材を参考にしました。:

今回の実装では、Unityでの3Dオブジェクトの扱い方というよりは、UdonSharp周りについての理解が必要であり、この教材はその内容についてプログラミング初心者でも理解できる記述で説明があり最適でした。

実装

APIからの最新ニュース取得についてはString Loading を用いました。
CursorはUdonSharpについてもコード補完してくれるし、ChatGPTはUnityの分からない箇所についてスクショと共に質問したらそれなりの精度で回答が返ってくるので素晴らしいです。

出来上がったアセットがこちら


実際にワールドに配置した最新ニュース掲示板

ワールド制作

前述のようにモデリングは全然できないので、Boothに販売されているサンプルワールドを購入し、そのワールドに必要なアセットを配置することでワールド制作を行いました。(制作というか改変ですが、本記事では制作という単語で統一して記載いたします)

学習

制作に際して、新たにlightingやcolliderについて学習が必要だったので、こちらもboothにて販売されていた以下の教材を参考に学びました。:

ワールド制作時に設定する項目や手順についての基本的な説明が記載されています。
調整するパラメータの把握に大いに役立ちました。無料の教材です。すごい。

制作

ワールドの基本なアセット、V睡に必要なアセットの配置、実装した独自機能の組み込みを行いました。ワールドの基本的なアセットはこの記事を参考に見繕いました。追加した家具はUnity Asset Storeで見繕いました。
新たなアセットを配置する際には、ライティング回りの設定にとても躓きました。しかし、それを除けばプレハブを配置するだけなのですごく簡単です。ミラーやコライダーの新規追加もとても簡単にできました。

本当はGitHubで管理したかったのですが、今回限りだし、Unityのファイル理解ができていない状態で走り始めてしまったのでとりあえず定期的なコミットだけでお茶を濁してました。
UnityがGit管理できるのを今回初めて知りました。

light bakeの設定で参考にしたサイト
Git管理で参考にしたサイト

完成! 街角の安らぎ ~Urban Lounge~

最終的にこのようなワールドになりました。
毎晩テストや使い心地を確認しながらV睡をし、満足のいくワールドとなりました。
独自機能として設置したニュース掲示板は日本時間で6時10分と18時10分に更新されます。

まとめ

本記事では、Unity初心者がVRChatのワールド制作を2週間で行い、その過程や制作物について紹介しました。Booth等に販売されている既存ワールドに既存のアセットを組み込んで公開するだけなら、多くのVRChatterは少ない学習コストで公開できると感じました。皆さんも是非トライしてみてください!
自分のお気に入りの絵画や音楽をワールドに設定できるのは凄く良いですよ!
また、フレンドから生の感想聞けるのは凄くモチベーション維持になりました。ありがとうございました。

ありがとうAI

結局最後まで光源系やUdonSharpは分からないことが沢山ありましたが、だいたいChatGPTやCursorが解決してくれました(ワールド制作を継続的に行う予定は無いし、チーム開発をする気も無かったので、じっくり理解するより完成させることを優先しました)。

Unityが分からなさ過ぎて、トラブルシューティングに際してそもそも解決の方針すら立っていない際に調べる項目のきっかけとしてとても役に立ちました。この期間で公開までこぎつけることができたのはAIのおかげだと思います。

ChatGPTにスクショと共に質問を投げかけている図

具体的なスケジュールやコスト

スケジュール

  • ニュース生成APIは構想が具体的に固まっていたので、短い期間で実装できました。
  • ワールド制作はコンセプトがフンワリしたまま4/25から制作開始し、サンプルワールドを探しながら学習し、かなり時間がかかりました。
  • 毎日平均6時間は作業しているので、4/21-5/3で80時間くらいワールド制作に充てています。

コスト

  • Boothでの教材・アセット購入費: 5000円
  • API維持費: $ 0.05/day
    • APIをAWSでサービス維持するために必要な費用
    • 大部分が生成AIの利用料金
    • API Gateway, Lambda, DynamoDBについてはほぼコストは掛かっていない

Assets

商品名 作者(敬称略)
【VRChat向け販売ワールド】AXU_s_Room 園田交通局
ベッドギミックこれだけでOK!多機能タブレット搭載【セーブ対応】 らずべりー工房(はるる早苗)
【VRChat】YamaPlayer - VRChat向け動画プレイヤー【Video Player】 yamadev
どこでもアニメーションシステム【VRChat】【ワールドギミック】 のりたま直販所
[VRCSDK3] Visitors Information Board ちくわ屋
Lura's Switch【VCC/Persistence】 QuickBrown Design Studio
デジタル時計【VCC対応】 MIKI House VR
Chair and Sofa set Geniuscrate Games
Polaroid Camera for Vrchat World Fairplex Shop
QvPen Package Shop @aivrc
QVSmartPen Mofcosmos
Nike Goddess of Victory statue Free low-poly 3D model bripocubes
Fragrance tachibana muou

Discussion