using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.Rendering.Universal; /// /// менеджер тайлов /// инициализация, создание новых, удаление, отслеживание кол-ва тайлов /// public class TileManagerScript : MonoBehaviour { /// /// число тайлов, которые будут созданы /// [SerializeField] private int _NumTile; /// /// расстояние между центрами двух тайлов, нужно переделать, чтобы бралось само /// [SerializeField] private float _DistanceTiles; /// /// список префабов для случайной генерации /// [SerializeField] private List _TilePrefs = new List(); /// /// поле массива тайлов /// [SerializeField] private List _Tiles = new List(); /// /// счётчик кол-ва созданных тайлов /// private int _CountTile = 0; /// /// при запуске сцены, создание новых тайлов /// private void Awake() { // координата самого дальнего тайла float z = -(_NumTile / 2) * _DistanceTiles; // создание тайлов назад от игрока, где i номер тайла, а z координата transfrom.position.z for (int i = 0; i < _NumTile; i++) { // генерация нового тайла, с собственным z GameObject tile = GenerateTile(new Vector3(0, 0, z), new Quaternion(0, 0, 0, 0)); if (z <= 0) { SetCloseZone(tile); } // увелечение позиции тайла по transform.position.z z += _DistanceTiles; } } /// /// Активация зон закрытия /// /// private void SetCloseZone(GameObject tile) { // цикл нахождения скрипта тригера по тегу foreach (Transform child in tile.transform) { // если найден тег, то передать и закрыть if (child.CompareTag("Trigger Zone")) { // получение адреса объекта child.GetComponent().WasTrigged = true; // выход из цикла break; } } foreach (Transform child in tile.transform) { // если найден тег, то передать и закрыть if (child.CompareTag("Close Zone")) { // передача адреса объекта child.gameObject.SetActive(true); // выход из цикла break; } } } /// /// присваивание тайлу его номера в имя /// /// передаваемый тайл private void NewNameTile(GameObject tile) { // увеличение счётчика тайлов _CountTile++; // Прибавить к имени тайла его номер tile.name += _CountTile; } /// /// генератор тайлов по заданному transform /// /// позиция нового тайла /// поворот нового тайла /// возвращает созданный тайл public GameObject GenerateTile(Vector3 pos, Quaternion rot) { // создание нового тайла GameObject newTile = Instantiate(GetRandomObject(_TilePrefs), pos, rot); // присваивание номера NewNameTile(newTile); GameObject prevTile = _Tiles.LastOrDefault(); TransCloseZoneSub(newTile, prevTile); // добавление массива в отслеживание _Tiles.Add(newTile); // подпись нового тайла на эвент SubTileTrigEvent(newTile); // перемещение нового тайла в менеджер как child newTile.transform.SetParent(gameObject.transform); //Debug.Log($"Was created new tile awake"); return newTile; } /// /// генерация тайла с добавлением его в конец списка /// /// возвращает созданный тайл public GameObject GenerateTile() { // индекс последнего элемента int index = _NumTile - 1; // позиция и поворот последнего тайла Vector3 pos = _Tiles[index].transform.position; Quaternion rot = _Tiles[index].transform.rotation; // создание нового position для генерации нового тайла Vector3 newVector = new Vector3(pos.x, pos.y, pos.z + _DistanceTiles); // создание нового тайла и получение его адреса GameObject newTile = Instantiate(GetRandomObject(_TilePrefs), newVector, rot); // присваивание номера NewNameTile(newTile); GameObject prevTile = _Tiles.LastOrDefault(); TransCloseZoneSub(newTile, prevTile); // добавление массива в отслеживание _Tiles.Add(newTile); // перемещение нового тайла в менеджер как child newTile.transform.SetParent(gameObject.transform); // подпись нового тайла на эвент тригера зоны SubTileTrigEvent(newTile); // удаление первого в списке тайла DeleteTile(); //Debug.Log($"Was created new tile"); return newTile; } /// /// Удалитель тайлов /// public void DeleteTile() { // индекс первого тайла в списке int index = 0; // удаление GameObject первого тайла Destroy(_Tiles[index]); // удаление первого тайла в списке _Tiles.RemoveAt(index); //Debug.Log("Was deleted tile"); } /// /// Подпись на триггер эвент в тайле /// /// передаваемый тайл на подпись private void SubTileTrigEvent(GameObject tile) { // прохождение по всем child в tile foreach (Transform child in tile.transform) { // если тайл является тригерной зоной, то подписаться и закончить if (child.CompareTag("Trigger Zone")) { // в подпись передаётся анонимная функция, так как GenerateTile() возвращает GameObject child.GetComponent().TriggerZoneEvent.AddListener(() => GenerateTile()); // выход из цикла break; } } } /// /// Передача в ново созданный тайл, зоны закртытия предыдущего /// /// Новый тайл /// Предыдущий тайл public void TransCloseZoneSub(GameObject newTile, GameObject pervTile) { // Получение зоны закрытия GameObject closeZone = null; // скрипт с эвентом тригера TriggerZoneScript triggerZoneScript = null; // проверка наличия нового тайла if (newTile != null) { // цикл нахождения скрипта тригера по тегу foreach (Transform child in newTile.transform) { // если найден тег, то передать и закрыть if (child.CompareTag("Trigger Zone")) { // получение адреса объекта triggerZoneScript = child.GetComponent(); // выход из цикла break; } } } // проверка на наличие предыдущего тайла if (pervTile != null) { // поиск зоны закрытия по тегу foreach (Transform child in pervTile.transform) { // если найден тег, то передать и закрыть if (child.CompareTag("Close Zone")) { // передача адреса объекта closeZone = child.gameObject; // выход из цикла break; } } } // проверка на первосозданный тайл, у него нет предыдущего тайла, поэтому нечего закрывать if (closeZone != null) { // передача анонимной функции активации зоны закрытия triggerZoneScript.GetComponent().TriggerZoneEvent.AddListener(() => closeZone.SetActive(true)); } } /// /// Генератор случайно взятого объекта /// /// /// Список из которого брать /// T GetRandomObject(List list) { // проверка на пустоту списка if (list == null || list.Count == 0) { return default; } // Генерация случайного индекса int randomIndex = UnityEngine.Random.Range(0, list.Count); return list[randomIndex]; } }