동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
완성본
만들었던 과정

우선 이 ray를 보자.
원랜 훨씬 듬성듬성한 기본 상태였다.

그래서 좀 빠져나가는 좀비들이 있었고, 그걸 개선하려고 거의 다 완성된 상태였을때 레이 개수를 늘렸다.

그러면 안됬다.
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
다시 영상을 찍으려하니 그저 에러나 뜨고말지만 아까전엔 그동안 했던 교육을 싹 다 까먹고 총을 난사했다.
그리고 원래는 몹 스폰시간이 훨씬 빨랐다.

하지만 보다시피, 이친구는 총을 한발만 쏜다는 개념이 없고, 총을 쐈다하면 스프레드로 쏴버린다.
플래피버드를 만들때도 느꼈지만, 얘네의 action전달법은 뭔가 많이 이상하다.
그냥 단순히 0 1 0 1 이런식으로 숫자를 전달하는게 아니라, 1을 전달하면 1111111111111111111이런식으로 전달되어 개작살이 나는것같다.
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
20배의 속도로 훈련을 돌릴땐 분명 적재적소에 한발씩만 쏘면서 평균점수도 9점대로 잘나오는걸 알수있다.
근데 직접 원래 속도로 돌릴땐 저렇게 때려박는걸 보아. action전달 방식이 getkeyDown이 아닌 getkey인것같다.

tenser board 그래프이다. 계속 한번떨어졌다가 더 높게 올라가는걸 볼수있는데, 나는 애초에 커리큘럼식으로 만들지 않았다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Actuators;
public class ShotAgent : Agent
{
public GameObject bulletPrefab;
private List<GameObject> bullets;
public RayPerceptionSensorComponent3D sensor;
// Start is called before the first frame update
void Start()
{
this.bullets = new List<GameObject>();
}
// Update is called once per frame
void Update()
{
/*if (Input.GetKeyDown(KeyCode.LeftArrow))
{
if (!(this.transform.localPosition.x < -2))
{
Debug.Log("왼");
this.transform.Translate(Vector3.left * 2);
}
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
if (!(this.transform.localPosition.x > 2))
{
Debug.Log("오른");
this.transform.Translate(Vector3.right * 2);
}
}
if (Input.GetKeyDown(KeyCode.Space))
{
var bul = Instantiate(this.bulletPrefab, this.transform.position + Vector3.forward, Quaternion.identity);
this.bullets.Add(bul);
}*/
}
public override void CollectObservations(VectorSensor sensor)
{
//관찰내용
sensor.AddObservation(this.transform.localPosition.x);
}
public override void OnActionReceived(ActionBuffers actions)
{
//매 스탭
/*RayPerceptionInput rayInput = this.sensor.GetRayPerceptionInput();
RayPerceptionOutput output = RayPerceptionSensor.Perceive(rayInput);
RayPerceptionOutput.RayOutput[] arr = output.RayOutputs;
//Debug.Log(arr.Length);
foreach (var rayOutput in arr)
{
Debug.LogFormat("-----> {0}", rayOutput.HitGameObject);
}*/
if (actions.DiscreteActions[0] == 0)
{
if (!(this.transform.localPosition.x < -2))
{
//Debug.Log("왼");
this.transform.Translate(Vector3.left * 2);
}
}
else if (actions.DiscreteActions[0] == 2)
{
if (!(this.transform.localPosition.x > 2))
{
//Debug.Log("오른");
this.transform.Translate(Vector3.right * 2);
}
}
if (actions.DiscreteActions[1] == 1)
{
//AddReward(-1f);
var bul = Instantiate(this.bulletPrefab, this.transform.position + Vector3.forward, Quaternion.identity);
bul.GetComponent<Bullet>().shotNoOne = () => {
AddReward(-0.1f);
};
this.bullets.Add(bul);
}
}
public override void OnEpisodeBegin()
{
//시작할떄
//Debug.Log("tlwkr");
this.transform.localPosition = new Vector3(-3, 0, -8);
}
public override void Heuristic(in ActionBuffers actionsOut)
{
//직접 컨트롤
/*actionsOut.DiscreteActions.Array[0] = (int)Input.GetAxisRaw("Horizontal") + 1;
actionsOut.DiscreteActions.Array[1] = Input.GetKeyDown(KeyCode.Space) ? 1 : 0;*/
}
public void GetScore()
{
AddReward(1f);
}
public void BadEnd()
{
AddReward(-1f);
foreach (var a in this.bullets)
{
Destroy(a.gameObject);
}
EndEpisode();
}
public void GoodEnd()
{
Debug.Log("고수");
//AddReward(10f);
foreach(var a in this.bullets)
{
Destroy(a.gameObject);
}
EndEpisode();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class Bullet : MonoBehaviour
{
public float moveSpeed = 20f;
public UnityAction shotNoOne;
private float pos;
private void Start()
{
this.pos = this.transform.position.z;
}
// Update is called once per frame
void Update()
{
this.transform.Translate(Vector3.forward * Time.deltaTime * this.moveSpeed);
if (this.transform.position.z - this.pos > 8)
{
this.shotNoOne();
Destroy(this.gameObject);
}
}
private void OnCollisionEnter(Collision collision)
{
Destroy(this.gameObject);
}
}
보다시피, 총알이 아무에게도 맞지않아 사라질때, shotNoOne이라는 대리자를 전달했고, 그 내용은 점수 0.1점 깎기였다.
그래서 탄을 난사하지않고 적재적소에 쏘게끔 훈련되었고, 한번씩 떨어지는 이유는 얘가 총점을 더 높게 받기위해 총알을 아끼다가 실수할때마다 점수가 떨어졌기때문이다. 그렇게 세부조정과정을 거칠때마다 점수는 더 높게 올라가는걸 볼수있었다.
'C# > 수업내용' 카테고리의 다른 글
| 0825 전방 사물 인식해서 그에 맞게 찾아가기_2 (0) | 2022.08.25 |
|---|---|
| 0824 커리큘럼 머신러닝 (0) | 2022.08.24 |
| 0823 머신러닝 (0) | 2022.08.23 |
| 0822 머신러닝 (0) | 2022.08.22 |
| 0816 polybrush 안되는 거 해결방법 (0) | 2022.08.16 |