Community画像github.com

g0shtj0sh/fivem-vehicle-to-roblox

FiveM / GTA Vの車両(.yft/.ytd/.meta/.awc付きZIPまたはリソースフォルダ、dlc.rpf、CodeWalker XML出力)を、Robloxで完全に動作する車両に変換します。Roblox StudioがMCP経由で接続されている場合は、自動でインストール・検証まで行います。

fivem-vehicle-to-roblox とは?

このスキルは、FiveM / GTA Vの車両ファイル(ZIPやリソースフォルダ)を、Robloxで即座に使用可能な状態に変換するためのものです。3Dモデルを部品ごとに分割し、テクスチャ、ホイール、可動式のドア/ボンネット/トランク、ステアリング、ライト類(ヘッドライト、ブレーキ、ウインカー、バック、サイレン)、エンジン/クラクション/サイレン音、キーボード・コントローラー・モバイル対応の操作、カスタマイズ機能(カラー、リバリー、エクストラ、ネオン、ナンバープレート)を提供します。MCP Roblox Studioが接続されていれば、変換からアップロード、Studioへのセットアップ、検証、修正までを自動実行します。接続がない場合は、手動セットアップ手順を提供します。物理演算はユーザー側のゲームエンジンに任せ、スキルは入力とテレメトリのフックポイントのみを提供します。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/g0shtj0sh/Fivem-To-Roblox-Skills/tree/HEAD/skills/fivem-vehicle-to-roblox

Installed? Explore more 画像 skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

FiveM / GTA V → Roblox(車両)

「この車両を変換して」+ZIP = ユーザーのクリック不要で全フロー:前提条件→変換→アップロード→Studioへの到着→セットアップ→検証→修正→短いレポート(日本語)。StudioのステップはMCP Roblox Studioが接続されている場合のみ適用されます。接続がない場合は、フォルダと手動ステップを提供します(ページ下部)。

測定、選択、注意点:docs/studio-import-tests.md。

ガードレール

  • ZIP内のコードは決して実行しないでください。内容はデータのみです。
  • シークレットは表示、ファイルへの書き込み、コミットを行わないでください(Open Cloudキーは環境変数のみ)。
  • 既存のプレイスは、作業ディレクトリ Workspace.F2R_ImportTest(またはユーザーが指定したフォルダ)以外は変更しないでください。プレイスの保存や公開は絶対に行わないでください。ランタイムは ReplicatedStorage / ServerScriptService / StarterPlayerScripts にインストールされます。レポートにその旨を記載してください。
  • Robloxに公開するのは、車両のプライベートアセット(GLB、サウンド)のみとし、それ以外は許可なく公開しないでください。
  • 結果を捏造しないでください。スクリプトやVerifyのメッセージをそのまま引用してください。
  • ゲームを公開する前に、Modのライセンスと実際の商標を確認するよう、一度リマインドしてください。

0. 前提条件(並行して、最初に)

前提条件確認方法ない場合
Python 3.10+、numpy、Pillowpython3 -c "import numpy, PIL"python3 -m pip install --user numpy pillow(pipがない場合:get-pip.py --user)
.NET 8(バイナリファイル .yft/.ytd/.awc 用)dotnet --version または ~/.dotnet/dotnetdotnet-install.sh --channel 8.0 --install-dir ~/.dotnet;コンバーターは ~/.dotnet を自動で見つけます
GTA Vアセットサーバー(実際のテクスチャとサウンド)MCPツール gta_status(ready: true)PC上で tools/gta-asset-server/start-server.bat を起動し、My MCP servers に登録するよう提案;それ以外の場合は、キャッシュ(~/.cache/fivem2roblox)内のものを使用し、キャッシュにもなければ単色/合成音を使用
Studio接続studio_connection_status(プラグイン接続)、list_roblox_studiosフォルダと手動ステップを提供
RobloxアップロードVibeStarter:ツール upload_file + asset_publish;それ以外:環境変数 ROBLOX_API_KEY が存在すること(絶対に表示しない)最終手段:手動アクション1回のみ、「3Dインポート」(§ 4c)

1. 変換

