Community이미지github.com

fivem-vehicle-to-roblox

FiveM/GTA V 차량(zip 또는 .yft/.ytd/.meta/.awc, dlc.rpf, XML CodeWalker 내보내기가 포함된 리소스 폴더)을 완전하고 기능적인 Roblox 차량으로 변환합니다. Roblox Studio가 연결된 경우(MCP Roblox Studio) 자동으로 설치 및 확인합니다.

fivem-vehicle-to-roblox란 무엇인가요?

이 스킬은 FiveM 또는 GTA V 차량을 Roblox로 완전히 변환하는 자동화된 워크플로우를 제공합니다. 사용자가 차량을 zip 파일이나 폴더로 제공하면, 3D 모델을 부품으로 분할하고, 텍스처, 바퀴, 경첩식 문/보닛/트렁크, 스티어링 휠, 조명(헤드라이트, 브레이크, 방향지시등, 후진등, 경광등), 엔진/경적/사이렌 사운드, 키보드/컨트롤러/모바일 제어, 그리고 커스터마이징(카컬러, 도색, 리버리, 엑스트라, 네온, 번호판)을 포함한 완전한 Roblox 차량을 생성합니다. 변환은 Python 스크립트(convert_vehicle.py)를 통해 수행되며, GTA V의 실제 텍스처와 사운드를 사용하기 위해 로컬 에셋 서버(GTA V 게임 파일)가 필요합니다. Roblox Studio MCP가 연결되어 있으면 변환된 GLB 모델과 사운드를 Roblox에 업로드하고, Studio에서 자동으로 셋업, 검증 및 수정을 수행합니다. 물리 엔진은 사용자 게임에 맡기고, 스킬은 입력과 텔레메트리 연결점만 제공합니다. MCP가 없는 경우에는 수동 단계를 제공합니다. 이 스킬은 다양한 FiveM 차량 포맷을 지원하며, 충돌체(hitbox) 정확도 향상, 사운드 ID 통합, 상세한 검증(Verify.lua)을 통한 품질 보증 등의 고급 기능을 제공합니다.

지원 대상~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에 설치됩니다. 보고서에 명시하십시오.
  • 필요한 비공개 차량 자산(GLB, 사운드)만 Roblox에 게시하십시오. 다른 것은 동의 없이 게시하지 마십시오.
  • 결과를 지어내지 마십시오. 실패 시 스크립트 또는 Verify 메시지를 인용하십시오.
  • 게임을 게시하기 전에 모드 라이선스와 실제 상표권을 확인하라는 알림을 한 번 제공하십시오.

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가 있어야 함 (절대 표시 금지)최후의 수단: 한 번의 수동 작업, 3D 가져오기 (§ 4c)

1. 변환

cd skills/fivem-vehicle-to-roblox
python scripts/convert_vehicle.py "<zip>" -o "<출력>" [--plate "텍스트"] [--texture-overrides <폴더>]

옵션: --vehicle <이름> (멀티 차량 팩), --lod med (> 300,000 삼각형), --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 → rbxassetid (Model 유형).
  • 사운드: 각 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에서 측정: 충돌 상자 대비 34%에 비해 광선의 86%가 보이는 차체로부터 15cm 이내에 있음; 플레이어가 +3.17 대신 +1.55 스터드 높이에 보닛 위에 섭니다. 히트박스 보기: 스크린샷을 위해 Collision을 일시적으로 표시(투명도 0.5).

3. Studio용 스크립트 준비 (100KB 코드를 다시 복사하지 않음)

