Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Question Discerete actiona always are 0

Discussion in 'ML-Agents' started by Unity_knight, Jan 12, 2023.

  1. Unity_knight

    Unity_knight

    Joined:
    Aug 22, 2021
    Posts:
    3
    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:
    Code (CSharp):
    1.  using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.MLAgents;
    5. using Unity.MLAgents.Actuators;
    6. using Unity.MLAgents.Sensors;
    7.  
    8. public class TestAgent : Agent
    9. {
    10.     [SerializeField]
    11.     private Transform _target;
    12.     private Vector3 _oldPosition;
    13.     private float _speed;
    14.     private bool _jump;
    15.     [SerializeField]
    16.     private Rigidbody _rb;
    17.     private bool _onGround;
    18.     public override void OnActionReceived(ActionBuffers actions)
    19.     {
    20.         float moveX = actions.ContinuousActions[0];
    21.         float moveZ = actions.ContinuousActions[1];
    22.         _jump = actions.DiscreteActions[1] != 0;
    23.         Debug.Log(_jump);
    24.         transform.position += new Vector3(moveX, 0, moveZ) * Time.deltaTime * _speed;
    25.     }
    26.     public override void CollectObservations(VectorSensor sensor)
    27.     {
    28.         sensor.AddObservation(transform.localPosition);
    29.         sensor.AddObservation(_target.localPosition);
    30.     }
    31.     public override void OnEpisodeBegin()
    32.     {
    33.         _speed = 3f;
    34.         _target.localPosition = new Vector3(Random.Range(-10f, 10f), 3f, Random.Range(-15f, 15f));
    35.     }
    36.     private void Update()
    37.     {
    38.         var reward = 0.1f;
    39.         if (transform.localPosition.y < -1f)
    40.         {
    41.             SetReward(-10f);
    42.             transform.localPosition = Vector3.zero;
    43.             EndEpisode();
    44.             return;
    45.         }
    46.         _oldPosition = new Vector3(_oldPosition.x, 0, _oldPosition.z);
    47.        
    48.         var oldDistance = Vector3.Distance(_oldPosition, _target.localPosition - new Vector3(0f, _target.localPosition.y, 0f));
    49.         var currentDistance = Vector3.Distance(transform.localPosition, _target.localPosition - new Vector3(0f, _target.localPosition.y, 0f));
    50.         if (currentDistance <= 3f)
    51.         {
    52.             AddReward(reward * 2);
    53.         }
    54.         else
    55.         {
    56.             if (currentDistance > oldDistance)
    57.             {
    58.                 AddReward(-reward / 10);
    59.             }
    60.             else if (currentDistance < oldDistance)
    61.             {
    62.                 AddReward(reward / 10);
    63.             }
    64.         }
    65.  
    66.         if (_jump && _onGround)
    67.         {
    68.             if (currentDistance <= 3)
    69.             {
    70.                 AddReward(reward * 10);
    71.             }
    72.             _rb.AddForce(Vector3.up * 10, ForceMode.Impulse);
    73.         }
    74.         _oldPosition = transform.localPosition;
    75.     }
    76.     public override void Heuristic(in ActionBuffers actionsOut)
    77.     {
    78.         var continuousActions = actionsOut.ContinuousActions;
    79.  
    80.         var discreteActions = actionsOut.DiscreteActions;
    81.         continuousActions[0] = Input.GetAxis("Horizontal");
    82.         continuousActions[1] = Input.GetAxis("Vertical");
    83.         discreteActions[0] = Input.GetAxis("Jump") == 0 ? 0 : 1;
    84.     }
    85.     private void OnTriggerEnter(Collider other)
    86.     {
    87.         if (other.CompareTag("Target"))
    88.         {
    89.             AddReward(50f);
    90.         }
    91.         EndEpisode();
    92.     }
    93.     private void OnCollisionEnter(Collision collision)
    94.     {
    95.         _onGround = true;
    96.     }
    97.     private void OnCollisionExit(Collision collision)
    98.     {
    99.         _onGround = false;
    100.     }
    101. }
    102.  
    My Agent's object params in inspector on Google Drive
    https://drive.google.com/file/d/1f2jBTn1iC452LJCqGfnXisLXxhHJY_hN/view?usp=share_link
     
    Last edited: Jan 12, 2023
  2. garytrickett

    garytrickett

    Joined:
    Sep 2, 2018
    Posts:
    62
    your branch sizes are 1 in your inspector - meaning they can only hold 1 value (0 is the first result)
     
    Unity_knight likes this.
  3. Unity_knight

    Unity_knight

    Joined:
    Aug 22, 2021
    Posts:
    3
    It working bruh. Tysm man. but i tried it yesterday, and it wasn't work. Magic lol.
     
    Last edited: Jan 12, 2023
  4. garytrickett

    garytrickett

    Joined:
    Sep 2, 2018
    Posts:
    62
    are you using discrete branch 0 or 1 for jumping? your heuristics is set to use branch 0 and your ai actions is set to use branch 1

    make sure you can test your code is working in heuristics first, then the AI should be fine if it's using the same logic
     
  5. Unity_knight

    Unity_knight

    Joined:
    Aug 22, 2021
    Posts:
    3
    It's working in heuristics and I use discreteActions[0] for jumps.