Dizel c7e0620447 Код закрытых тайлов
Дописал код в менеджер тайлов, который закрывает пройденные зоны от игрока
2024-12-13 16:54:18 +03:00

300 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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