浏览代码

Add DungeonEscape env

/develop/pushcollabonly
HH 3 年前
当前提交
700af652
共有 13 个文件被更改,包括 2603 次插入6 次删除
  1. 2
      Project/Assets/ML-Agents/Examples/PushBlock/Prefabs/PushBlockAgentGridZombie.prefab
  2. 3
      Project/Assets/ML-Agents/Examples/PushBlock/Prefabs/ZombiePushBlockWithLocksPlatform.prefab
  3. 6
      Project/Assets/ML-Agents/Examples/PushBlock/Scenes/ZombiePushBlock.unity
  4. 1
      Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentZombie.cs
  5. 9
      Project/Assets/ML-Agents/Examples/PushBlock/Scripts/ZombiePushBlockDeathEnvController.cs
  6. 1001
      Project/Assets/ML-Agents/Examples/PushBlock/Prefabs/DungeonEscapePlatform.prefab
  7. 7
      Project/Assets/ML-Agents/Examples/PushBlock/Prefabs/DungeonEscapePlatform.prefab.meta
  8. 1001
      Project/Assets/ML-Agents/Examples/PushBlock/Scenes/DungeonEscape.unity
  9. 9
      Project/Assets/ML-Agents/Examples/PushBlock/Scenes/DungeonEscape.unity.meta
  10. 404
      Project/Assets/ML-Agents/Examples/PushBlock/Scripts/DungeonEscapeEnvController.cs
  11. 11
      Project/Assets/ML-Agents/Examples/PushBlock/Scripts/DungeonEscapeEnvController.cs.meta
  12. 143
      Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentEscape.cs
  13. 12
      Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentEscape.cs.meta

2
Project/Assets/ML-Agents/Examples/PushBlock/Prefabs/PushBlockAgentGridZombie.prefab


m_Name:
m_EditorClassIdentifier:
m_BrainParameters:
VectorObservationSize: 1
VectorObservationSize: 2
NumStackedVectorObservations: 1
m_ActionSpec:
m_NumContinuousActions: 0

3
Project/Assets/ML-Agents/Examples/PushBlock/Prefabs/ZombiePushBlockWithLocksPlatform.prefab


m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 439129354807280141}
serializedVersion: 2
m_Mass: 50
m_Mass: 15
m_Drag: 0.5
m_AngularDrag: 0.05
m_UseGravity: 1

Key: {fileID: 3288169921762018350}
LockedBlock: {fileID: 8550896088730156840}
UnlockedBlock: {fileID: 7898128147621382802}
BlockIsLocked: 0
--- !u!1 &8550896088526703259
GameObject:
m_ObjectHideFlags: 0

6
Project/Assets/ML-Agents/Examples/PushBlock/Scenes/ZombiePushBlock.unity


m_Name:
m_EditorClassIdentifier:
gravityMultiplier: 1.5
fixedDeltaTime: 0.01333
fixedDeltaTime: 0.02
solverIterations: 12
solverVelocityIterations: 12
solverIterations: 6
solverVelocityIterations: 1
reuseCollisionCallbacks: 1
--- !u!4 &1574236049
Transform:

1
Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentZombie.cs


// if (useVectorObs)
// {
sensor.AddObservation(IHaveAKey);
sensor.AddObservation(m_GameController.BlockIsLocked);
// sensor.AddObservation(m_GameController.PlayerDict[this].HoldingSwitch);
// sensor.AddObservation(m_GameController.PlayerDict[this].Scored);
// }

9
Project/Assets/ML-Agents/Examples/PushBlock/Scripts/ZombiePushBlockDeathEnvController.cs


public Dictionary<Transform, ZombieInfo> m_ZombiesDict = new Dictionary<Transform, ZombieInfo>();
// public Dictionary<Transform, BlockInfo> m_BlocksDict = new Dictionary<Transform, BlockInfo>();
private SimpleMultiAgentGroup m_AgentGroup;
public bool BlockIsLocked;
void Start()
{

m_AgentGroup.GroupEpisodeInterrupted();
ResetScene();
}
//Hurry Up Penalty
m_AgentGroup.AddGroupReward(-0.5f / MaxEnvironmentSteps);
}
// // public Dictionary<Agent>

