I have a simple agent script attached to an object as in the image:
The goal of the agent would be to navigate the map and reach the ping cube. The agent is a ball controlled with velocity. I tested the heuristics and they worked perfectly. I am not getting any errors. However, when I start the mlagents in command prompt (it doesn’t show any errors neither) and click play in my Unity project, my agent doesn’t appear to move at all. I find it very confusing because heuristics work.
Does anyone have any idea about what went wrong? I would really appreciate some help.
My code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors;
public class EnemyAgent : Agent
{
public GameObject player;
public int numRays = 20;
public float maxRayDistance = 100f;
public Vector3 v3forceX;
public Vector3 v3forceY;
public override void OnEpisodeBegin()
{
player = GameObject.Find("MLtarget");
transform.position = new Vector3(34.2361298f, 10.85267067f, 0.0426945575f);
GetComponent<Rigidbody>().velocity = Vector3.zero;
GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
GetComponent<Rigidbody>().velocity += v3forceY;
}
public override void CollectObservations(VectorSensor sensor)
{
sensor.AddObservation(transform.position);
sensor.AddObservation(player.gameObject.transform.position);
sensor.AddObservation(GetComponent<Rigidbody>().velocity);
//sensor.AddObservation(player.gameObject.GetComponent<Rigidbody>().velocity);
for (int i = 0; i < numRays; i++)
{
float angle = (360f / numRays) * i;
Vector3 direction = Quaternion.Euler(0, angle, 0) * transform.forward;
if (Physics.Raycast(transform.position, direction, out RaycastHit hit, maxRayDistance))
{
// Normalize the distance to a value between 0 and 1
float normalizedDistance = hit.distance / maxRayDistance;
sensor.AddObservation(normalizedDistance);
Debug.DrawLine(transform.position, hit.point, Color.red);
}
else
{
// If no collision, set distance to 1 (max distance)
sensor.AddObservation(1f);
}
}
}
public override void OnActionReceived(ActionBuffers actions)
{
float moveX = actions.ContinuousActions[0];
float moveY = actions.ContinuousActions[1];
GetComponent<Rigidbody>().velocity += moveY * v3forceY;
GetComponent<Rigidbody>().velocity += moveX * v3forceX;
}
public override void Heuristic(in ActionBuffers actionsOut)
{
ActionSegment<float> continuousActions = actionsOut.ContinuousActions;
continuousActions[0] = Input.GetAxisRaw("Horizontal");
continuousActions[1] = Input.GetAxisRaw("Vertical");
}
private void OnTriggerEnter(Collider other)
{
if(other.tag == "Floor")
{
SetReward(-1f);
}
else
{
SetReward(1f);
}
EndEpisode();
}
}