변환은 <출력>/<이름>/studio/에 다음을 씁니다: FiveMRuntime.lua (런타임, 장소당 한 번), <이름>_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), Studio에서 ~2초 후에 표시됩니다.
  • 그렇지 않으면: studio/chunks/*.lua를 manifest.json 순서대로 보내고, 파일당 execute_luau 하나씩, 그대로 보냅니다. 각 단계의 마지막 조각이 스크립트를 실행하고 결과를 반환합니다.

4. Studio에 모델 가져오기

a. EditableMesh: 거부됨(저장 시 지오메트리 손실, 차량당 ~12MB 텍스트). b. 선택됨: insert_asset을 GLB ID와 함께 사용, parent = "Workspace.F2R_ImportTest" (폴더가 없으면 execute_luau로 생성), position 자유 (설정이 차량을 바닥에 놓음). MeshParts는 glTF 노드 이름을 유지합니다(Model <이름>_Node 내부, 설정에서 제거됨). c. 최후의 수단, 업로드가 불가능한 경우: 사용자에게 한 번만 요청 — "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.<name>      -- 삽입된 Model
local setup = run("<name>_Setup")                    -- { parts, joints, missingParts, missingSounds, groundedBy, warnings }
return { runtime = runtime, setup = setup }

_G.F2R_NO_GROUND = true를 설정 전에 설정하면 가져오기 높이가 유지됩니다. SoundId 누락: _G.F2R_TARGET = model ; _G.F2R_SOUND_IDS = T.<name>_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 = <model> }): 런타임 설치됨; 부품 존재 및 이름 지정됨 (F2RExpectedParts); 차량이 똑바르고, 앞이 -Z 방향; 축척(축간거리 1% 이내); 헤드라이트가 미등보다 앞에 있음; 부품이 경계 내에 있음; 바닥에 닿음; 바퀴가 제자리에 있고 올바른 면; 히트박스(조각 및 바퀴 존재, 보이지 않고 단단함, 뼈대에 용접됨, 정밀도 설정됨, 상자 중립화됨, 6면에서 400개의 광선으로 충실도를 보이는 차체 및 상자와 비교: ≥ 80%가 15cm 이내); SoundId가 입력됨; SetColor / SetMod / SetLivery / SetExtra / SetNeon / SetPlate 및 Serialize → 상태를 복원하는 Apply.

플레이, 서버(execute_luau 서버, 한 명의 플레이어) — require(…Verify)({ model = …, checks = {…} }): seats_play (각 좌석에 탑승 후 하차; seat = "<name>"으로 단일 좌석 지정 가능), lock_play, park_play, flip_play, void_play (낙하 후 복구). 신체 적응(클라이언트, 앉은 플레이어): checks = {"fit_play"} — 신체 포인트 0개가 실내 외부, 좌석에 착석, 스케일 읽음. 경사로에 놓인 차량에서 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("<name>"), checks = {"joints","lights","sounds","audio"} }) → 렌더링이 FiveMVehiclesClient에 의해 자동으로 연결됨 (그렇지 않으면 차량이 게임에서 비활성 상태), 문/보닛/트렁크가 Hinges 각도로 Door_*를 통해, 바퀴와 핸들은 텔레메트리를 통해, 캘리퍼(hub_*)는 회전하지 않고 조향, 서스펜션 암(suspension_*)은 회전 고정, 각 LightRole은 Neon(또는 조명 켜짐)으로 Headlights 1/2, Brake, Reverse, Indicator Left/Right/Hazard, Engine, Siren; 사운드 로드됨; 엔진 청취 가능.
  3. 운전: execute_luau 서버 — 플레이어를 앉힘(seat:Sit(humanoid) on 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"} }) (가속, 일관된 RPM, 정지, 직진 유지). 전체 측정(0-100, 제동, 코너링, 연석, 언덕, 후진): Play에서 맵과 떨어진 곳에 생성된 TestTrack.lua 트랙, DriveBench.lua 벤치마크, references/roblox-integration.md("주행 테스트") 참조; 긴 테스트는 task.spawn으로.
  5. start_stop_play (is_start = false). 항상 제어권을 반환하기 전에 Play를 중지하십시오. VibeStarter는 Studio 호출 없이 3분이 지나면 Play를 중지합니다.

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%모드 충돌체가 거칠거나 없음"너무 넓음/너무 좁음" 읽기; Physics가 없는 모드 → 상자(알림)
FiveMVehiclesClient가 렌더링을 연결하지 않음2026-11-10 수정 이전의 런타임FiveMRuntime 재설치 (새 버전)
바퀴가 조향될 때 캘리퍼가 고정됨2026-11-11 이전 변환(hub_* 뼈대 무시됨)재변환 및 재설치 (§ 4b ~ 6)
"차량 외부" 프롬프트/사운드2026-11-11 이전 설정(부모 설정 전에 WorldPosition 설정됨)차량 재설치 (§ 4b ~ 6)
하차: 지붕 위에 착륙양쪽에 빈 공간 없음(벽, 다른 차량)정상; 그렇지 않으면 경사와 주변 부품 확인
지붕에 머리가 닿음 (경고)아바타가 스케일보다 너무 큼seats_play에서 권장하는 스케일로 재변환

스킬 수정 후: 재변환, 재설치(모델 삭제, § 4b ~ 6) 및 재확인. 런타임 수정은 FiveMRuntime을 통해 전파됩니다(버전 = 소스 해시).

…

[번역을 위해 잘림]

관련 스킬