Создание системы уровней с различными условиями прохождения в 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();
        }
    } 
}

Как было бы правильно изменить код, чтобы такая система работала и не пришлось плодить десятки похожих префабов чекпоинта, и возможна ли моя реализация вообще?

Нигде не видел, чтобы кто-то добавлял скрипт с игровой логикой в качестве переменной, но и других вариантов решения задачи пока найти не могу.


Ответы (0 шт):