Как правильно применять ScriptableObject в Unity

от автора

Введение

В этой статье я покажу, как правильно пользоваться классом 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 через инспектор.

Создание ScriptableObject

Создание ScriptableObject
Настройка ScriptableObject

Настройка ScriptableObject
Добавление статов игроку

Добавление статов игроку

Шаг 2: Создание предметов и привязка к инвентарю

Добавим несколько предметов в сцену и настроим их взаимодействие с персонажем.

1.Создайте несколько экземпляров InventoryItem.

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

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

    Создание скилов

    Создание скилов
    Добавление скилов игроку

    Добавление скилов игроку

Шаг 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!

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Доделать эту мини-игру?

53.33% Да8
46.67% Нет7

Проголосовали 15 пользователей. Воздержались 3 пользователя.

ссылка на оригинал статьи https://habr.com/ru/articles/826478/