소개
Unity ML-Agents를 사용하여 3D 평면 위에서 큐브가 스스로 타겟을 찾아가는 AI 에이전트를 처음부터 만들어 보았습니다.
목표: 파란 큐브가 노란 구체(타겟)를 스스로 찾아가도록 학습시키기
진행 방법
사용 도구 및 환경
도구
버전
Unity
6.3 LTS (6000.3.11f1)
ML-Agents 패키지
4.0.0
Python ml-agents 트레이너
1.1.0
PyTorch
2.2.2
전체 진행 과정
작업은 크게 8단계로 나누어 진행했습니다.
Step 1: 씬 구성
Unity에서 3D 오브젝트 3개를 배치했습니다.
오브젝트
타입
역할
색상
Floor
Plane
바닥
초록
Agent
Cube
AI가 조종할 큐브
파랑
Target
Sphere
목표 지점
노랑
Agent에는 Rigidbody를 추가하고, Linear/Angular Damping을 5로 설정하여 미끄러짐을 줄였습니다. 큐브가 굴러가지 않도록 Freeze Rotation도 X, Y, Z 모두 체크했습니다.
Step 2: 키보드 이동부터 구현
ML-Agents를 바로 적용하지 않고, 순수 MonoBehaviour로 WASD 키보드 이동을 먼저 구현했습니다. 오브젝트가 정상적으로 움직이는지 확인하는 것이 우선이었습니다.
이 단계에서는 FixedUpdate() 하나에 입력 감지와 물리 이동이 함께 들어 있었습니다.
Step 3: Agent 상속으로 전환
핵심은 행동 결정과 실행의 분리였습니다.
이전: 키 입력 → 힘 계산 → 이동 (한 곳에서 전부 처리)
이후:
Heuristic()에서 입력 → 숫자로 변환 /OnActionReceived()에서 숫자 → 이동 실행
이렇게 분리하면 키보드 입력 대신 신경망이 행동을 결정할 수 있게 됩니다. 이동 실행 코드는 "누가 결정했는지"와 무관하게 동일하게 동작합니다.
Step 4: Inspector 설정
Agent로 전환하면 Behavior Parameters 컴포넌트가 자동 추가됩니다. 주요 설정:
Space Size: 5 (신경망에 전달할 관측값 개수)
Discrete Branch 0 Size: 5 (정지/우/좌/앞/뒤 5가지 행동)
Behavior Type: Heuristic Only (키보드 테스트 시)
Decision Requester: 매 스텝마다 의사결정하도록 Decision Period = 1
Step 5: Heuristic 모드 테스트
Behavior Type을 "Heuristic Only"로 두고 Play하여 키보드로 조작해 보았습니다. 타겟 도달 시 리셋, 바닥 이탈 시 리셋이 정상 동작하는지 확인했습니다.
Step 6: 관측과 보상 로직 완성
에이전트가 학습할 수 있도록 다음을 구현했습니다.
구성 요소
RL 개념
내용
CollectObservations()
상태(State)
타겟과의 상대 위치(3개) + 현재 속도(2개) = 5개 float
OnActionReceived()
행동 + 보상
이동 실행 + 성공/실패/진행 중 보상 계산
OnEpisodeBegin()
환경 리셋
에이전트 초기화 + 타겟 랜덤 배치
AddObservation은 신경망에게 현재 상황을 숫자로 전달하는 역할을 합니다. 에이전트는 눈이 없기 때문에, 타겟과의 상대 위치(X/Y/Z 차이 3개)와 현재 이동 속도(X/Z 2개) 총 5개의 float 값을 매 스텝 전달합니다. 이때 절대 좌표 대신 상대 좌표를 사용해야 에이전트가 위치에 관계없이 패턴을 일반화할 수 있고, 목표 달성에 불필요한 정보(예: Y축 속도)는 제외하는 것이 학습 효율을 높이는 핵심입니다. 참고로 AddObservation 호출 횟수는 반드시 Inspector의 Space Size와 일치해야 합니다.
보상 설계:
타겟 도달 → +1.0 (성공)
바닥 이탈 → -2.0 (실패)
매 스텝 → 거리 기반 작은 패널티 (가까울수록 패널티 감소)
Step 7: 학습 설정 YAML 작성
PPO(Proximal Policy Optimization) 알고리즘을 사용하는 학습 설정 파일을 작성했습니다. batch_size 64, 은닉층 64유닛 1층, 총 300,000 스텝으로 설정했습니다.
Step 8: 학습 실행 및 모델 적용
Behavior Type을 Default로 변경
터미널에서
mlagents-learn명령으로 학습 서버 시작Unity에서 Play 클릭하여 학습 진행
완료 후 생성된
.onnx모델 파일을 Inspector에 연결Behavior Type을 Inference Only로 변경 → AI가 스스로 타겟을 찾아감
결과와 배운 점
학습 결과
시행착오
관측 크기 불일치: Space Size와 실제 AddObservation 호출 횟수가 다르면 에러 → 반드시 개수를 맞출 것
Branch Size 설정 오류: Branch 0 Size가 1이면 행동 0만 사용 가능 → 5가지 행동이면 5로 설정
앞으로 계획
실제 게임에 적용할 방법을 고민해 볼 예정