 
      まずターミナルを起動し、ML-Agents Toolkitを任意の場所にクローンします。
次にUnityの新しい3Dプロジェクトを作成します。
プロジェクトが開いたら、Window→Package Managerをクリックし「+」からAdd package from disk...を選択します。
 
        クローンしたml-agents→com.unity.ml-agents→package.jsonを選択します。
①床を追加
・Hierarchyウィンドウで右クリックし、3D Object→Planeを選択します。
・Planeを選択しInspectorで名前をFloorに変更します。
・Transformの値がPosition(0,0,0)、Rotation(0,0,0)、Scale(1,1,1)になっていることを確認します。
 
        ②キューブを追加
・Hierarchyウィンドウで右クリックし、3D Object→Cubeを選択します。
・Cubeを選択しInspectorで名前をTargetに変更します。
・Transformの値をPosition(3,0.5,3)、Rotation(0,0,0)、Scale(1,1,1)に設定します。
 
        ③スフィアを追加
・Hierarchyウィンドウで右クリックし、3D Object→Sphereを選択します。
・Sphereを選択しInspectorで名前をRollerAgentに変更します。
・Transformの値をPosition(0,0.5,0)、Rotation(0,0,0)、Scale(1,1,1)に設定します。
・Add ComponentからRigidbodyを追加します。
 
        ④ゲームオブジェクトをグループ化
・Hierarchyウィンドウで右クリックし、Create Emptyを選択します。
・GameObjectを選択しInspectorで名前をTrainingAreaに変更します。
・Transformの値をPosition(0,0,0)、Rotation(0,0,0)、Scale(1,1,1)に設定します。
Floor、Target、RollerAgentをTrainingAreaにドラッグします。
 
      ①RollerAgent→Add Componentで適当な名前のスクリプトを追加します。ここではRollerAgentという名前のスクリプトを作成しました。
作成したスクリプトに下のコードを貼り付けます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//MLAgentsを使えるように名前空間を追加
using Unity.MLAgents;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Actuators;
//MonoBehaviourをAgentに変更
public class RollerAgent : Agent
{
    public Transform Target;
    Rigidbody rBody;
    public float forceMultiplier = 10;
    void Start()
    {
        rBody = GetComponent<Rigidbody>();
    }
    //エピソードの開始
    public override void OnEpisodeBegin()
    {
     //Agentが落ちた時の処理
      if (this.transform.localPosition.y < 0)
        {
          //Agentの回転を止める
            this.rBody.angularVelocity = Vector3.zero;
          //Agentの速度を0にする
            this.rBody.velocity = Vector3.zero;
          //Agentの位置を初期位置に戻す
            this.transform.localPosition = new Vector3(0,0.5f,0);
        }
      //Targetの新しい位置
      Target.localPosition = new Vector3(Random.value * 8 - 4,0.5f,Random.value * 8 - 4);
    }
    //環境の情報を収集
    public override void CollectObservations(VectorSensor sensor)
  {
    //TargetとAgentの位置
     sensor.AddObservation(Target.localPosition);
     sensor.AddObservation(this.transform.localPosition);
    //Agentの速度
     sensor.AddObservation(rBody.velocity.x);
     sensor.AddObservation(rBody.velocity.z);
  }
    //Agentの移動と報酬
    public override void OnActionReceived(ActionBuffers actionBuffers)
   {
    //Agentを移動させる
    Vector3 controlSignal = Vector3.zero;
    controlSignal.x = actionBuffers.ContinuousActions[0];
    controlSignal.z = actionBuffers.ContinuousActions[1];
    rBody.AddForce(controlSignal * forceMultiplier);
   //TargetとAgentの距離を取得
   float distanceToTarget = Vector3.Distance(this.transform.localPosition, Target.localPosition);
   //TargetとAgentの距離が1.42より小さい場合、1.0の報酬を与えてエピソードを終了する
   if (distanceToTarget < 1.42f)
   {
       SetReward(1.0f);
       EndEpisode();
   }
   //Agentが床から落ちたらエピソードを終了する
   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");
   }
}
②RollerAgentのTargetにHierarchyのTargetをドラッグします。
 
        ③Add ComponentからBehavior Parametersを追加し、
・Behavior NameをRollerBallに変更します。
・Vector ObservationのSpace Sizeを8に変更します。
・ActionsのContinuous Actionsを2に変更します。
・Discrete Branchesを0に変更します。
・ModelのInference DeviceをCPUに変更します。
 
        ④Add ComponentからDecision Requesterを追加し、Decision Periodを10に変更します
 
        RollerAgentのBehavior ParametersのBehavior TypeをHeuristic Onlyに変更して、Unityエディターを再生したら、RollerAgentが矢印キーで操作できるのでRollerAgentが落下した時、Targetに接近した時の動作を確認します。
正しく動作していることが確認できたら、Behavior TypeをDefaultに戻しておきます。
クローンしたml-agentsのファイル→configファイルにrollerball_config.yamlファイルを作成します
 
        rollerball_config.yamlファイルに下のコードを貼り付けます。
behaviors:
  RollerBall:
    trainer_type: ppo
    hyperparameters:
      batch_size: 10
      buffer_size: 100
      learning_rate: 3.0e-4
      beta: 5.0e-4
      epsilon: 0.2
      lambd: 0.99
      num_epoch: 3
      learning_rate_schedule: linear
      beta_schedule: constant
      epsilon_schedule: linear
    network_settings:
      normalize: false
      hidden_units: 128
      num_layers: 2
    reward_signals:
      extrinsic:
        gamma: 0.99
        strength: 1.0
    max_steps: 500000
    time_horizon: 64
    summary_freq: 10000
yamlファイルの詳細は、下のGitHubのページで確認することができます。
①ターミナルでPythonのバージョンが3.6.1以降であることを確認します。
②サンプルを学習させるために仮想環境を使うのでターミナルを立ち上げて任意の場所にディレクトリを作ってください。今回はSampleという名前のディレクトリを作りました。
③cdコマンドでSampleに移動した後、今回使う新しい環境を作成します。ここでは、learning-envという名前の仮想環境を作成しました。
④仮想環境が作成できたら、作成した仮想環境を有効化します。
⑤仮想環境を有効化している状態でpipとsetuptoolsをアップグレードします。
⑥mlagentsPythonパッケージをインストールします。
⑦importlib-metadataのバージョンを変更します。
仮想環境は$ deactivateで終了することができます。
仮想環境を有効化している状態でターミナルでcdコマンドを使い、クローンしたml-agentsのファイルに移動します。移動できたら下のコマンドを入力します。
(--run-id=の「RollerBall」は好きに変えてもらっても大丈夫です。)
ターミナルにUnityのロゴが表示されたら、Unityエディターで再生をクリックします。
問題なく動作すれば学習が開始されます。
学習はターミナルでCtrl+Cを実行することで終了させることができます。
学習させたモデルはクローンしたml-agentsのresultsの中の保存されます。今回は、resultsにRollerBallというディレクトリが作成されているはずなので、そのディレクトリの中のRollerBall.onnxをUnityのProjectウィンドウのAssetsにドラッグアンドドロップします。
次に、RollerAgentのBehaviorParametersのModelにRollerBall.onnxをドラッグします。
 
        その状態でUnityエディターを再生すると、学習させたモデルを使うことができます。