Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

지극히 개인적인 개발블로그

유니티 머신러닝 5. 직접 개발(1) 본문

카테고리 없음

유니티 머신러닝 5. 직접 개발(1)

코드분쇄기 2019. 8. 26. 17:55

우리는 머신러닝에 대해 간략하게나마 알아보았고 예제를 통해 실습까지 해봤습니다.

그럼 이제는 직접 제가 게임을 만들고 학습 시켜야겠죠?

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();
        }

    }