UnlockedBlock.angularVelocity = Vector3.zero;
UnlockedBlock.transform.SetPositionAndRotation(blockT.position, blockT.rotation);
UnlockedBlock.gameObject.SetActive(true);
BlockIsLocked = false;
m_AgentGroup.AddGroupReward(0.1f);
}
public void LockTheBlock()

UnlockedBlock.angularVelocity = Vector3.zero;
UnlockedBlock.transform.SetPositionAndRotation(LockedBlock.transform.position, LockedBlock.transform.rotation);
UnlockedBlock.gameObject.SetActive(false);
BlockIsLocked = true;
}
public void KilledByZombie(PushAgentZombie agent, Collision zombCol)

1001
Project/Assets/ML-Agents/Examples/PushBlock/Prefabs/DungeonEscapePlatform.prefab
文件差异内容过多而无法显示
查看文件

7
Project/Assets/ML-Agents/Examples/PushBlock/Prefabs/DungeonEscapePlatform.prefab.meta


fileFormatVersion: 2
guid: 5878a6d7527854d0a84b133c7c6efe55
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

1001
Project/Assets/ML-Agents/Examples/PushBlock/Scenes/DungeonEscape.unity
文件差异内容过多而无法显示
查看文件

9
Project/Assets/ML-Agents/Examples/PushBlock/Scenes/DungeonEscape.unity.meta


fileFormatVersion: 2
guid: d00d2995d83c94f5da81bb19644a00ac
timeCreated: 1506808980
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

404
Project/Assets/ML-Agents/Examples/PushBlock/Scripts/DungeonEscapeEnvController.cs


