Guys, help. In Unity, I’m trying to make an ai using mlagents. The problem is that Discrete actions always return 0 (or rarely 1 after dancing with tambourines but it bug again after the 1st code change). I was busy for half a day, I did not find a solution on the forums (mb searched badly). In the inspector in branch N size always > 0.
Agent’s code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors;
public class TestAgent : Agent
{
[SerializeField]
private Transform _target;
private Vector3 _oldPosition;
private float _speed;
private bool _jump;
[SerializeField]
private Rigidbody _rb;
private bool _onGround;
public override void OnActionReceived(ActionBuffers actions)
{
float moveX = actions.ContinuousActions[0];
float moveZ = actions.ContinuousActions[1];
_jump = actions.DiscreteActions[1] != 0;
Debug.Log(_jump);
transform.position += new Vector3(moveX, 0, moveZ) * Time.deltaTime * _speed;
}
public override void CollectObservations(VectorSensor sensor)
{
sensor.AddObservation(transform.localPosition);
sensor.AddObservation(_target.localPosition);
}
public override void OnEpisodeBegin()
{
_speed = 3f;
_target.localPosition = new Vector3(Random.Range(-10f, 10f), 3f, Random.Range(-15f, 15f));
}
private void Update()
{
var reward = 0.1f;
if (transform.localPosition.y < -1f)
{
SetReward(-10f);
transform.localPosition = Vector3.zero;
EndEpisode();
return;
}
_oldPosition = new Vector3(_oldPosition.x, 0, _oldPosition.z);
var oldDistance = Vector3.Distance(_oldPosition, _target.localPosition - new Vector3(0f, _target.localPosition.y, 0f));
var currentDistance = Vector3.Distance(transform.localPosition, _target.localPosition - new Vector3(0f, _target.localPosition.y, 0f));
if (currentDistance <= 3f)
{
AddReward(reward * 2);
}
else
{
if (currentDistance > oldDistance)
{
AddReward(-reward / 10);
}
else if (currentDistance < oldDistance)
{
AddReward(reward / 10);
}
}
if (_jump && _onGround)
{
if (currentDistance <= 3)
{
AddReward(reward * 10);
}
_rb.AddForce(Vector3.up * 10, ForceMode.Impulse);
}
_oldPosition = transform.localPosition;
}
public override void Heuristic(in ActionBuffers actionsOut)
{
var continuousActions = actionsOut.ContinuousActions;
var discreteActions = actionsOut.DiscreteActions;
continuousActions[0] = Input.GetAxis("Horizontal");
continuousActions[1] = Input.GetAxis("Vertical");
discreteActions[0] = Input.GetAxis("Jump") == 0 ? 0 : 1;
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Target"))
{
AddReward(50f);
}
EndEpisode();
}
private void OnCollisionEnter(Collision collision)
{
_onGround = true;
}
private void OnCollisionExit(Collision collision)
{
_onGround = false;
}
}
My Agent’s object params in inspector on Google Drive
https://drive.google.com/file/d/1f2jBTn1iC452LJCqGfnXisLXxhHJY_hN/view?usp=share_link