Ervin Teng
4 年前
当前提交
d337e411
共有 15 个文件被更改,包括 1 次插入 和 1379 次删除
-
2Project/Assets/ML-Agents/Examples/PushBlock/Prefabs/DungeonEscapeAgent.prefab
-
289Project/Assets/ML-Agents/Examples/PushBlock/Scripts/ZombiePushBlockEnvController.cs
-
11Project/Assets/ML-Agents/Examples/PushBlock/Scripts/ZombiePushBlockEnvController.cs.meta
-
45Project/Assets/ML-Agents/Examples/PushBlock/Scripts/SimpleNPC.cs
-
11Project/Assets/ML-Agents/Examples/PushBlock/Scripts/SimpleNPC.cs.meta
-
11Project/Assets/ML-Agents/Examples/PushBlock/Scripts/ZombiePushBlockDeathEnvController.cs.meta
-
398Project/Assets/ML-Agents/Examples/PushBlock/Scripts/ZombiePushBlockDeathEnvController.cs
-
60Project/Assets/ML-Agents/Examples/PushBlock/Scripts/DoorSwitchTrigger.cs
-
11Project/Assets/ML-Agents/Examples/PushBlock/Scripts/DoorSwitchTrigger.cs.meta
-
143Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentZombie.cs
-
12Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentZombie.cs.meta
-
11Project/Assets/ML-Agents/Examples/PushBlock/Scripts/DungeonEscapeEnvController.cs.meta
-
12Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentEscape.cs.meta
-
231Project/Assets/ML-Agents/Examples/PushBlock/Scripts/DungeonEscapeEnvController.cs
-
133Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentEscape.cs
|
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using Unity.MLAgents; |
|||
using UnityEngine; |
|||
|
|||
public class ZombiePushBlockEnvController : MonoBehaviour |
|||
{ |
|||
[System.Serializable] |
|||
public class AgentInfo |
|||
{ |
|||
public PushAgentCollab Agent; |
|||
[HideInInspector] |
|||
public Vector3 StartingPos; |
|||
[HideInInspector] |
|||
public Quaternion StartingRot; |
|||
[HideInInspector] |
|||
public Rigidbody Rb; |
|||
public Collider Col; |
|||
} |
|||
|
|||
[System.Serializable] |
|||
public class ZombieInfo |
|||
{ |
|||
public SimpleNPC Agent; |
|||
[HideInInspector] |
|||
public Vector3 StartingPos; |
|||
[HideInInspector] |
|||
public Quaternion StartingRot; |
|||
[HideInInspector] |
|||
public Rigidbody Rb; |
|||
public Collider Col; |
|||
} |
|||
|
|||
[System.Serializable] |
|||
public class BlockInfo |
|||
{ |
|||
public Transform T; |
|||
[HideInInspector] |
|||
public Vector3 StartingPos; |
|||
[HideInInspector] |
|||
public Quaternion StartingRot; |
|||
[HideInInspector] |
|||
public Rigidbody Rb; |
|||
} |
|||
|
|||
/// <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<AgentInfo> AgentsList = new List<AgentInfo>(); |
|||
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; |
|||
|
|||
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>(); |
|||
foreach (var item in BlocksList) |
|||
{ |
|||
item.StartingPos = item.T.transform.position; |
|||
item.StartingRot = item.T.transform.rotation; |
|||
item.Rb = item.T.GetComponent<Rigidbody>(); |
|||
} |
|||
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>(); |
|||
} |
|||
foreach (var item in ZombiesList) |
|||
{ |
|||
item.StartingPos = item.Agent.transform.position; |
|||
item.StartingRot = item.Agent.transform.rotation; |
|||
item.Col = item.Agent.GetComponent<Collider>(); |
|||
} |
|||
|
|||
ResetScene(); |
|||
|
|||
} |
|||
|
|||
// Update is called once per frame
|
|||
void FixedUpdate() |
|||
{ |
|||
m_ResetTimer += 1; |
|||
if (m_ResetTimer > MaxEnvironmentSteps) |
|||
{ |
|||
ResetScene(); |
|||
} |
|||
} |
|||
|
|||
//Kill/disable an agent
|
|||
public void KillAgent(Collider col) |
|||
{ |
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
/// <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>
|
|||
/// Resets the block position and velocities.
|
|||
/// </summary>
|
|||
void ResetBlock(BlockInfo block) |
|||
{ |
|||
// Get a random position for the block.
|
|||
block.T.position = GetRandomSpawnPos(); |
|||
|
|||
// Reset block velocity back to zero.
|
|||
block.Rb.velocity = Vector3.zero; |
|||
|
|||
// Reset block angularVelocity back to zero.
|
|||
block.Rb.angularVelocity = Vector3.zero; |
|||
} |
|||
|
|||
|
|||
/// <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) |
|||
{ |
|||
// //Decrement the counter
|
|||
// m_NumberOfRemainingBlocks--;
|
|||
//
|
|||
// //Are we done?
|
|||
// bool done = m_NumberOfRemainingBlocks == 0;
|
|||
//
|
|||
// //Disable the block
|
|||
// col.gameObject.SetActive(false);
|
|||
|
|||
//Give Agent Rewards
|
|||
foreach (var item in AgentsList) |
|||
{ |
|||
item.Agent.AddReward(score); |
|||
} |
|||
|
|||
// Swap ground material for a bit to indicate we scored.
|
|||
StartCoroutine(GoalScoredSwapGroundMaterial(m_PushBlockSettings.goalScoredMaterial, 0.5f)); |
|||
|
|||
// if (done)
|
|||
// {
|
|||
//Reset assets
|
|||
ResetScene(); |
|||
// }
|
|||
} |
|||
|
|||
public void ZombieTouchedBlock() |
|||
{ |
|||
//Give Agent Rewards
|
|||
foreach (var item in AgentsList) |
|||
{ |
|||
item.Agent.AddReward(-1); |
|||
} |
|||
// 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() |
|||
{ |
|||
m_ResetTimer = 0; |
|||
|
|||
//Random platform rot
|
|||
var rotation = Random.Range(0, 4); |
|||
var rotationAngle = rotation * 90f; |
|||
area.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; |
|||
} |
|||
|
|||
//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); |
|||
} |
|||
//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(); |
|||
} |
|||
|
|||
//Reset counter
|
|||
m_NumberOfRemainingBlocks = BlocksList.Count; |
|||
// m_NumberOfRemainingBlocks = 2;
|
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 5e113b4a4dbb24eea8d143f2b168e161 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
// using System;
|
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
|
|||
public class SimpleNPC : MonoBehaviour |
|||
{ |
|||
|
|||
public Transform target; |
|||
|
|||
private Rigidbody rb; |
|||
|
|||
public float walkSpeed = 1; |
|||
// public ForceMode walkForceMode;
|
|||
private Vector3 dirToGo; |
|||
|
|||
// private Vector3 m_StartingPos;
|
|||
// Start is called before the first frame update
|
|||
void Awake() |
|||
{ |
|||
rb = GetComponent<Rigidbody>(); |
|||
// m_StartingPos = transform.position;
|
|||
} |
|||
|
|||
// Update is called once per frame
|
|||
void Update() |
|||
{ |
|||
} |
|||
|
|||
void FixedUpdate() |
|||
{ |
|||
dirToGo = target.position - transform.position; |
|||
dirToGo.y = 0; |
|||
rb.rotation = Quaternion.LookRotation(dirToGo); |
|||
// rb.AddForce(dirToGo.normalized * walkSpeed * Time.fixedDeltaTime, walkForceMode);
|
|||
// rb.MovePosition(rb.transform.TransformDirection(Vector3.forward * walkSpeed * Time.deltaTime));
|
|||
// rb.MovePosition(rb.transform.TransformVector() (Vector3.forward * walkSpeed * Time.deltaTime));
|
|||
rb.MovePosition(transform.position + transform.forward * walkSpeed * Time.deltaTime); |
|||
} |
|||
|
|||
public void SetRandomWalkSpeed() |
|||
{ |
|||
walkSpeed = Random.Range(1f, 7f); |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 9685bac759362440ea71765cdece3305 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 7df9fa4d08b7d4d198d5165b07ddd47e |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using Unity.MLAgents; |
|||
using UnityEngine; |
|||
|
|||
public class ZombiePushBlockDeathEnvController : MonoBehaviour |
|||
{ |
|||
[System.Serializable] |
|||
public class PlayerInfo |
|||
{ |
|||
public PushAgentZombie 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(0.1f); |
|||
|
|||
} |
|||
|
|||
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(PushAgentZombie 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); |
|||
} |
|||
|
|||
//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); |
|||
} |
|||
|
|||
|
|||
m_AgentGroup.EndGroupEpisode(); |
|||
|
|||
} |
|||
|
|||
// 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;
|
|||
// }
|
|||
} |
|
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
using UnityEngine.Events; |
|||
|
|||
public class DoorSwitchTrigger : MonoBehaviour |
|||
{ |
|||
|
|||
[Header("Trigger Collider Tag To Detect")] |
|||
public string tagToDetect = "agent"; //collider tag to detect
|
|||
|
|||
[Header("Goal Value")] |
|||
public float GoalValue = 1; |
|||
|
|||
private Collider m_col; |
|||
[System.Serializable] |
|||
public class TriggerEvent : UnityEvent<Collider, float> |
|||
{ |
|||
} |
|||
|
|||
[Header("Trigger Callbacks")] |
|||
public TriggerEvent onTriggerEnterEvent = new TriggerEvent(); |
|||
public TriggerEvent onTriggerStayEvent = new TriggerEvent(); |
|||
public TriggerEvent onTriggerExitEvent = new TriggerEvent(); |
|||
|
|||
private void OnTriggerEnter(Collider col) |
|||
{ |
|||
if (col.CompareTag(tagToDetect)) |
|||
{ |
|||
onTriggerEnterEvent.Invoke(m_col, GoalValue); |
|||
} |
|||
} |
|||
|
|||
private void OnTriggerStay(Collider col) |
|||
{ |
|||
if (col.CompareTag(tagToDetect)) |
|||
{ |
|||
onTriggerStayEvent.Invoke(m_col, GoalValue); |
|||
} |
|||
} |
|||
|
|||
private void OnTriggerExit(Collider col) |
|||
{ |
|||
if (col.CompareTag(tagToDetect)) |
|||
{ |
|||
onTriggerExitEvent.Invoke(m_col, GoalValue); |
|||
} |
|||
} |
|||
// Start is called before the first frame update
|
|||
void Awake() |
|||
{ |
|||
m_col = GetComponent<Collider>(); |
|||
} |
|||
|
|||
// Update is called once per frame
|
|||
void Update() |
|||
{ |
|||
|
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 5c64c5b8ad6c544739a1501a90819e05 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
//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 PushAgentZombie : Agent |
|||
{ |
|||
|
|||
public GameObject MyKey; |
|||
public bool IHaveAKey; |
|||
private PushBlockSettings m_PushBlockSettings; |
|||
private Rigidbody m_AgentRb; //cached on initialization
|
|||
private ZombiePushBlockDeathEnvController m_GameController; |
|||
|
|||
public override void Initialize() |
|||
{ |
|||
m_GameController = GetComponentInParent<ZombiePushBlockDeathEnvController>(); |
|||
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) |
|||
{ |
|||
m_GameController.UnlockBlock(col.transform); |
|||
MyKey.SetActive(false); |
|||
IHaveAKey = false; |
|||
} |
|||
} |
|||
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; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: d8aeb1e1df3e2469aa13d37bb4d1f000 |
|||
timeCreated: 1506829537 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 7f0d060d8c3074edf80fc69e847d4c60 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 78c960fbbc7844c269d4d14ae68abfc8 |
|||
timeCreated: 1506829537 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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 DragonInfo |
|||
{ |
|||
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; |
|||
} |
|||
|
|||
/// <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; |
|||
|
|||
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<DragonInfo> DragonsList = new List<DragonInfo>(); |
|||
|
|||
public bool UseRandomAgentRotation = true; |
|||
public bool UseRandomAgentPosition = true; |
|||
PushBlockSettings m_PushBlockSettings; |
|||
|
|||
private int m_NumberOfRemainingBlocks; |
|||
public GameObject Key; |
|||
|
|||
private SimpleMultiAgentGroup m_AgentGroup; |
|||
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>(); |
|||
|
|||
//Hide The Key
|
|||
Key.SetActive(false); |
|||
|
|||
// 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>(); |
|||
// Add to team manager
|
|||
m_AgentGroup.RegisterAgent(item.Agent); |
|||
} |
|||
foreach (var item in DragonsList) |
|||
{ |
|||
item.StartingPos = item.Agent.transform.position; |
|||
item.StartingRot = item.Agent.transform.rotation; |
|||
item.T = item.Agent.transform; |
|||
item.Col = item.Agent.GetComponent<Collider>(); |
|||
} |
|||
|
|||
ResetScene(); |
|||
} |
|||
|
|||
// Update is called once per frame
|
|||
void FixedUpdate() |
|||
{ |
|||
m_ResetTimer += 1; |
|||
if (m_ResetTimer >= MaxEnvironmentSteps && MaxEnvironmentSteps > 0) |
|||
{ |
|||
m_AgentGroup.GroupEpisodeInterrupted(); |
|||
ResetScene(); |
|||
} |
|||
} |
|||
|
|||
public void UnlockBlock(Transform blockT) |
|||
{ |
|||
m_AgentGroup.AddGroupReward(1f); |
|||
StartCoroutine(GoalScoredSwapGroundMaterial(m_PushBlockSettings.goalScoredMaterial, 0.5f)); |
|||
|
|||
print("Unlocked Door"); |
|||
m_AgentGroup.EndGroupEpisode(); |
|||
|
|||
ResetScene(); |
|||
} |
|||
|
|||
public void KilledByBaddie(PushAgentEscape agent, Collision baddieCol) |
|||
{ |
|||
baddieCol.gameObject.SetActive(false); |
|||
agent.EndEpisode(); |
|||
agent.gameObject.SetActive(false); |
|||
print($"{baddieCol.gameObject.name} ate {agent.transform.name}"); |
|||
//Spawn the Key Pickup
|
|||
Key.transform.SetPositionAndRotation(baddieCol.collider.transform.position, baddieCol.collider.transform.rotation); |
|||
Key.SetActive(true); |
|||
} |
|||
|
|||
/// <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; |
|||
} |
|||
|
|||
public void BaddieTouchedBlock() |
|||
{ |
|||
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 Key
|
|||
Key.SetActive(false); |
|||
|
|||
//End Episode
|
|||
foreach (var item in DragonsList) |
|||
{ |
|||
if (!item.Agent) |
|||
{ |
|||
return; |
|||
} |
|||
item.Agent.transform.SetPositionAndRotation(item.StartingPos, item.StartingRot); |
|||
item.Agent.SetRandomWalkSpeed(); |
|||
item.Agent.gameObject.SetActive(true); |
|||
} |
|||
} |
|||
} |
|
|||
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; |
|||
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.UnlockBlock(col.transform); |
|||
} |
|||
} |
|||
if (col.transform.CompareTag("dragon")) |
|||
{ |
|||
m_GameController.KilledByBaddie(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") && 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; |
|||
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; |
|||
} |
|||
} |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue