Введение
В этой статье я покажу, как правильно пользоваться классом ScriptableObject в Unity. Мы создадим небольшую игру для наглядности, в которой игрок сможет управлять персонажем с различными параметрами, навыками и инвентарем. Мы рассмотрим создание и использование ScriptableObject для хранения данных. В конце вы найдете плюсы и минусы использования данного метода.
Введение в ScriptableObject
Что такое ScriptableObject и зачем он нужен?
ScriptableObject - это класс в Unity, который позволяет хранить данные отдельно от игровых объектов. Это особенно полезно для управления данными, которые часто изменяются или используются многократно. Основные случаи использования включают:
• Хранение игровых данных (например, параметры персонажей, настройки уровней).
• Управление состоянием игры.
• Создание редакторов и инструментов.
Пример использования ScriptableObject в Unity
Общий обзор
Мы создадим мини-игру, где игрок может управлять персонажем с различными параметрами, навыками и инвентарем. Весь функционал будет построен на ScriptableObject для хранения данных персонажей, навыков и предметов.
Шаг 1: Создание ScriptableObject для параметров персонажа
Начнем с создания класса ScriptableObject для хранения параметров персонажа.
using UnityEngine; [CreateAssetMenu(fileName = "NewCharacterStats", menuName = "Character Stats")] public class CharacterStats : ScriptableObject { [SerializeField] private string _characterName; [SerializeField] private int _health; [SerializeField] private int _attackPower; [SerializeField] private int _defense; [SerializeField] private Skill[] _skills; public string CharacterName => _characterName; public int Health => _health; public int AttackPower => _attackPower; public int Defense => _defense; public Skill[] Skills => _skills; }
Пояснение к коду:
• CreateAssetMenu позволяет создавать объекты через контекстное меню в Unity Editor.
• Параметры персонажа включают имя, здоровье, силу атаки, защиту и массив навыков.
Шаг 2: Создание ScriptableObject для навыков
Теперь создадим ScriptableObject для хранения данных о навыках.
using UnityEngine; [CreateAssetMenu(fileName = "NewSkill", menuName = "Skill")] public class Skill : ScriptableObject { [SerializeField] private string _skillName; [SerializeField] private int _power; [SerializeField] private float _cooldown; public string SkillName => _skillName; public int Power => _power; public float Cooldown => _cooldown; }
Пояснение к коду:
• CreateAssetMenu позволяет создавать объекты через контекстное меню в Unity Editor.
• Данные о навыке включают имя, силу и время перезарядки.
Шаг 3: Создание ScriptableObject для предметов
Создадим ScriptableObject для хранения данных о предметах.
using UnityEngine; [CreateAssetMenu(fileName = "NewItem", menuName = "Inventory Item")] public class InventoryItem : ScriptableObject { [SerializeField] private string _itemName; [SerializeField] private Sprite _itemIcon; [SerializeField] private int _itemID; public string ItemName => _itemName; public Sprite ItemIcon => _itemIcon; public int ItemID => _itemID; }
Пояснение к коду:
• CreateAssetMenu позволяет создавать объекты через контекстное меню в Unity Editor.
• Данные о предмете включают имя, иконку и уникальный идентификатор.
Шаг 4: Использование ScriptableObject в MonoBehaviour
Создадим MonoBehaviour для управления персонажем, который будет использовать ScriptableObject для хранения параметров, навыков и инвентаря.
using System.Collections.Generic; using UnityEngine; public class Character : MonoBehaviour { [SerializeField] private CharacterStats _stats; [SerializeField] private List<InventoryItem> _inventory = new(); public void AddItemToInventory(InventoryItem item) { _inventory.Add(item); Debug.Log($"Added item: {item.ItemName}"); } private void Start() { Debug.Log($"Name: {_stats.CharacterName}, Health: {_stats.Health}, Attack: {_stats.AttackPower}, Defense: {_stats.Defense}"); foreach (var skill in _stats.Skills) { Debug.Log($"Skill: {skill.SkillName}, Power: {skill.Power}, Cooldown: {skill.Cooldown}"); } } }
Пояснение к коду:
• Переменные _stats и _inventory хранят ссылки на объекты ScriptableObject.
• Метод Start выводит параметры персонажа и его навыки в консоль.
• Метод AddItemToInventory добавляет предмет в инвентарь персонажа.
3. Создание мини-игры
Общий обзор
Создадим сцену, на которой игрок сможет управлять персонажем, собирать предметы, использовать навыки и видеть их в инвентаре.
Шаг 1: Создание персонажа и привязка параметров
В Unity создадим префаб персонажа и привяжем к нему параметры, используя ScriptableObject.
1. Создайте GameObject для персонажа.
2. Добавьте компонент Character и привяжите CharacterStats через инспектор.



