using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// Spawns the specified prefab and positions it when a NavMeshSurface reports there's
/// a new NavMesh it can walk on. Used in the ZED spatial mapping sample scene to spawn a bunny
/// to walk around your environment once you're done scanning it.
///
public class EnemyManager : MonoBehaviour
{
///
/// The prefab used to spawn the enemy. Should contain a NavMeshAgent component.
///
[Tooltip("The prefab used to spawn the enemy. Should contain a NavMeshAgent component. ")]
public GameObject enemyPrefab;
///
/// Whether or not the NavMesh from the NavMeshSurface is ready.
///
private bool isReady = false;
///
/// Number of tries the script has attempted to place the prefab on the NavMesh. It stops trying at 20.
///
private int noNavMeshCount = 0;
///
/// Center of the current navMesh.
///
private Vector3 centerNavMesh;
///
/// ID of agent type accepted by the NavMesh. Agent IDs are defined in the Navigation window.
///
private int agentTypeNavMeshID = 0;
///
/// ID of the agent type from the prefab's NavMeshAgent component. Agent IDs are defined in the Navigation window.
///
private int agentType = 0;
///
/// List of all instantiated enemies.
///
static List enemies = new List();
void Update()
{
//Try to create an enemy on the NavMesh.
if (isReady && enemies.Count == 0 && noNavMeshCount < 20)
{
Create();
}
//Clear all the empty items
if (enemies.Count > 0)
{
enemies.RemoveAll(item => item == null);
}
}
///
/// Called when ZEDSpatialMapping begins making a new mesh, to clear existing enemies
/// and prevent the script from trying to place enemies.
/// Subscribed to ZEDSpatialMapping.OnMeshStarted in OnEnable().
///
void StartNavMesh()
{
//Clear all the enemies
Clear();
isReady = false;
}
private void OnEnable()
{
NavMeshSurface.OnNavMeshReady += Ready;
//Set the ZEDLight component on the object if a light is active
Component[] lights = enemyPrefab.GetComponentsInChildren(typeof(Light));
foreach (Light l in lights)
{
if (!l.gameObject.GetComponent())
{
l.gameObject.AddComponent();
}
}
}
private void Start()
{
StartNavMesh ();
UnityEngine.AI.NavMeshAgent c;
if ((c = enemyPrefab.GetComponent()) != null)
{
agentType = c.agentTypeID;
}
}
private void OnDisable()
{
//Unsubscribe from the events.
NavMeshSurface.OnNavMeshReady -= Ready;
}
///
/// Called when the NavMesh is finished being created, to clear existing data
/// and begin trying to place the enemy.
/// Subscribed to NavMeshSurface.OnNavMeshReady in OnEnable().
///
///
///
void Ready(object sender, NavMeshSurface.PositionEventArgs e)
{
centerNavMesh = e.position;
isReady = e.valid;
agentTypeNavMeshID = e.agentTypeID;
Clear();
}
public void Ready()
{
isReady = true;
Clear();
}
///
/// Destroy all the enemies and clear its container
///
void Clear()
{
foreach (GameObject o in enemies)
{
Destroy(o);
}
enemies.Clear();
}
///
/// Remove a particular GameObject
///
///
static void Destroyed(GameObject o)
{
enemies.Remove(o);
}
///
/// Try to create an agent on the NavMesh.
///
public void Create()
{
//If the agent and the NavMesh have different agent IDs, don't assign it.
if (agentType != agentTypeNavMeshID)
{
Debug.LogWarning("The agent ID differs from the NavMesh");
return;
}
//Instantiate the prefab and try to place it on the NavMesh.
enemies.Add(Instantiate(enemyPrefab, centerNavMesh, Quaternion.identity));
List notActivated = new List();
//For each enemy created, move it on the NavMesh.
foreach (GameObject o in enemies)
{
NavMeshAgentController a = o.GetComponent();
if (a.Move())
{
a.GetComponent().Activate();
noNavMeshCount = 0;
}
else
{
notActivated.Add(a.gameObject);
noNavMeshCount++;
}
}
//Destroy any objects that were not properly added to the NavMesh.
foreach (GameObject o in notActivated)
{
Destroy(o);
enemies.Remove(o);
}
}
}