문제 해결
R3S 는 잘못된 사용을 R3Gen 진단으로 컴파일 단계에서 알려줍니다.
빠른 분류
- 구조 문제:
R3Gen001,R3Gen007,R3Gen008,R3Gen009,R3Gen010 - 대상/타입 문제:
R3Gen003,R3Gen004,R3Gen006 - 수명/모드 문제:
R3Gen005,R3Gen011,R3Gen012
자주 보는 진단
-
R3Gen001: 클래스는partial이어야 함 -
R3Gen003:AutoSubscribe대상 필드 없음 -
R3Gen004: 구독 메서드 파라미터 타입 불일치 -
R3Gen005:AddTo.Disposable사용 시AutoDispose필요 -
R3Gen007:Awake()누락 -
R3Gen008:Awake()에서R3Awake()호출 누락 -
R3Gen009:OnDestroy()누락 -
R3Gen010:OnDestroy()에서R3OnDestroy()호출 누락 -
R3Gen011: 비 MonoBehaviour에서 MonoBehaviour 전용 AddTo 사용 -
R3Gen012:Dispose()중복 선언
코드별 빠른 해결 예제
R3Gen001 - partial 누락
// before
public class PlayerViewModel : MonoBehaviour
{
}
// after
public partial class PlayerViewModel : MonoBehaviour
{
}
R3Gen008 - Awake에서 R3Awake 누락
private void Awake()
{
// R3Awake(); 누락
}
private void Awake()
{
R3Awake();
}
R3Gen010 - OnDestroy에서 R3OnDestroy 누락
private void OnDestroy()
{
// R3OnDestroy(); 누락
}
private void OnDestroy()
{
R3OnDestroy();
}
R3Gen004 - Subscribe 시그니처 불일치
[ReactiveProperty]
private ReactiveProperty<int> _hp = new(100);
[AutoSubscribe(nameof(_hp))]
private void OnHpChanged(string hpText) // 잘못된 타입
{
}
[AutoSubscribe(nameof(_hp))]
private void OnHpChanged(int hp) // 올바른 타입
{
}
R3Gen003 - AutoSubscribe 대상 필드 누락
[AutoSubscribe(nameof(_hp))]
private void OnHpChanged(int hp) { } // _hp 필드가 실제로 없음
[ReactiveProperty]
private ReactiveProperty<int> _hp = new(100);
[AutoSubscribe(nameof(_hp))]
private void OnHpChanged(int hp) { }
권장 대응 순서
-
partial,Awake,OnDestroy기본 규칙부터 맞춘다. -
AutoSubscribe의 대상 필드명/타입을 확인한다. -
AddTo 모드가 클래스 타입(MonoBehaviour 여부)과 맞는지 확인한다.
운영 팁
-
nameof(_field)를 고정 습관으로 사용하면 필드명 변경 시 오류를 줄일 수 있습니다. -
신규 팀원이 합류하면 먼저
R3Gen001,R3Gen008,R3Gen010세 개를 우선 안내하세요.
튜토리얼 - 자주 터지는 조합 오류
케이스 A : AutoSubscribe는 있는데 AutoDispose가 없음
public partial class WrongCaseA : MonoBehaviour
{
[ReactiveProperty] private ReactiveProperty<int> _hp = new(100);
[AutoSubscribe(nameof(_hp))]
private void OnHpChanged(int hp) { }
private void Awake() => R3Awake();
}
AddTo.Disposable가 기본값일 때는 AutoDispose가 필요합니다.
[AutoDispose]
public partial class FixedCaseA : MonoBehaviour
{
[ReactiveProperty] private ReactiveProperty<int> _hp = new(100);
[AutoSubscribe(nameof(_hp))]
private void OnHpChanged(int hp) { }
private void Awake() => R3Awake();
private void OnDestroy() => R3OnDestroy();
}
케이스 B : 비 MonoBehaviour에서 AddTo.CancellationToken 사용
[AutoDispose]
public partial class WrongCaseB
{
[ReactiveProperty] private ReactiveProperty<int> _value = new(1);
[AutoSubscribe(nameof(_value), AddTo.CancellationToken)] // R3Gen011
private void OnValue(int value) { }
public WrongCaseB() => R3Initialize();
}
해결 : 일반 클래스는 AddTo.Disposable로 사용합니다.
[AutoDispose]
public partial class FixedCaseB
{
[ReactiveProperty] private ReactiveProperty<int> _value = new(1);
[AutoSubscribe(nameof(_value), AddTo.Disposable)]
private void OnValue(int value) { }
public FixedCaseB() => R3Initialize();
}
튜토리얼 - 디버깅 순서 (30초 루틴)
-
첫 에러 코드 하나만 본다 (
R3Genxxx) -
partial,Awake/OnDestroy,nameof세 가지를 먼저 확인한다 -
AutoSubscribe 대상 필드의 실제 타입을 확인한다
-
AddTo 모드와 클래스 타입(MonoBehaviour 여부)을 대조한다
-
수정 후 재컴파일하여 다음 에러로 이동한다
튜토리얼 - 신규 팀원 온보딩용 점검 코드
아래 코드를 붙여 넣고 일부를 의도적으로 깨뜨리면 진단 코드 학습이 빠릅니다.
using R3;
using R3.Attributes;
using UnityEngine;
[AutoDispose]
public partial class R3GenTraining : MonoBehaviour
{
[ReactiveProperty]
private ReactiveProperty<int> _value = new(1);
[AutoSubscribe(nameof(_value))]
private void OnValueChanged(int value) { }
private void Awake() => R3Awake();
private void OnDestroy() => R3OnDestroy();
}
-
partial제거 →R3Gen001 -
R3Awake()호출 삭제 →R3Gen008 -
OnDestroy에서R3OnDestroy()삭제 →R3Gen010 -
OnValueChanged(string value)로 변경 →R3Gen004