Изучаю Unity. Решил сделать небольшую игру, разбитую на несколько уровней. В каждом уровне есть своя механика. Например, на первом уровне надо пройтись по дому и найти несколько предметов, после чего подойти к двери (чекпоинт) и перейти на второй уровень. На втором надо на время добежать до чекпоинта. И так далее.
Возник вопрос: как реализовать скрипты для каждого уровня (LevelScript_01, LevelScript_02 и т.д.)?
Я попытался сделать папку со скриптами на каждый уровень, в каждом из которых есть похожие функции, например переход на другой уровень, а также уникальные условия прохождения (счетчик предметов в 1ом, таймер во 2ом, побежден ли босс в 3ем и так далее). Еще я сделал префаб чекпоинта (триггер, который отсылает сигнал скрипту уровня о том, что игрок хочет перейти на другой уровень). Игрок касается триггера -> триггер отсылает сигнал скрипту LevelScript_01 -> скрипт уровня проверяет условия прохождения -> игрок переходит на второй уровень.
На каждой сцене есть объект SceneObserver, в котором находится единственный скрипт - нумерованный скрипт уровня.
Но возникает проблема: сигнал от чекпоинта к определенному скрипту уровня не передается (или я не понимаю как это сделать). Делать один скрипт, в котором будут указаны условия прохождения сразу всех уровней, после чего аргументом от чекпоинта передавать на каком уровне мы находимся - не логично.
Та же проблема с предметами, которые надо собрать. Как привязать их именно к первому уровню, а не, например, к пятому (где такие объекты тоже будут)?
Было бы отлично, если в скрипте чекпоинта можно было бы создать поле Level, а потом через инспектор поместить в это поле нужный мне скрипт, в котором точно есть метод для перехода на следующую локацию. Но я не уверен, что это возможно.
Как правильно организовать архитектуру и связь между объектами сцены, не создавая десятки префабов для чекпоинта на каждый уровень?
Пример скрипта к первому уровнюusing System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using UnityEngine;
public class Level_01 : MonoBehaviour
{
int itemsCollected = 0; // предметов собрано
int itemsToCollect = 3; // сколько надо собрать
bool allItemsCollected = false;
void OnItemCollect()
{
itemsCollected += 1;
Debug.Log("Вы собрали объект");
if (itemsCollected >= itemsToCollect)
allItemsCollected = true;
}
// этот метод есть в каждом скрипте уровня
void OnCheckpointEnter() // метод должен вызываться из префаба чекпоинта (но этого сделать не получается)
{
if (allItemsCollected) {
SceneManager.LoadScene("Level_02");
Debug.Log("Переход на новый уровень");
}
}
}
Примерный код чекпоинтаusing System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Checkpoint : MonoBehaviour
{
[SerializeField] private int level_ID; // номер уровня, на котором мы находимся
Collider col;
void Start()
{
col = GetComponent<Collider>();
}
private void OnTriggerEnter(Collider other)
{
// отсюда надо вызвать метод конкретного скрипта уровня (для этого я в начало добавил id)
}
}