//Put this script on your blue cube. using System.Collections; using UnityEngine; using Unity.MLAgents; using Unity.MLAgents.Actuators; using Unity.MLAgents.Sensors; public class PushAgentCollab : Agent { PushBlockSettings m_PushBlockSettings; // Rigidbody m_BlockRb; //cached on initialization Rigidbody m_AgentRb; //cached on initialization public bool useVectorObs = true; void Awake() { m_PushBlockSettings = FindObjectOfType(); } public override void Initialize() { // Cache the agent rigidbody m_AgentRb = GetComponent(); } /// /// Moves the agent according to the selected action. /// public void MoveAgent(ActionSegment act) { var dirToGo = Vector3.zero; var rotateDir = Vector3.zero; var forwardAxis = act[0]; var rightAxis = act[1]; var rotateAxis = act[2]; switch (forwardAxis) { case 1: dirToGo = transform.forward * 1f; break; case 2: dirToGo = transform.forward * -1f; break; } switch (rightAxis) { case 1: dirToGo = transform.right * 1f; break; case 2: dirToGo = transform.right * -1f; break; } switch (rotateAxis) { case 1: rotateDir = transform.up * -1f; break; case 2: rotateDir = transform.up * 1f; break; } transform.Rotate(rotateDir, Time.fixedDeltaTime * 200f); m_AgentRb.AddForce(dirToGo * m_PushBlockSettings.agentRunSpeed, ForceMode.VelocityChange); } public override void CollectObservations(VectorSensor sensor) { if (useVectorObs) { sensor.AddObservation(StepCount / (float)MaxStep); } } /// /// Called every step of the engine. Here the agent takes an action. /// public override void OnActionReceived(ActionBuffers actionBuffers) { // Move the agent using the action. MoveAgent(actionBuffers.DiscreteActions); // Penalty given each step to encourage agent to finish task quickly. //AddReward(-1f / MaxStep); } public override void Heuristic(in ActionBuffers actionsOut) { var discreteActionsOut = actionsOut.DiscreteActions; discreteActionsOut.Clear(); //forward if (Input.GetKey(KeyCode.W)) { discreteActionsOut[0] = 1; } if (Input.GetKey(KeyCode.S)) { discreteActionsOut[0] = 2; } //rotate if (Input.GetKey(KeyCode.A)) { discreteActionsOut[2] = 1; } if (Input.GetKey(KeyCode.D)) { discreteActionsOut[2] = 2; } //right if (Input.GetKey(KeyCode.E)) { discreteActionsOut[1] = 1; } if (Input.GetKey(KeyCode.Q)) { discreteActionsOut[1] = 2; } } /// /// In the editor, if "Reset On Done" is checked then AgentReset() will be /// called automatically anytime we mark done = true in an agent script. /// public override void OnEpisodeBegin() { } }