지극히 개인적인 개발블로그
유니티 머신러닝 5. 직접 개발(1) 본문
우리는 머신러닝에 대해 간략하게나마 알아보았고 예제를 통해 실습까지 해봤습니다.
그럼 이제는 직접 제가 게임을 만들고 학습 시켜야겠죠?
https://learn.unity.com/project/2d-platformer-template
이 곳을 참고하여 2D 플랫폼 게임을 만들었습니다.
만들었다는 표현보다는 그래도 썻다는 표현이 더 적합하겠네요.
이번 프로젝트의 목적은 게임개발이 아닌 머신러닝이기 때문에 개발과정은 과감하게 생략하겠습니다.
이 프로젝트에 ML-Agent toolkit을 이용하기 위해서는 우선 유니티헙에서 받은 2D 플랫폼 프로젝트를 엽니다. 유니티 깃허브에서 받은 UnitySDK/Asset폴더 안에 ML-Agents와 Gizmos를 넣어줍시다.
3DRollerBall 프로젝트를 생각해보겠습니다. 이 프로젝트는 간단해서 오직 Floor와 Target 그리고 RollerAgent만 추가하면 됐습니다. 하지만 이 플랫폼게임과도 별반 다르지 않습니다. Floor는 이미 만들어져있고 Target는 맵 가장 오른쪽에 있는 Victory라는 오브젝트, 그리고 RollerAgent는 Player로 치환될수 있습니다. 하지만 Agent의 Brain과 정보를 주고 받을 Academy는 없으므로 새로 추가해 줍시다.
Academy의 이름은 PlayerAcademy로 해주고 PlayerAcademy라는 스크립트를 추가해줍시다.
스크립트는 일단 이렇게만 작성했습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class PlayerAcademy : Academy
{
}
Player Brain과 Learning Brain을 만들어줍니다. 각 오브젝트의 이름은 PlayerBrain과 LearningBrain으로 해줬습니다.
Agent(우리가 직접 조종하는 캐릭터)오브젝터에 PlayerAgent스크립트를 추가해줍시다. 스크립트 내용을 아래와 같이 해줍시다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class PlayerAgent : Agent
{
Rigidbody2D rBody;
// Start is called before the first frame update
void Start()
{
rBody = GetComponent<Rigidbody2D>();
}
public Transform target;
public override void AgentReset()
{
//If the Agents is fall, zero its momentum
this.rBody.velocity = Vector2.zero;
this.transform.position = new Vector2(0, -0.575f);
}
}
그리고는 Agent.CollectObservaction 메소드를 추가하겠습니다. 이 메소드는 정보를 모아 Brain에게 전달합니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class PlayerAgent : Agent
{
Rigidbody2D rBody;
public Transform target;
// Start is called before the first frame update
void Start()
{
rBody = GetComponent<Rigidbody2D>();
}
public override void AgentReset()
{
//If the Agents is fall, zero its momentum
this.rBody.velocity = Vector2.zero;
this.transform.position = new Vector2(0, 0);
}
public override void CollectObservations()
{
//Agent positions
AddVectorObs(target.position);
AddVectorObs(this.transform.position);
// Agent velocity
AddVectorObs(rBody.velocity.x);
}
}
마지막으로 Agent.AgentAction메소드를 만들어 보겠습니다. 이 메소드는 Brain에게 결정을 받고 Reward를 할당하는 메소드 입니다.
public float speed = 3;
public override void AgentAction(float[] vectorAction, string textAction)
{
// Actions, size = 1
Vector2 controlSignal = Vector2.zero;
controlSignal.x = vectorAction[0];
rBody.AddForce(controlSignal * speed);
// Rewards
float distanceToTarget = Vector2.Distance(this.transform.position,
target.position);
// Reached target
if (distanceToTarget < 1.0f)
{
SetReward(1.0f);
Done();
}
// Fell off platform
if (this.transform.position.y < -10.0f)
{
Done();
}
}