cd skills/fivem-vehicle-to-roblox
python scripts/convert_vehicle.py "<zip>" -o "<出力先>" [--plate "テキスト"] [--texture-overrides <フォルダ>]

オプション:--vehicle <名前>(マルチビークルパック)、--lod med(30万トライアングル超)、--no-collision(当たり判定=単純なボックス)、--wheel-collision(ホイールのソリッドシリンダー)、--studs-per-meter、--texture-overrides <フォルダ>(パック内のテクスチャを置き換える同名のPNG/DDS:リブランド、修正)、--sound-ids <json>、--retry-gamefiles、--no-game-server。 コード2=抽出機能なしのバイナリ:.NET 8をインストール(上記)して再実行;それ以外の場合はユーザーがCodeWalker XML出力を提供;暗号化された dlc.rpf → OpenIV。

<出力先>/<名前>/report.md を読む:「当たり判定:車両の公式衝突判定」(それ以外は境界ボックス:.yft に Physics/Bounds がない場合はその旨を報告)、「基本ゲームから再利用されたテクスチャ」、「実際のゲームサウンド」、「アセットサーバーからの転送」(ファイル、MB、秒)の各行。vehshare/vehicle_generic_* テクスチャの欠落、または合成音の使用=アセットサーバーに接続できない。

2. モデルとサウンドのアップロード(プライベートアセット)