using System.Collections;
using System.Collections.Generic;
using Unity.MLAgents;
using UnityEngine;
public class DungeonEscapeEnvController : MonoBehaviour
{
[System.Serializable]
public class PlayerInfo
{
public PushAgentEscape Agent;
[HideInInspector]
public Vector3 StartingPos;
[HideInInspector]
public Quaternion StartingRot;
[HideInInspector]
public Rigidbody Rb;
[HideInInspector]
public Collider Col;
}
[System.Serializable]
public class ZombieInfo
{
public SimpleNPC Agent;
[HideInInspector]
public Vector3 StartingPos;
[HideInInspector]
public Quaternion StartingRot;
[HideInInspector]
public Rigidbody Rb;
[HideInInspector]
public Collider Col;
public Transform T;
public bool IsDead;
}
// [System.Serializable]
// public class BlockInfo
// {
// public Transform T;
// [HideInInspector]
// public Vector3 StartingPos;
// [HideInInspector]
// public Quaternion StartingRot;
// [HideInInspector]
// public Rigidbody Rb;
// public Transform LockedBlock;
// }
/// <summary>
/// Max Academy steps before this platform resets
/// </summary>
/// <returns></returns>
[Header("Max Environment Steps")] public int MaxEnvironmentSteps = 25000;
private int m_ResetTimer;
/// <summary>
/// The area bounds.
/// </summary>
[HideInInspector]
public Bounds areaBounds;
/// <summary>
/// The ground. The bounds are used to spawn the elements.
/// </summary>
public GameObject ground;
// public GameObject area;
Material m_GroundMaterial; //cached on Awake()
/// <summary>
/// We will be changing the ground material based on success/failue
/// </summary>
Renderer m_GroundRenderer;
public List<PlayerInfo> AgentsList = new List<PlayerInfo>();
public List<ZombieInfo> ZombiesList = new List<ZombieInfo>();
// public List<BlockInfo> BlocksList = new List<BlockInfo>();
public bool UseRandomAgentRotation = true;
public bool UseRandomAgentPosition = true;
// public bool UseRandomBlockRotation = true;
// public bool UseRandomBlockPosition = true;
PushBlockSettings m_PushBlockSettings;
private int m_NumberOfRemainingBlocks;
public GameObject Key;
public GameObject LockedBlock;
// public Rigidbody UnlockedBlock;
public Dictionary<Transform, PlayerInfo> m_AgentsDict = new Dictionary<Transform, PlayerInfo>();
public Dictionary<Transform, ZombieInfo> m_ZombiesDict = new Dictionary<Transform, ZombieInfo>();
// public Dictionary<Transform, BlockInfo> m_BlocksDict = new Dictionary<Transform, BlockInfo>();
private SimpleMultiAgentGroup m_AgentGroup;
// public bool BlockIsLocked;
void Start()
{
// Get the ground's bounds
areaBounds = ground.GetComponent<Collider>().bounds;
// Get the ground renderer so we can change the material when a goal is scored
m_GroundRenderer = ground.GetComponent<Renderer>();
// Starting material
m_GroundMaterial = m_GroundRenderer.material;
m_PushBlockSettings = FindObjectOfType<PushBlockSettings>();
// //Lock The Block
// LockTheBlock();
//Hide The Key
Key.SetActive(false);
// foreach (var item in BlocksList)
// {
// item.StartingPos = item.T.transform.position;
// item.StartingRot = item.T.transform.rotation;
// item.Rb = item.T.GetComponent<Rigidbody>();
// m_BlocksDict.Add(item.T, item);
// }
// Initialize TeamManager
m_AgentGroup = new SimpleMultiAgentGroup();
foreach (var item in AgentsList)
{
item.StartingPos = item.Agent.transform.position;
item.StartingRot = item.Agent.transform.rotation;
item.Rb = item.Agent.GetComponent<Rigidbody>();
item.Col = item.Agent.GetComponent<Collider>();
m_AgentsDict.Add(item.Agent.transform, item);
// Add to team manager
m_AgentGroup.RegisterAgent(item.Agent);
}
foreach (var item in ZombiesList)
{
item.StartingPos = item.Agent.transform.position;
item.StartingRot = item.Agent.transform.rotation;
item.T = item.Agent.transform;
item.Col = item.Agent.GetComponent<Collider>();
m_ZombiesDict.Add(item.T, item);
}
ResetScene();
}
// Update is called once per frame
void FixedUpdate()
{
m_ResetTimer += 1;
if (m_ResetTimer >= MaxEnvironmentSteps && MaxEnvironmentSteps > 0)
{
m_AgentGroup.GroupEpisodeInterrupted();
ResetScene();
}
//Hurry Up Penalty
// m_AgentGroup.AddGroupReward(-0.5f / MaxEnvironmentSteps);
}
// // public Dictionary<Agent>
// //Kill/disable an agent
// public void KillAgent(Collision col, Transform t)
// {
// print($"zombie {t.name} ate {col.collider.name}");
// //Disable killed Agent
// foreach (var item in AgentsList)
// {
// if (item.Col == col.collider)
// {
// item.Agent.EndEpisode();
// item.Col.gameObject.SetActive(false);
// break;
// }
// }
//
// //End Episode
// foreach (var item in ZombiesList)
// {
// if (item.Agent.transform == t)
// {
// KillZombie(item);
// break;
// }
// }
// }
public void UnlockBlock(Transform blockT)
{
// LockedBlock.SetActive(false);
// UnlockedBlock.velocity = Vector3.zero;
// UnlockedBlock.angularVelocity = Vector3.zero;
// UnlockedBlock.transform.SetPositionAndRotation(blockT.position, blockT.rotation);
// UnlockedBlock.gameObject.SetActive(true);
// BlockIsLocked = false;
m_AgentGroup.AddGroupReward(1f);
StartCoroutine(GoalScoredSwapGroundMaterial(m_PushBlockSettings.goalScoredMaterial, 0.5f));
print("Unlocked Door");
m_AgentGroup.EndGroupEpisode();
ResetScene();
}
// public void LockTheBlock()
// {
// LockedBlock.SetActive(true);
// // UnlockedBlock.velocity = Vector3.zero;
// // UnlockedBlock.angularVelocity = Vector3.zero;
// // UnlockedBlock.transform.SetPositionAndRotation(LockedBlock.transform.position, LockedBlock.transform.rotation);
// // UnlockedBlock.gameObject.SetActive(false);
// BlockIsLocked = true;
// }
public void KilledByZombie(PushAgentEscape agent, Collision zombCol)
{
zombCol.gameObject.SetActive(false);
agent.EndEpisode();
agent.gameObject.SetActive(false);
print($"zombie {zombCol.gameObject.name} ate {agent.transform.name}");
//Spawn the Key Pickup
Key.transform.SetPositionAndRotation(zombCol.collider.transform.position, zombCol.collider.transform.rotation);
Key.SetActive(true);
// Instantiate(KeyPrefab, zombCol.collider.transform.position, zombCol.collider.transform.rotation, transform);
}
/// <summary>
/// Use the ground's bounds to pick a random spawn position.
/// </summary>
public Vector3 GetRandomSpawnPos()
{
var foundNewSpawnLocation = false;
var randomSpawnPos = Vector3.zero;
while (foundNewSpawnLocation == false)
{
var randomPosX = Random.Range(-areaBounds.extents.x * m_PushBlockSettings.spawnAreaMarginMultiplier,
areaBounds.extents.x * m_PushBlockSettings.spawnAreaMarginMultiplier);
var randomPosZ = Random.Range(-areaBounds.extents.z * m_PushBlockSettings.spawnAreaMarginMultiplier,
areaBounds.extents.z * m_PushBlockSettings.spawnAreaMarginMultiplier);
randomSpawnPos = ground.transform.position + new Vector3(randomPosX, 1f, randomPosZ);
if (Physics.CheckBox(randomSpawnPos, new Vector3(2.5f, 0.01f, 2.5f)) == false)
{
foundNewSpawnLocation = true;
}
}
return randomSpawnPos;
}
/// <summary>
/// Swap ground material, wait time seconds, then swap back to the regular material.
/// </summary>
IEnumerator GoalScoredSwapGroundMaterial(Material mat, float time)
{
m_GroundRenderer.material = mat;
yield return new WaitForSeconds(time); // Wait for 2 sec
m_GroundRenderer.material = m_GroundMaterial;
}
/// <summary>
/// Called when the agent moves the block into the goal.
/// </summary>
public void ScoredAGoal(Collider col, float score)
{
print($"Scored {score} on {gameObject.name}");
//Give Agent Rewards
m_AgentGroup.AddGroupReward(score);
// m_AgentGroup.EndGroupEpisode();
// Swap ground material for a bit to indicate we scored.
StartCoroutine(GoalScoredSwapGroundMaterial(m_PushBlockSettings.goalScoredMaterial, 0.5f));
ResetScene();
}
public void ZombieTouchedBlock()
{
//Give Agents Penalties
// m_AgentGroup.AddGroupReward(-1);
m_AgentGroup.EndGroupEpisode();
// Swap ground material for a bit to indicate we scored.
StartCoroutine(GoalScoredSwapGroundMaterial(m_PushBlockSettings.failMaterial, 0.5f));
ResetScene();
}
Quaternion GetRandomRot()
{
return Quaternion.Euler(0, Random.Range(0.0f, 360.0f), 0);
}
void ResetScene()
{
//Reset counter
m_ResetTimer = 0;
//Random platform rot
var rotation = Random.Range(0, 4);
var rotationAngle = rotation * 90f;
transform.Rotate(new Vector3(0f, rotationAngle, 0f));
//Reset Agents
foreach (var item in AgentsList)
{
var pos = UseRandomAgentPosition ? GetRandomSpawnPos() : item.StartingPos;
var rot = UseRandomAgentRotation ? GetRandomRot() : item.StartingRot;
item.Agent.transform.SetPositionAndRotation(pos, rot);
item.Rb.velocity = Vector3.zero;
item.Rb.angularVelocity = Vector3.zero;
item.Agent.MyKey.SetActive(false);
item.Agent.IHaveAKey = false;
item.Agent.gameObject.SetActive(true);
m_AgentGroup.RegisterAgent(item.Agent);
}
//Reset Blocks
// LockedBlock.transform.position = GetRandomSpawnPos();
// LockedBlock.transform.rotation = GetRandomRot();
// LockTheBlock();
//Reset Key
Key.SetActive(false);
//End Episode
foreach (var item in ZombiesList)
{
if (!item.Agent)
{
return;
}
// item.Agent.EndEpisode();
item.Agent.transform.SetPositionAndRotation(item.StartingPos, item.StartingRot);
item.Agent.SetRandomWalkSpeed();
item.Agent.gameObject.SetActive(true);
}
}
// void ResetScene()
// {
// m_ResetTimer = 0;
//
// //Random platform rot
// var rotation = Random.Range(0, 4);
// var rotationAngle = rotation * 90f;
// transform.Rotate(new Vector3(0f, rotationAngle, 0f));
//
// //End Episode
// foreach (var item in AgentsList)
// {
// if (!item.Agent)
// {
// return;
// }
// item.Agent.EndEpisode();
// }
// //Reset Agents
// foreach (var item in AgentsList)
// {
// var pos = UseRandomAgentPosition ? GetRandomSpawnPos() : item.StartingPos;
// var rot = UseRandomAgentRotation ? GetRandomRot() : item.StartingRot;
//
// item.Agent.transform.SetPositionAndRotation(pos, rot);
// item.Rb.velocity = Vector3.zero;
// item.Rb.angularVelocity = Vector3.zero;
// item.Agent.gameObject.SetActive(true);
// }
//
// //Reset Blocks
// foreach (var item in BlocksList)
// {
// var pos = UseRandomBlockPosition ? GetRandomSpawnPos() : item.StartingPos;
// var rot = UseRandomBlockRotation ? GetRandomRot() : item.StartingRot;
//
// item.T.transform.SetPositionAndRotation(pos, rot);
// item.Rb.velocity = Vector3.zero;
// item.Rb.angularVelocity = Vector3.zero;
// item.T.gameObject.SetActive(true);
// // BlockIsLocked(item, true);
// }
// //End Episode
// foreach (var item in ZombiesList)
// {
// if (!item.Agent)
// {
// return;
// }
// // item.Agent.EndEpisode();
// item.Agent.transform.SetPositionAndRotation(item.StartingPos, item.StartingRot);
// item.Agent.SetRandomWalkSpeed();
// item.Agent.gameObject.SetActive(true);
// }
//
// //Reset counter
// m_NumberOfRemainingBlocks = BlocksList.Count;
// // m_NumberOfRemainingBlocks = 2;
// }
}

