"깊이"가 다른 게임개발자 허민영

유저에서 게임까지, 철학에서 코딩까지, 본질을 보는 게임개발

소프트웨어 공학/바이브코딩

문제해결] CoplayDev Unity-MCP, 스크린샷 사용 시 유니티 재컴파일 문제

허민영 2026. 3. 1. 19:29

MCP 스크린샷 사용 시 재컴파일 문제 해결 보고서

문제 현상

MCP의 manage_scene(action="screenshot") 호출 시, 스크린샷 캡처 직후 Unity가 스크립트 재컴파일(Domain Reload)을 수행하여 플레이 모드가 중단되거나 에디터가 일시적으로 멈추는 문제가 발생했다.

변경된 파일 (2개)

  1. Runtime/Helpers/ScreenshotUtility.cs
  2. Editor/Tools/ManageScene.cs

변경점 1: ScreenshotUtility.cs

변경 A — 스크린샷 저장 경로 변경

항목 원본 수정본
저장 기준 폴더 Application.dataPath (Assets/) GetProjectRootPath() (프로젝트 루트)
실제 저장 위치 Assets/Screenshots/ ProjectRoot/Screenshots/
// 원본: Assets 폴더 내부에 저장
string folder = Path.Combine(Application.dataPath, ScreenshotsFolderName);

// 수정본: 프로젝트 루트에 저장
string folder = Path.Combine(GetProjectRootPath(), ScreenshotsFolderName);

근본 원인: Assets/ 폴더 내부에 파일이 생성되면, Unity의 AssetDatabase가 이를 감지하고 자동 임포트 → 스크립트 재컴파일(Domain Reload)을 트리거할 수 있다.

변경 B — CaptureScreenshot 호출 인자 변경

항목 원본 수정본
전달 경로 result.AssetsRelativePath (상대 경로) result.FullPath (절대 경로)
// 원본: Assets 기준 상대 경로 전달
ScreenCapture.CaptureScreenshot(result.AssetsRelativePath, result.SuperSize);

// 수정본: 절대 경로 전달
ScreenCapture.CaptureScreenshot(result.FullPath, result.SuperSize);

이유: 저장 위치가 Assets/ 외부(프로젝트 루트)로 변경되었으므로, ScreenCapture.CaptureScreenshot에 Assets 상대 경로를 전달하면 잘못된 위치에 저장된다. 절대 경로를 사용해야 프로젝트 루트의 Screenshots/ 폴더에 정확히 저장된다.


변경점 2: ManageScene.cs

변경 C — LockReloadAssemblies 방식 도입

원본은 스크린샷 캡처 후 AssetDatabase.ImportAsset을 호출하고, 비동기 캡처 시 파일이 디스크에 생성될 때까지 폴링하는 ScheduleAssetImportWhenFileExists 메서드를 사용했다.

수정본은 이 전체 구조를 EditorApplication.LockReloadAssemblies() / UnlockReloadAssemblies()로 대체했다.

// 원본: 비동기 임포트 + 폴링
ScreenshotCaptureResult result = ScreenshotUtility.CaptureToAssetsFolder(...);

if (result.IsAsync)
{
    ScheduleAssetImportWhenFileExists(result.AssetsRelativePath, result.FullPath, timeoutSeconds: 30.0);
}
else
{
    AssetDatabase.ImportAsset(result.AssetsRelativePath, ImportAssetOptions.ForceSynchronousImport);
}
// + ScheduleAssetImportWhenFileExists 메서드 (55줄)
// 수정본: 어셈블리 리로드 잠금
EditorApplication.LockReloadAssemblies();
try
{
    ScreenshotCaptureResult result = ScreenshotUtility.CaptureToAssetsFolder(...);
    // 즉시 응답 반환 (임포트 시도 없음)
    return new SuccessResponse(...);
}
finally
{
    EditorApplication.UnlockReloadAssemblies();
}

변경 D — ScheduleAssetImportWhenFileExists 제거

원본에 존재하던 55줄짜리 ScheduleAssetImportWhenFileExists 메서드 제거.

항목 원본 수정본
ScheduleAssetImportWhenFileExists 존재 (55줄) 제거됨
AssetDatabase.ImportAsset 호출 있음 없음
EditorApplication.LockReloadAssemblies 없음 있음

전체 변경 요약

# 파일 변경 내용 해결하는 문제
A ScreenshotUtility.cs 저장 경로: Assets/Screenshots/ProjectRoot/Screenshots/ Assets 폴더 내 파일 생성 시 자동 리프레시/재컴파일 방지
B ScreenshotUtility.cs CaptureScreenshot 인자: 상대경로 → 절대경로 경로 변경 A에 따른 정합성 유지
C ManageScene.cs LockReloadAssemblies/UnlockReloadAssemblies 래핑 추가 캡처 중 Domain Reload 방지
D ManageScene.cs ScheduleAssetImportWhenFileExists 메서드 및 AssetDatabase.ImportAsset 호출 제거 Assets 외부에 저장하므로 임포트 불필요, 불필요한 AssetDB 임포트로 인한 재컴파일 원인 제거

근본 원인 분석

[원본 동작 흐름 - 문제 발생]
manage_scene(screenshot)
  → ScreenCapture.CaptureScreenshot("Assets/Screenshots/xxx.png")
  → 파일이 Assets/ 내부에 생성됨
  → Unity AssetDatabase가 새 파일을 자동 감지
  → 텍스처 임포트 처리
  → ScheduleAssetImportWhenFileExists에서 ForceSynchronousImport 호출
  → Domain Reload (재컴파일) 트리거
  → 플레이 모드 중단 / 에디터 멈춤
[수정본 동작 흐름 - 문제 해결]
manage_scene(screenshot)
  → LockReloadAssemblies() (안전장치)
  → ScreenCapture.CaptureScreenshot("C:/.../ProjectRoot/Screenshots/xxx.png")
  → 파일이 Assets/ 외부에 생성됨
  → Unity AssetDatabase가 감지하지 않음
  → 임포트 처리 없음
  → UnlockReloadAssemblies()
  → 재컴파일 발생하지 않음

해결 방법의 핵심

  1. Assets 폴더 외부로 스크린샷 저장: 재컴파일의 근본 원인을 제거
  2. LockReloadAssemblies: 캡처 과정 중 예기치 않은 재컴파일에 대한 이중 안전장치
  3. AssetDatabase 임포트 로직 제거: Assets 외부 저장이므로 임포트 자체가 불필요