並行して:

  • GLB <名前>.glb → upload_file のち asset_publish → Modelタイプの rbxassetid。
  • サウンド:各 sounds/*.wav|ogg → upload_file + asset_publish → sounds/sound_ids.json に書き込み = { "engine_on_1.wav": "rbxassetid://…", … }。 VibeStarter以外の場合:python scripts/roblox_upload.py <出力先>/<名前>/sounds --user-id <id>(キーは環境変数)。
  • --sound-ids <出力先>/<名前>/sounds/sound_ids.json を指定して変換を再実行(キャッシュ:約15秒)し、SoundIdをセットアップに統合します。GLBは変換間で同一(決定論的)です:新しいアップロードは不要。

忠実な当たり判定(自動)

.yft には車両の公式衝突判定(Physics/LOD1、複合 Bound)が含まれています:ボディ、ボンネット、トランク、ドア、窓が低ポリゴンメッシュ(約240トライアングル)、ホイールがディスク。コンバーターはこれをGLB(col__<os>__<n>、*_lowlod / *_dummy は除外)にエクスポートします。セットアップでは、これらを不可視でソリッド、かつ照会可能なパーツとして Collision/<os>/ に配置し、それぞれのボーンに溶接(ドアを開けても衝突判定は保持)、精度を設定(凸の場合は Hull、そうでない場合は PreciseConvexDecomposition、CreateMeshPartAsync + ApplyMesh を使用:スクリプトで CollisionFidelity を設定してもエラーなしで無視される)、ホイールをシリンダー(半径と接触点;--wheel-collision でソリッド)として追加し、Hitbox ボックスを無効化(境界ボリュームとして保持、属性 BoundsOnly)。m422での測定:可視ボディからの距離が15cm未満のレイを86%が達成(ボックスのみでは34%)。プレイヤーはボンネットの上に +1.55 stud で立つ(+3.17 stud ではなく)。当たり判定を表示するには:Collision を一時的に可視化(Transparency 0.5)。

3. Studio用スクリプトの準備(100KBのコードをコピーしない)

変換によって <出力先>/<名前>/studio/ が作成されます:FiveMRuntime.lua(ランタイム、プレイスに1回)、<名前>_Setup.studio.lua(コンパクトなセットアップ)、Verify.lua、ApplySoundIds.lua、chunks/ + manifest.json。

  • 開いているプレイスと同期したRojoプロジェクト(VibeStarter):ファイルをマウントされたフォルダに配置 —
    python scripts/studio_stage.py <出力先>/<名前> --project <プロジェクトのフォルダ>
    
    → ReplicatedStorage.rbxts_include.F2R_Transfer(StringValue FiveMRuntime、<名前>_Setup、ApplySoundIds、<名前>_sound_ids;ModuleScript Verify)が約2秒でStudioに表示されます。
  • それ以外の場合:studio/chunks/*.lua を manifest.json の順序で、execute_luau をファイルごとに1回ずつ、そのまま送信します。各ステップの最後のチャンクがスクリプトを実行し、結果を返します。

4. Studioにモデルを配置する

a. EditableMesh:却下(保存時にジオメトリが失われる、車両1台で約12MBのテキストになる)。 b. 採用:insert_asset でGLBのIDを使用、parent = "Workspace.F2R_ImportTest"(フォルダがなければ execute_luau で作成)、position は自由(セットアップが車両を地面に配置)。MeshPartsはglTFノードの名前を保持(Model <名前>_Node 内、セットアップで削除)。 c. 最終手段、アップロードが不可能な場合:ユーザーに1回だけアクションを依頼 — 「Studioで:ホーム › 3Dインポート › <出力先>/<名前>/<名前>.glb、デフォルトオプション。完了したら教えてください。」 セットアップはその後、モデルを自動的に見つけます(パーツ ProbePart)。

5. ランタイム + セットアップ(execute_luau、編集)

local T = game.ReplicatedStorage.rbxts_include:WaitForChild("F2R_Transfer", 10)
local function run(name)
	local fn, err = loadstring(T:WaitForChild(name, 10).Value, "=" .. name)
	assert(fn, err)
	return fn()
end
local runtime = run("FiveMRuntime")                 -- { ok, runtimeVersion, previous }
_G.F2R_TARGET = workspace.F2R_ImportTest.<名前>      -- 挿入されたModel
local setup = run("<名前>_Setup")                    -- { parts, joints, missingParts, missingSounds, groundedBy, warnings }
return { runtime = runtime, setup = setup }

セットアップの前に _G.F2R_NO_GROUND = true とすると、インポート時の高さを維持します。SoundIdの忘れ:_G.F2R_TARGET = モデル;_G.F2R_SOUND_IDS = T.<名前>_sound_ids.Value;run("ApplySoundIds")。

6. 検証(roblox/Verify.lua)

Verify.lua は関数 verify(opts) -> JSON を返します:{ pass, fail, warn, skip, results = { {group, name, status, detail} } }。

編集 — require(T.Verify:Clone())({ model = <モデル> }):ランタイムがインストールされていること;パーツが存在し、正しく命名されていること(F2RExpectedParts);車両がまっすぐで、前方が−Z方向であること;スケール(ホイールベースが1%以内);ヘッドライトがテールライトより前にあること;パーツがフットプリント内にあること;地面に設置されていること;ホイールが正しい位置と向きにあること;当たり判定(パーツとホイールが存在し、不可視かつソリッドでボーンに溶接され、精度が設定され、ボックスが無効化されていること、6方向から400本のレイを使用した忠実度が可視ボディおよびボックスと比較して15cm未満が80%以上);SoundIdが入力されていること;SetColor / SetMod / SetLivery / SetExtra / SetNeon / SetPlate および Serialize → Apply で状態が復元されること。

プレイ、サーバー(execute_luau Server、1プレイヤー)— require(…Verify)({ model = …, checks = {…} }):seats_play(各シートで乗車、降車;seat = "<名前>" で1つのみ)、lock_play、park_play、flip_play、void_play(虚空への落下から回復)。ボディ適応(クライアント、着座プレイヤー):checks = {"fit_play"} — ボディのどの点もキャビンの外に出ていない、シートに座っている、スケールが読み取れる。seats_play を車両を軽い傾斜(作業フォルダ内の一時的な傾斜プラットフォーム)に置いて再実行。

プレイ、クライアント(レンダリングランタイムはクライアント側でのみ動作;loadstring はクライアントでは禁止):

  1. start_stop_play(is_start = true)。
  2. execute_luau クライアント: require(game.ReplicatedStorage.rbxts_include.F2R_Transfer.Verify)({ model = workspace.F2R_ImportTest:WaitForChild("<名前>"), checks = {"joints","lights","sounds","audio"} }) → レンダリングは FiveMVehiclesClient によって自動的にアタッチされる(それ以外の場合はゲーム内で車両が無反応);ドア/ボンネット/トランクが Hinges から Door_* 経由で角度を持って動作、ホイールとステアリングはテレメトリ経由で動作、キャリパー(hub_*)は回転せずに操舵、サスペンションアーム(suspension_*)は回転固定、各LightRoleはHeadlights 1/2、Brake、Reverse、Indicator Left/Right/Hazard、Engine、Sirenに対してNeon(または照明点灯)として機能;サウンドが読み込まれる;エンジン音が聞こえる。
  3. 運転:execute_luau サーバー — プレイヤーを座らせる(seat:Sit(humanoid) を Seats.DriverSeat に対して)そして属性 Horn を監視;player_input H 次いで E(700ms間押し続ける);execute_luau サーバー — Engine = true、Headlights = 1、Horn が true になった後 false に戻るのを待つ。
  4. 運転エンジン:プレイヤーがステアリングを握る(サーバー側で VehicleAccess.Enter)、次いで execute_luau クライアント require(…Verify)({ model = …, checks = {"drive_play"} })(加速、一貫した回転数、停止、直進を維持)。完全な測定(0-100、制動、旋回、縁石、坂道、後退):マップから離れた場所に TestTrack.lua を作成、DriveBench.lua ベンチマーク、詳細は references/roblox-integration.md(「運転テスト」)を参照;長時間テストは task.spawn で。
  5. start_stop_play(is_start = false)。制御を返す前に必ずPlayを停止してください。3分間Studio呼び出しなしのPlayはVibeStarterによって停止されます。

Verifyの結果を読み取ってください。コンソールのエラー数ではありません:他の車両を含むプレイスでは、私たちのものではない「Failed to load sound …」が数百件表示されることがあります。warn ステータス「レンダリング停止」=Studioにフォーカスがない(RenderStepped停止):グループを再実行してください。

7. 各エラーの修正

Verifyエラー一般的な原因修正
パーツ欠落/名前変更異なるインポーター名前を確認(F2RMissingParts);GLBを再インポート(§ 4b)
ホイールベース / 前方が−Z方向でない / ホイールの向きモデルが反転、基準点が不適切セットアップのメッセージ「位置合わせが不正確」;pick_ref_parts または軸変換を修正
ドアが0°(「レンダリング停止」ではない)Motor6Dがない、パーツがルートに溶接されているJoints/ とドアパーツの Owner を確認
ライトの役割がオフのままパーツに LightRole がない、不明なライトIDreferences/gta-format.md(ライトID);f2r/vehicle.py を修正
SoundIdが空/サウンドが読み込まれないアップロード未完了または拒否§ 2;ApplySoundIds
Serialize / Apply状態が復元されないroblox/runtime/VehicleCustomization.lua
当たり判定:精度 DefaultApplyMesh が拒否された(メッシュ未ロード、権限不足)セットアップを再実行;GLBがプレイス所有者のアセットであることを確認
当たり判定の忠実度 < 80%Modの衝突判定が粗い、または存在しない「大きすぎる/小さすぎる」と報告;Physics がないMod → ボックス(報告)
レンダリングがFiveMVehiclesClientによってアタッチされない2026-11-10の修正前のランタイムFiveMRuntime(新しいバージョン)を再インストール
ホイール操舵時にキャリパーが固定2026-11-11より前の変換(hub_* ボーンが無視)再変換して再インストール(§ 4bから6)
プロンプト/サウンドが「車外」2026-11-11より前のセットアップ(親設定前にWorldPositionが設定)車両を再インストール(§ 4bから6)
降車:屋根の上に着地両側に空きスペースがない(壁、他の車両)正常;それ以外の場合は傾斜と隣接パーツを確認
頭が天井に(警告)アバターがスケールに対して大きすぎるseats_play が推奨するスケールで再変換

スキルの修正後:再変換、再インストール(モデルを削除し、§ 4bから6を実行)、再検証。ランタイムの変更は FiveMRuntime(バージョン=ソースのハッシュ)によって伝播します。

…

[翻訳のために省略]

関連スキル