using UnityEngine; using Unity.MLAgents; using Unity.MLAgents.Sensors; using Unity.MLAgents.Actuators; public class PushAgentEscape : Agent { public GameObject MyKey; //my key gameobject. will be enabled when key picked up. public bool IHaveAKey; //have i picked up a key private PushBlockSettings m_PushBlockSettings; private Rigidbody m_AgentRb; private DungeonEscapeEnvController m_GameController; public override void Initialize() { m_GameController = GetComponentInParent(); m_AgentRb = GetComponent(); m_PushBlockSettings = FindObjectOfType(); MyKey.SetActive(false); IHaveAKey = false; } public override void OnEpisodeBegin() { MyKey.SetActive(false); IHaveAKey = false; } public override void CollectObservations(VectorSensor sensor) { sensor.AddObservation(IHaveAKey); } /// /// Moves the agent according to the selected action. /// public void MoveAgent(ActionSegment act) { var dirToGo = Vector3.zero; var rotateDir = Vector3.zero; var action = act[0]; switch (action) { case 1: dirToGo = transform.forward * 1f; break; case 2: dirToGo = transform.forward * -1f; break; case 3: rotateDir = transform.up * 1f; break; case 4: rotateDir = transform.up * -1f; break; case 5: dirToGo = transform.right * -0.75f; break; case 6: dirToGo = transform.right * 0.75f; break; } transform.Rotate(rotateDir, Time.fixedDeltaTime * 200f); m_AgentRb.AddForce(dirToGo * m_PushBlockSettings.agentRunSpeed, ForceMode.VelocityChange); } /// /// 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); } void OnCollisionEnter(Collision col) { if (col.transform.CompareTag("lock")) { if (IHaveAKey) { MyKey.SetActive(false); IHaveAKey = false; m_GameController.UnlockDoor(); } } if (col.transform.CompareTag("dragon")) { m_GameController.KilledByBaddie(this, col); MyKey.SetActive(false); IHaveAKey = false; } if (col.transform.CompareTag("portal")) { m_GameController.TouchedHazard(this); } } void OnTriggerEnter(Collider col) { //if we find a key and it's parent is the main platform we can pick it up if (col.transform.CompareTag("key") && col.transform.parent == transform.parent && gameObject.activeInHierarchy) { print("Picked up key"); MyKey.SetActive(true); IHaveAKey = true; col.gameObject.SetActive(false); } } public override void Heuristic(in ActionBuffers actionsOut) { var discreteActionsOut = actionsOut.DiscreteActions; if (Input.GetKey(KeyCode.D)) { discreteActionsOut[0] = 3; } else if (Input.GetKey(KeyCode.W)) { discreteActionsOut[0] = 1; } else if (Input.GetKey(KeyCode.A)) { discreteActionsOut[0] = 4; } else if (Input.GetKey(KeyCode.S)) { discreteActionsOut[0] = 2; } } }