340 lines
12 KiB
C#
340 lines
12 KiB
C#
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using UnityEngine;
|
||
|
||
/// <summary>
|
||
/// менеджер тайлов
|
||
/// инициализация, создание новых, удаление, отслеживание кол-ва тайлов
|
||
/// </ summary >
|
||
public class TileManagerScript : MonoBehaviour
|
||
{
|
||
/// <summary>
|
||
/// to do
|
||
/// </summary>
|
||
[HideInInspector]
|
||
public ScoreManagerScript scoreManager;
|
||
|
||
/// <summary>
|
||
/// число тайлов, которые будут созданы
|
||
/// </summary>
|
||
[SerializeField]
|
||
private int _NumTile;
|
||
|
||
/// <summary>
|
||
/// расстояние между центрами двух тайлов, нужно переделать, чтобы бралось само
|
||
/// </summary>
|
||
[SerializeField]
|
||
private float _DistanceTiles;
|
||
public float DistanceTiles
|
||
{
|
||
get => _DistanceTiles;
|
||
set => _DistanceTiles = value;
|
||
}
|
||
|
||
/// <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;
|
||
|
||
[SerializeField]
|
||
private GameObject _PlayerSetup;
|
||
|
||
/// <summary>
|
||
/// при запуске сцены, создание новых тайлов
|
||
/// </summary>
|
||
private void Start()
|
||
{
|
||
|
||
// координата самого дальнего тайла
|
||
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);
|
||
SetTrigZone(tile);
|
||
}
|
||
if (z == 0)
|
||
{
|
||
SetTrigZone(tile);
|
||
}
|
||
|
||
// увелечение позиции тайла по transform.position.z
|
||
z += _DistanceTiles;
|
||
}
|
||
|
||
|
||
|
||
_PlayerSetup.SetActive(true);
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="tile"></param>
|
||
private void SetTrigZone(GameObject tile)
|
||
{
|
||
// цикл нахождения скрипта тригера по тегу
|
||
foreach (Transform child in tile.transform)
|
||
{
|
||
// если найден тег, то передать и закрыть
|
||
if (child.CompareTag("Trigger Zone"))
|
||
{
|
||
// получение адреса объекта
|
||
child.GetComponent<TriggerZoneScript>().WasTrigged = true;
|
||
|
||
// выход из цикла
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Активация зоны закрытия
|
||
/// </summary>
|
||
/// <param name="tile"></param>
|
||
private void SetCloseZone(GameObject tile)
|
||
{
|
||
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");
|
||
}
|
||
|
||
private delegate void SubTileTrigDelegate();
|
||
private SubTileTrigDelegate _SubTileTrigEvent;
|
||
|
||
/// <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());
|
||
|
||
// в подпись передаётся функция увелечения счёта
|
||
child.GetComponent<TriggerZoneScript>().TriggerZoneEvent.AddListener(scoreManager.Increase);
|
||
|
||
// в подпись передаётся функция перемещения счёта
|
||
child.GetComponent<TriggerZoneScript>().TriggerZoneEvent.AddListener(scoreManager.UpdatePos);
|
||
|
||
// выход из цикла
|
||
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];
|
||
}
|
||
}
|