using System;
using System.Linq;
using UnityEngine;
using UnityEngine.Serialization;
public class SpawnSystem : MonoBehaviour
{
[Header("Settings")]
[SerializeField] private int _defaultSpawnIndex = 0;
[Header("Asset References")]
[SerializeField] private Protagonist _playerPrefab = default;
[SerializeField] private TransformEventChannelSO _playerInstantiatedChannel = default;
[Header("Scene References")]
[SerializeField] private Transform[] _spawnLocations;
[Header("Scene Ready Event")]
[SerializeField] private VoidEventChannelSO _OnSceneReady = default; //Raised when the scene is loaded and set active
private void OnEnable()
{
if (_OnSceneReady != null)
{
_OnSceneReady.OnEventRaised += SpawnPlayer;
}
}
private void OnDisable()
{
if (_OnSceneReady != null)
{
_OnSceneReady.OnEventRaised -= SpawnPlayer;
}
}
private void SpawnPlayer()
{
Spawn(_defaultSpawnIndex);
}
void Reset()
{
AutoFill();
}
///
/// This function tries to autofill some of the parameters of the component, so it's easy to drop in a new scene
///
[ContextMenu("Attempt Auto Fill")]
private void AutoFill()
{
if (_spawnLocations == null || _spawnLocations.Length == 0)
_spawnLocations = transform.GetComponentsInChildren(true)
.Where(t => t != this.transform)
.ToArray();
}
private void Spawn(int spawnIndex)
{
Transform spawnLocation = GetSpawnLocation(spawnIndex, _spawnLocations);
Protagonist playerInstance = InstantiatePlayer(_playerPrefab, spawnLocation);
_playerInstantiatedChannel.RaiseEvent(playerInstance.transform); // The CameraSystem will pick this up to frame the player
}
private Transform GetSpawnLocation(int index, Transform[] spawnLocations)
{
if (spawnLocations == null || spawnLocations.Length == 0)
throw new Exception("No spawn locations set.");
index = Mathf.Clamp(index, 0, spawnLocations.Length - 1);
return spawnLocations[index];
}
private Protagonist InstantiatePlayer(Protagonist playerPrefab, Transform spawnLocation)
{
if (playerPrefab == null)
throw new Exception("Player Prefab can't be null.");
Protagonist playerInstance = Instantiate(playerPrefab, spawnLocation.position, spawnLocation.rotation);
return playerInstance;
}
}