Шаг 2: Создание предметов и привязка к инвентарю
Добавим несколько предметов в сцену и настроим их взаимодействие с персонажем.
1. Создайте несколько экземпляров InventoryItem.

2. Добавьте их в список inventory у компонента Character.

Создайте скилы и добавьте в статы игрока.

Создание скилов 
Добавление скилов игроку
Шаг 3: Реализация использования навыков
Добавим возможность использования навыков персонажем.
using System.Collections; using UnityEngine; public class SkillUser : MonoBehaviour { [SerializeField] private Character _character; private bool _isAbleToUseSkill = true; private void Update() { if (_isAbleToUseSkill) { for (int i = 0; i < _character.Stats.Skills.Length; i++) { if (Input.GetKeyDown(KeyCode.Alpha1 + i)) { UseSkill(i); } } } } private void UseSkill(int index) { if (index < _character.Stats.Skills.Length) { Skill skill = _character.Stats.Skills[index]; Debug.Log($"Using skill: {skill.SkillName}"); StartCoroutine(Cooldown(skill)); } } private IEnumerator Cooldown(Skill skill) { _isAbleToUseSkill = false; Debug.Log($"Skill {skill.SkillName} on cooldown for {skill.Cooldown} seconds."); yield return new WaitForSeconds(skill.Cooldown); Debug.Log($"Skill {skill.SkillName} is ready to use again."); _isAbleToUseSkill = true; } }
Пояснение к коду:
• Компонент SkillUser управляет использованием навыков персонажа.
• Метод UseSkill активирует навык и запускает перезарядку.
Добавьте этот скрипт персонажу и перенесите компонент Character в соответствующее поле
Теперь можно запустить сцену и проверить работос��особность нашей мини-игры через консоль и есть нам понравится результат, добавлять визуальную реализацию.
P.s.
Я специально не стал писать логику для работы с предметами из инвентаря, чтобы не загромождать туториал лишней инфой, все таки статья про другое)
Если вам вдруг интересно, пишите в комментария "Доделай игру" и я добавлю оставшийся функционал
4. Преимущества и недостатки ScriptableObject
Преимущества
• Удобство управления данными: Разделение данных от логики, упрощение изменения параметров.
• Повторное использование: Легкое использование одного и того же объекта в разных местах проекта.
• Снижение загрузки памяти: ScriptableObject загружаются только один раз и могут быть использованы многократно.
• Простота тестирования: Легкость тестирования и отладки данных.
Недостатки
• Ограниченная поддержка сценариев: Не подходит для всех типов данных и логики.
• Необходимость понимания работы Unity Editor: Требуется знание работы с редактором и ScriptableObject.
• Нет обновлений в реальном времени: Изменения в ScriptableObject не обновляются автоматически в связанных объектах.
5. Заключение
Мы рассмотрели, как использовать ScriptableObject в Unity для создания более сложной мини-игры с управлением персонажем, его навыками и инвентарем. ScriptableObject предоставляет удобный способ управления данными, улучшая архитектуру и производительность проектов. Попробуйте внедрить этот подход в своих проектах и оцените его преимущества.
Если тебе понравилась статья, обязательно голосуй за нее! Так я пойму что тебе она понравилась и рассмотрю другие тематики, связанные с Unity!
