Создание системы уровней с различными условиями прохождения в Unity
Недавно начал изучать Unity, и решил сделать небольшую игру, разделенную на несколько уровней, в каждом из которых есть свои механики.
Для этого построил следующую архитектуру:
- есть ScriptableObject LevelScript.cs, от которого наследуются скрипты для каждого уровня (Level_1.cs, Level_2.cs и так далее)
- при выполнении задачи уровня активируется чекпоинт, который стоит в конце локации, и когда мы его касаемся, скрипт LevelManager запускает следующий уровень
- в LevelManager через инспектор я собирался добавить все скрипты уровня, но тут возникает проблема - добавить их нельзя.
Это решаемо, если создавать Level_номер в инспекторе как игровой объект, но тогда нельзя изменить в его коде уникальные условия для прохождения (сбор предметов, прохождение на время, победа над боссом и т.д.)
Вот все скрипты:
LevelManager.cs
using System;
using UnityEngine.SceneManagement;
using UnityEngine;
public class LevelManager : MonoBehaviour
{
[SerializeField] private LevelScript[] levels;
private int levelActive;
private int countOfLevels;
void Awake()
{
DontDestroyOnLoad(this);
levelActive = 1;
countOfLevels = levels.Length;
}
public void SetLevel(int level)
{
levelActive = level;
SceneManager.LoadScene("Level_" + level);
Debug.Log("Переходим на уровень " + level);
}
public void RestartLevel()
{
SetLevel(levelActive);
}
public void CheckpointActivated()
{
if (levelActive < countOfLevels)
SetLevel(levelActive + 1);
Debug.Log("Чекпоинт достигнут");
}
}
LevelScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LevelScript : ScriptableObject
{
[SerializeField] private int levelIdx;
[SerializeField] private string levelName;
[SerializeField] private Checkpoint checkpoint;
private bool ableToComplete; // выполнены ли условия прохождения?
void Start()
{
ableToComplete = false;
}
public void TaskComplited()
{
ableToComplete = true;
checkpoint.ChangeState();
}
}
Checkpoint.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Checkpoint : MonoBehaviour
{
[SerializeField] private LevelManager levelManager;
Collider col;
private bool checkpointState; // можно ли пройти на следующий уровень?
void Start()
{
col = GetComponent<Collider>();
checkpointState = false;
}
public void ChangeState()
{
checkpointState = true;
}
private void OnTriggerEnter(Collider other)
{
if (checkpointState)
{
levelManager.CheckpointActivated();
}
}
}
И пример скрипта первого уровня:
using UnityEngine;
public class Level_01 : LevelScript
{
int itemsCollected = 0; // предметов собрано
int itemsToCollect = 3; // сколько надо собрать
bool allItemsCollected = false;
public void OnItemCollect()
{
itemsCollected += 1;
Debug.Log("Вы собрали объект");
if (itemsCollected >= itemsToCollect)
{
allItemsCollected = true;
base.TaskComplited();
}
}
}
Как было бы правильно изменить код, чтобы такая система работала и не пришлось плодить десятки похожих префабов чекпоинта, и возможна ли моя реализация вообще?
Нигде не видел, чтобы кто-то добавлял скрипт с игровой логикой в качестве переменной, но и других вариантов решения задачи пока найти не могу.