언어/UNITY
[C# / UNITY] mummy asset를 이용하여 Rollerball test 진행하기
코린영이
2023. 3. 2. 12:52
728x90
반응형
Rollerball test을 mummy asset을 이용하여 해보기
- rollerball 폴더 안에 meshes 폴더를 만들고 mummy prefab을 복사해 넣어준다.
- 파일을 추가할 땐 항상 파일 명을 체크해야 한다.
- fbx -> meshes 폴더 안에 넣어도된다.
- FBX -> ctrl도 함께 존재하기 때문에 독립적으로 존재해야 한다.
- asset store에서 추가해도 된다.
- 이제 RollerAgent를 바꿔야 한다.
- mummy가 rolleragent를 대체하도록 위치해준다. Training Area 폴더 안에 넣어준다.
- 그냥 끌어다 놓으면 게임 오브젝트로 생성되는 것이 아니기 때문에 assets 폴더 안에 prefabs이라는 폴더를 만들어 넣어준다. original prefab을 눌러주면 된다. 그럼 게임 오브젝트화가 됐다.
- Scene의 이름도 movemummy로 바꿔 준다.
- mummy에도 rollerballagent처럼 component들을 추가해준다. (작업은 prefabs 안에서 해준다.)
- Capsule collider 추가
-
- RigidBody 추가한다. 아직은 따로 설정해 줄 정보는 없다.
- 나머지 몸 부위의 mesh 정보들은 mummy의 material에서 불러올 수 있다.
- Skinned Mesh Renderer의 materials 부분에 material을 넣어주면 된다.
- 우리가 prefabs에서 정보들을 바꿔줬을 때의 장점은 우리가 세팅했던 그대로 화면에 추가된다. 몇 개를 추가하던지 간에
- DecisionRequester 추가한다. (아님)
- DecisionRequester를 추가하니 BehaviorParameter도 함께 추가가 됐다.
- Rolleragent 였던 script를 mummyagent로 바꿔준다.
- script를 mummyagent에 추가하려고 하니까 에러가 나면서 창이 닫힌다.
- **script를 연결하려면 꼭 decisionrequester를 추가하기 전에 연결해야 한다.**
- script를 수정해준다.
- 당장은 이름만 바꿔주면 된다.
- Rolleragent의 component를 script 연결하기 전에 추가해준다. 이 때 절대로 decisionrequester부터 추가하면 안된다. Behaviorparameter부터 추가
- script를 연결해준다. script를 연결할 땐 꼭 script를 저장한 후에 연결해줘야 한다.
- 타겟도 넣어준다.
- 그리고 나서 rolleragent를 지워준다.
- 이제 그리고 난 후 DecisionRequester를 추가해준다.
- 이제 play를 해본다.
- 오류가 나는데 이 전에 mummy 예제에서 힘을 가하지 않고 매 순간 위치를 업데이트 하는 방법으로 오류를 해결했기 때문에 이번에도 그렇게 해준다.
- OnActionReceived 함수에서 결정해주면 된다.
- 힘을 가하는 AddForce가 아닌 transform 정보를 가져와서 입력 값에 대해서 -1과 +1로 제한시켜 놓고 Vector3.forward와 Vector3.right으로 설정해 주었다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Actuators;
public class MummyAgent : Agent
{
Transform tr;
Rigidbody rb;
void Start()
{
tr = GetComponent<Transform>();
rb = GetComponent<Rigidbody>();
}
public Transform Target;
public override void OnEpisodeBegin(){
if(this.transform.localPosition.y < 0){
this.rb.angularVelocity = Vector3.zero;
this.rb.velocity = Vector3.zero;
this.transform.localPosition = new Vector3(0, 0.5f, 0);
}
Target.localPosition = new Vector3(Random.value * 8 - 4, 0.5f, Random.value * 8 - 4);
}
// Update is called once per frame
void Update()
{
// pass
}
public override void CollectObservations(VectorSensor sensor)
{
// Target and Agent positions
sensor.AddObservation(Target.localPosition); // float 3
sensor.AddObservation(this.transform.localPosition); // float 3
// Agent velocity
sensor.AddObservation(rb.velocity.x); // float 1
sensor.AddObservation(rb.velocity.z); // float 1
}
public float forceMultiplier = 10;
public override void OnActionReceived(ActionBuffers actionBuffers)
{
// Actions, size = 2;
float move_x = actionBuffers.ContinuousActions[0];
float move_z = actionBuffers.ContinuousActions[1];
float delta_x = Mathf.Clamp(move_x, -1.0f, +1.0f);
float delta_z = Mathf.Clamp(move_z, -1.0f, +1.0f);
Vector3 dir = (Vector3.forward * delta_z) + (Vector3.right * delta_x);
// Vector3 dir = new Vector3(h,0,v);
tr.position += dir * 0.1f;
// 각속도를 0으로 해줘서 위치만 움직이게 한다.
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
float distanceToTarget = Vector3.Distance(this.transform.localPosition, Target.localPosition);
if (distanceToTarget < 1.42f)
{
SetReward(1.0f); // reward +1
EndEpisode();
}
// Fell off platform, 공이 floor 바깥으로 내려갈 때
else if (this.transform.localPosition.y < 0)
{
EndEpisode(); // 에피소드 종료
}
}
public override void Heuristic(in ActionBuffers actionsOut)
{
var continuousActionsOut = actionsOut.ContinuousActions;
continuousActionsOut[0] = Input.GetAxis("Horizontal");
continuousActionsOut[1] = Input.GetAxis("Vertical");
}
}
- 근데 나는 왜 안움직일까,,
- animator를 적용시키기 위해서는 entry가 움직일 때 move라는 것을 동작시켜야 할 것이다.
- mummy monster가 발 구르면서 걷는 것을 표현하고 싶으므로
- Controll에 mummy animation을 넣어줘야 한다.
- 좀 더 자연스럽게 움직이게 하기 위해서는 위치만 업데이트하면 안되고, transform에 있는 rotation도 함께 업데이트 해야한다.
- 에러 발생 시발
Couldn't connect to trainer on port 5004 using API version 1.5.0. Will perform inference instead. UnityEngine.Debug:Log(object)
- 오류가 나서 pytorch를 다시 다운 받아줬다.
-
pip3 install torch torchvision torchaudio
- 그래도 안된다.
- Package manager 에 있는 모든 것들을 upgrade 해줬는데도 안된다.
- Editor를 공식 버전으로 다른 버전으로 다운받았다. 그래도 안된다.
- Heuristic 오류는 해결했다.
- prefab에서 component를 추가하면 안되는 것 같다.
- prefab에서는 capsule collider 만 설정해주고 나머지는 scene에서 별도로 지정해줬다.
- 그리고 절대로 decision requester 먼저 추가하면 안된다. Behavior -> script 그리고 제일 마지막으로 decision을 추가해줘야 한다.
- 아직까지는 움직이는 것이 부자연스럽지만 나중에 script에 rotation에 관련된 코드도 집어 넣어주면 된다.
- 어떻게 Rotation 할지 생각하는 과정
- 지금 mummy는 한 방향만을 바라본 채로 x, z방향으로 위치만 바꾸고 있다. 자신이 가는 방향으로 시선이 가게 끔 만들어줘야 한다.
- 입력이 x는 1만큼, z는 3만큼일 때 그 사이를 바라보게 삼각함수를 이용하여 업데이트를 할 수도 있고, 아이디어를 생각해서 기능을 구현해보자.
- 다른 사람의 코드를 참조하는 것도 좋은 방법이다. 펭귄 예제에서 코드를 참조해보자. 펭귄에서는 KeyCode로 입력을 받고 있다. 그리고 discreteaction으로 받아서 transform.rotate를 이용했다.
- action의 종류가 달라서 그대로 쓰는 것에는 무리가 있지만 transform.rotate만 가져와보자.
- 자꾸 한 방향으로 도는 문제가 발생한다. 에러 발생
- 요점
기본적인 롤러볼 예제에서 환경을 설계. 환경에 대한 아이디어는
여러 개의 오브젝트가 생성되고 특정 몇 개만 획득
중간에 장애물을 만들어서 점프 기능을 추가한 후 원하는 목적지 도달
대상을 밀어서 민 대상을 특정 지역으로 옮기기
728x90
반응형