ppo-Pyramids-Training
/
Project
/Assets
/ML-Agents
/Examples
/DungeonEscape
/Scripts
/PushAgentEscape.cs
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<DungeonEscapeEnvController>(); | |
m_AgentRb = GetComponent<Rigidbody>(); | |
m_PushBlockSettings = FindObjectOfType<PushBlockSettings>(); | |
MyKey.SetActive(false); | |
IHaveAKey = false; | |
} | |
public override void OnEpisodeBegin() | |
{ | |
MyKey.SetActive(false); | |
IHaveAKey = false; | |
} | |
public override void CollectObservations(VectorSensor sensor) | |
{ | |
sensor.AddObservation(IHaveAKey); | |
} | |
/// <summary> | |
/// Moves the agent according to the selected action. | |
/// </summary> | |
public void MoveAgent(ActionSegment<int> 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); | |
} | |
/// <summary> | |
/// Called every step of the engine. Here the agent takes an action. | |
/// </summary> | |
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; | |
} | |
} | |
} | |