AI 보조 게임 개발

.cursor/rules 파일 하나로 Unity·Unreal AI 코드 제안 품질 올리기

kr-gamedev 2026. 6. 10. 09:03

Cursor를 써본 게임 개발자라면 한 번쯤 이런 경험이 있을 것이다. Update() 안에서 LINQ를 쓰라고 제안하거나, Unreal 프로젝트에서 raw pointer로 Actor를 관리하라고 안내하는 상황. 일반 C# · C++ 코드로는 맞는 말이지만 게임 개발 맥락에서는 성능 지옥 혹은 크래시의 입구다.

Cursor는 기본적으로 프로젝트가 Unity인지, Unreal인지, 아니면 그냥 콘솔 앱인지 구분하지 않는다. 이 공백을 메워주는 것이 .cursor/rules 파일이다. 프로젝트 루트에 이 파일을 두면 Cursor의 AI 에이전트가 응답을 생성하기 전에 해당 규칙을 참조한다. 엔진 버전, 금지 패턴, 선호 패턴을 한 곳에 명시해두면 AI가 "이 프로젝트는 Unity 2023 URP 기반"이라는 맥락 아래에서만 코드를 생성한다.


.cursor/rules vs .cursorrules -- 뭐가 다른가

Cursor 0.45 버전부터 .cursorrules 파일은 deprecated로 표시됐다. 새 포맷은 .cursor/rules/ 폴더 아래에 .mdc 확장자 파일 여러 개를 두는 방식이다. 핵심 차이는 glob 패턴으로 규칙 적용 범위를 파일별로 지정할 수 있다는 점이다.

.cursor/
  rules/
    unity-csharp.mdc      # Assets/**/*.cs 에만 적용
    unreal-cpp.mdc        # Source/**/*.cpp, *.h 에만 적용
    general.mdc           # 전체 프로젝트 공통

.mdc 파일 상단에 YAML 프런트매터로 적용 범위를 선언한다. alwaysApply: true 로 설정하면 파일 무관하게 항상 주입된다.


Unity C# 규칙 파일 작성하기

아래 예시는 Unity 2023 URP 프로젝트 기준이다. Assets/**/*.cs 경로를 globs에 지정해 Unity 스크립트 파일에만 적용한다.

# .cursor/rules/unity-csharp.mdc
---
description: Unity C# 코딩 규칙
globs: Assets/**/*.cs
alwaysApply: false
---

## 엔진 환경
- Unity 2023.3 LTS, URP 16.x / C# 12 / .NET Standard 2.1
- Burst Compiler, Collections 2.x, UniTask(Cysharp) 사용

## 금지 패턴
- Update/FixedUpdate 내부에서 LINQ, 박싱, GC 유발 코드 금지
- `new` 로 컴포넌트 생성 금지 -- AddComponent 또는 ObjectPool 사용
- Coroutine 대신 UniTask + CancellationToken 선호
- string 연결(+) 반복 금지, StringBuilder 또는 string.Create 사용

## 선호 패턴
- 오브젝트 풀: UnityEngine.Pool.ObjectPool<T>
- 에셋 로딩: Addressables.LoadAssetAsync (직접 참조 금지)
- 구조체 반환 시 C# 12 ref readonly struct 고려

이 파일을 두면 Cursor가 Unity 스크립트를 건드릴 때마다 UniTask · Addressables · GC-free 패턴이라는 전제 아래 제안을 생성한다. 아래는 실제 생성 품질 차이다.

Before (rules 없음):

// Cursor가 제안한 코드 -- GC 유발, 직접 참조
private IEnumerator LoadEnemy(string path)
{
    var prefab = Resources.Load<GameObject>(path); // 동기 로드
    yield return null;
    Instantiate(prefab);
}

After (rules 적용):

private async UniTaskVoid LoadEnemyAsync(string key, CancellationToken ct)
{
    var handle = Addressables.LoadAssetAsync<GameObject>(key);
    await handle.ToUniTask(cancellationToken: ct);
    if (handle.Status == AsyncOperationStatus.Succeeded)
        Instantiate(handle.Result);
}

Resources.Load 대신 Addressables, 코루틴 대신 UniTask로 자동 전환됐다.


Unreal C++ 규칙 파일 작성하기

Unreal 프로젝트는 매크로 규칙과 메모리 관리 패턴이 복잡하다. raw pointer 대신 TObjectPtr, UPROPERTY 누락 금지 등을 명시해 AI가 반복 실수를 하지 않도록 한다.

# .cursor/rules/unreal-cpp.mdc
---
description: Unreal Engine 5 C++ 규칙
globs: Source/**/*.cpp, Source/**/*.h
alwaysApply: false
---

## 엔진 환경
- Unreal Engine 5.4, C++ 20
- Enhanced Input System, GAS(Gameplay Ability System) 사용

## 메모리 / 포인터 규칙
- UObject 파생 클래스 멤버는 반드시 TObjectPtr<T> (raw pointer 금지)
- 약참조는 TWeakObjectPtr<T>
- 비 UObject 힙 객체는 TUniquePtr<T> / TSharedPtr<T>
- UPROPERTY 없는 UObject 멤버 선언 금지 (GC 회수 위험)

## 매크로 규칙
- 모든 UCLASS에 GENERATED_BODY() 필수
- BlueprintCallable / BlueprintPure 함수에 UFUNCTION 매크로 필수
- Delegate: DECLARE_DYNAMIC_MULTICAST_DELEGATE 계열 사용

Before (rules 없음):

// raw pointer + delete -- UObject에선 절대 금지
AActor* Enemy = SpawnEnemy();
if (Enemy->Health <= 0)
    delete Enemy;

After (rules 적용):

TObjectPtr<AEnemyCharacter> Enemy = SpawnEnemy();
if (IsValid(Enemy) && Enemy->GetHealth() <= 0)
{
    Enemy->SetLifeSpan(0.01f); // GC-safe 소멸
}

raw pointer와 delete가 사라지고 Unreal GC 방식으로 처리된다. 이 차이가 쌓이면 코드 리뷰 시간이 눈에 띄게 줄어든다.


팀 단위 활용 -- git에 커밋하라

.cursor/rules/ 폴더는 반드시 git에 커밋한다. 팀원 누구나 동일한 규칙을 공유하게 되므로 "AI가 이상한 코드를 제안했다"는 노이즈를 프로젝트 전체에서 낮출 수 있다. 규칙 파일을 수정할 때는 PR을 거쳐 팀이 합의한 패턴만 반영하면 된다.

규칙 파일이 길어지면 적용 glob 패턴을 좁히는 것이 효과적이다. Source/AI/**/*.h 처럼 서브디렉터리 단위로 쪼개면 AI가 컨텍스트를 더 집중해서 참조하고, 관계없는 규칙이 노이즈로 끼어드는 것을 막는다.


마치며

.cursor/rules 파일은 AI 도구를 "범용 코드 생성기"에서 "우리 프로젝트를 아는 동료"로 격상시키는 가장 빠른 방법이다. Unity라면 GC-free · UniTask · Addressables 패턴을, Unreal이라면 TObjectPtr · UPROPERTY · GAS 패턴을 명시해두자. 세팅 시간은 한 시간도 채 걸리지 않지만, 프로젝트 수명 내내 AI 제안 품질을 일정 수준 이상으로 유지해 준다.