11
Project/Assets/ML-Agents/Examples/PushBlock/Scripts/DungeonEscapeEnvController.cs.meta


fileFormatVersion: 2
guid: 7f0d060d8c3074edf80fc69e847d4c60
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

143
Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentEscape.cs


//Put this script on your blue cube.
using System.Collections;
using UnityEngine;
using Unity.MLAgents;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Actuators;
public class PushAgentEscape : Agent
{
public GameObject MyKey;
public bool IHaveAKey;
private PushBlockSettings m_PushBlockSettings;
private Rigidbody m_AgentRb; //cached on initialization
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)
{
// if (useVectorObs)
// {
sensor.AddObservation(IHaveAKey);
// sensor.AddObservation(m_GameController.BlockIsLocked);
// sensor.AddObservation(m_GameController.PlayerDict[this].HoldingSwitch);
// sensor.AddObservation(m_GameController.PlayerDict[this].Scored);
// }
}
/// <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.UnlockBlock(col.transform);
}
}
if (col.transform.CompareTag("zombie"))
{
m_GameController.KilledByZombie(this, col);
MyKey.SetActive(false);
IHaveAKey = false;
}
}
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"))
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);
// DestroyImmediate(col.gameObject);
}
}
public override void Heuristic(in ActionBuffers actionsOut)
{
var discreteActionsOut = actionsOut.DiscreteActions;
discreteActionsOut[0] = 0;
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;
}
}
}

12
Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentEscape.cs.meta


fileFormatVersion: 2
guid: 78c960fbbc7844c269d4d14ae68abfc8
timeCreated: 1506829537
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存