181 lines
6.7 KiB
C#
181 lines
6.7 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Passer {
|
|
using Humanoid;
|
|
|
|
/// <summary>
|
|
/// Component for spawning objects
|
|
/// </summary>
|
|
public class Spawner : SpawnPoint {
|
|
|
|
/// <summary>
|
|
/// The prefab which will be spawned
|
|
/// </summary>
|
|
public GameObject prefab;
|
|
|
|
/// <summary>
|
|
/// The available SpawnPoints.
|
|
/// </summary>
|
|
/// When the list is empty, the scene will be searched for available spawn points when it becomes enabled.
|
|
/// If no spawn points can be found, this transform will be used as a SpawnPoint
|
|
public SpawnPoint[] spawnPoints;
|
|
|
|
/// <summary>
|
|
/// The SpawnMethod to use for spawning the humanoids.
|
|
/// </summary>
|
|
public SpawnMethod spawnMethod;
|
|
/// <summary>
|
|
/// Spawning methods.
|
|
/// </summary>
|
|
public enum SpawnMethod {
|
|
SinglePlayer, ///< Only one humanoid will be spawned. It will be located at the first SpawnPoint.
|
|
Random, ///< A SpawnPoint is chosen randomly.
|
|
RoundRobin ///< Spawn points are chosen in round robin manner.
|
|
}
|
|
protected int spawnIndex = 0;
|
|
|
|
/// <summary>
|
|
/// Spawn an object when the scene starts
|
|
/// </summary>
|
|
public bool spawnAtStart;
|
|
|
|
/// <summary>
|
|
/// Will spawn only one object for this prefab
|
|
/// </summary>
|
|
/// When spawn is called a second time for the same prefab, the original spawned object
|
|
/// will be teleported to the new spawn point
|
|
public bool singleInstance;
|
|
// used for uniqueObject
|
|
private GameObject lastPrefabInstance;
|
|
|
|
protected virtual void OnEnable() {
|
|
if (spawnPoints != null && spawnPoints.Length > 0)
|
|
return;
|
|
|
|
spawnPoints = FindObjectsOfType<SpawnPoint>();
|
|
if (spawnPoints.Length == 0) {
|
|
SpawnPoint thisSpawnPoint = this.gameObject.AddComponent<SpawnPoint>();
|
|
spawnPoints = new SpawnPoint[] { thisSpawnPoint };
|
|
}
|
|
}
|
|
|
|
protected virtual void Start() {
|
|
if (spawnAtStart)
|
|
SpawnObject();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Spawn one GameObject using the Spawner settings.
|
|
/// </summary>
|
|
/// <returns>The instantiated GameObject. Will be null when the prefab could not be instantiated.</returns>
|
|
public virtual GameObject SpawnObject() {
|
|
if (prefab == null)
|
|
return null;
|
|
|
|
return Instantiate(prefab, transform.position, transform.rotation);
|
|
}
|
|
|
|
public void DoSpawn(GameObject prefab) {
|
|
Spawn(prefab);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Spawn a GameObject
|
|
/// </summary>
|
|
/// <param name="prefab">The GameObject prefab to spawn.</param>
|
|
/// <returns>The instantiated GameObject. Will be null when the prefab could not be spawned.</returns>
|
|
public virtual GameObject Spawn(GameObject prefab) {
|
|
return Spawn(prefab, spawnPoints, spawnMethod);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Spawn a GameObject
|
|
/// </summary>
|
|
/// <param name="prefab">The GameObject prefab to spawn.</param>
|
|
/// <param name="spawnPoints">The array of possible spawn points.</param>
|
|
/// <param name="spawnMethod">The SpawnMethod to use for spawning.</param>
|
|
/// <returns>The instantiated GameObject. Will be null when the prefab could not be spawned.</returns>
|
|
public virtual GameObject Spawn(GameObject prefab, SpawnPoint[] spawnPoints, SpawnMethod spawnMethod = SpawnMethod.RoundRobin) {
|
|
if (prefab == null)
|
|
return null;
|
|
|
|
GameObject newGameObject = null;
|
|
SpawnPoint spawnPoint = ChooseSpawnPoint(spawnPoints, spawnMethod);
|
|
if (spawnPoint == null)
|
|
Debug.Log("Could not find an empty SpawnPoint");
|
|
else {
|
|
if (singleInstance && lastPrefabInstance != null) {
|
|
lastPrefabInstance.transform.position = spawnPoint.transform.position;
|
|
lastPrefabInstance.transform.rotation = spawnPoint.transform.rotation;
|
|
newGameObject = lastPrefabInstance;
|
|
}
|
|
else {
|
|
|
|
//NetworkedTransform networkedTransform = prefab.GetComponent<NetworkedTransform>();
|
|
//if (networkedTransform != null)
|
|
// newGameObject = NetworkedTransform.Instantiate(prefab, spawnPoint.transform.position, spawnPoint.transform.rotation);
|
|
//else
|
|
// newGameObject = Instantiate(prefab, spawnPoint.transform.position, spawnPoint.transform.rotation);
|
|
|
|
newGameObject = Spawn(prefab, spawnPoint.transform.position, spawnPoint.transform.rotation);
|
|
lastPrefabInstance = newGameObject;
|
|
}
|
|
}
|
|
|
|
return newGameObject;
|
|
}
|
|
|
|
public static GameObject Spawn(GameObject prefab, Vector3 position, Quaternion rotation) {
|
|
GameObject newGameObject;
|
|
|
|
#if hNW_PHOTON
|
|
NetworkedTransform networkedTransform = prefab.GetComponent<NetworkedTransform>();
|
|
if (networkedTransform != null)
|
|
newGameObject = NetworkedTransform.Instantiate(prefab, position, rotation);
|
|
else
|
|
#endif
|
|
newGameObject = Instantiate(prefab, position, rotation);
|
|
|
|
return newGameObject;
|
|
}
|
|
|
|
protected SpawnPoint ChooseSpawnPoint(SpawnPoint[] spawnPoints, SpawnMethod spawnMethod) {
|
|
if (spawnPoints == null)
|
|
return null;
|
|
|
|
List<SpawnPoint> availablePoints = new List<SpawnPoint>();
|
|
foreach (SpawnPoint spawnPoint in spawnPoints) {
|
|
if (spawnPoint is HumanoidSpawnPoint) {
|
|
if (((HumanoidSpawnPoint)spawnPoint).isFree)
|
|
availablePoints.Add(spawnPoint);
|
|
}
|
|
else
|
|
availablePoints.Add(spawnPoint);
|
|
}
|
|
|
|
int spawnPointIndex = GetSpawnPointIndex(availablePoints.Count, spawnMethod);
|
|
if (spawnPointIndex == -1)
|
|
return null;
|
|
|
|
return availablePoints[spawnPointIndex];
|
|
}
|
|
|
|
private int GetSpawnPointIndex(int nSpawnPoints, SpawnMethod spawnMethod) {
|
|
if (nSpawnPoints <= 0)
|
|
return -1;
|
|
|
|
switch (spawnMethod) {
|
|
case SpawnMethod.RoundRobin:
|
|
return spawnIndex++ & nSpawnPoints;
|
|
|
|
case SpawnMethod.Random:
|
|
default:
|
|
return Random.Range(0, nSpawnPoints - 1);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
} |