Хотел бы я знать о них в первые годы работы с Unity3D

Я работаю уже почти 10 лет, а несколько лет назад я открыл для себя Scriptable Objects, и это было удивительное открытие.
Я большой поклонник Scriptable Objects!

Одно из основных преимуществ, которые я вижу с помощью ScriptableObjects, заключается в том, что вы можете создавать их как файл ресурсов в своем проекте, совместно использовать различные игровые объекты в вашем проекте, и вам не нужно прикреплять их к конкретной игре. объект.

Вот еще несколько преимуществ:

  • Они удобны для редактирования,
  • С ними можно справиться с помощью обычного единого конвейера Создание, включение, уничтожение.
  • Они вполне совместимы с системой сериализации Unity и могут быть сериализованы по ссылке.
  • Они отлично подходят для прототипирования.

И мне больше всего нравится, что они отлично подходят для организации ресурсов:

  • Звуковые эффекты / Музыка для вашей игры.
  • Спрайты
  • Мой личный фаворит: GameBalance. Для моих собственных проектов у меня обычно есть скриптовый объект, представляющий различные аспекты игрового баланса игры.
    Например, минимальное значение здоровья для нашего героя-игрока.

Теперь перейдем к практическому примеру с использованием ScriptableObjects.

В этом примере у нас есть игрок, который собирается начать битву с могущественным боссом.

Чтобы начать битву, игроку нужно выбрать 2 героя из 6 разных героев.

  • У каждого героя разная ценность здоровья.
  • У каждого героя своя силовая атака.
  • Каждый герой силен против определенного заклинания.

Игра генерирует случайного босса (силовая атака, здоровье и конкретное заклинание)
Случайные диапазоны для каждого элемента указываются в ScriptableObject

Игрок не знает, с каким боссом ему предстоит столкнуться, поэтому игрок должен вслепую выбирать героев.

Это идеальный пример реализации объекта, допускающего создание сценариев. Мы можем определить каждый тип героя в объекте, допускающем сценарий, и показать эту информацию в пользовательском интерфейсе.

Вот простой пример пользовательского интерфейса:

  • Каждый персонаж - это кнопка, которую игрок может выбрать, чтобы начать битву.
  • Каждая кнопка-персонаж содержит статистику каждого героя.
  • С правой стороны есть кнопка начала битвы, которая активируется, когда выбраны только 2 героя.
  • Статистика босса будет раскрыта, когда игрок будет готов к битве. Характеристики босса рандомизированы.

Первое, что нам нужно определить, это Scriptable Object, который содержит всех выбираемых героев и балансируемую статистику для босса (диапазон здоровья, диапазон атаки ...)

Каждый герой силен против определенного заклинания, и каждый босс накладывает определенное заклинание.

Enum SkillType определяет заклинания, против которых силен каждый герой, и заклинание босса.

В этом скрипте мы можем найти список героев, которых можно выбрать в пользовательском интерфейсе.

Взгляните на следующие строки:

[CreateAssetMenu(fileName = "GameBalance", menuName = "ScriptableObjectExample/GameBalance", order = 1)]
public class GameBalanceExample : ScriptableObject

С помощью этих простых строк кода мы можем создать наш Scriptable Object, чтобы сбалансировать игру.
Функция CreateAssetMenu указывает, что мы можем использовать правый щелчок по разделу Project в Unity для создания данных. актив.

Если вы нажмете на новый скриптовый объект GameBalance, вы увидите что-то вроде этого.

Как нам использовать эту прекрасную вещь?

Несмотря на то, что Scriptable Objects очень удобны в использовании, нам все же нужно как-то подключить активы. Простой способ сделать это - использовать классический синглтон GameManager (пожалуйста, не заполняйте свои проекты тысячами синглтонов, они великолепны, но подумайте сначала, когда он вам действительно нужен).

Вот мой простой код GameManager для этого примера:

Если я нажму на GameObject, который содержит GameManager, вы увидите, что есть поле для перетаскивания сценария GameBalance Scriptable Object.

Наконец, посмотрите, как я использую данные Scriptable Object для создания случайного босса.

Таким же образом мы можем использовать данные для отображения каждого врага в пользовательском интерфейсе.
В моем примере у меня есть сценарий под названием BattleSelectorUI, в котором я реализовал логику:

  • Когда игрок выбирает / отменяет выбор героя
  • Когда игрок нажимает кнопку битвы
  • Когда игрок выбрал как минимум 2 героев для битвы и кнопка активирована

Вот пример того, как я использую статистику одного героя в пользовательском интерфейсе:

// Initialize each hero on the UI
int numberHeroes = GameManager.instance.gameBalanceData.HeroList.Count;
// Loop through all heroes and display infor on the UI
for (int i=0; i< numberHeroes; i++)
{
   // Select the stats
    CharacterStats heroStats =   
         GameManagerSOE.instance.gameBalanceData.HeroList[i];
   
   string heroDesc = heroStats.Name;
   heroDesc += "\nAttack: ";
   heroDesc += heroStats.PowerAttack;
   heroDesc += "\nStrong: ";
   heroDesc += heroStats.StrongAgainst;
  characterCardList[i].description.text = heroDesc;
  characterCardList[i].imageCharacter.sprite = heroStats.Image;
}

И это все! Проверьте, как работает весь пример:

Спасибо, что прочитали этот блог разработчиков.
Надеюсь, вам понравилось читать это так же, как и мне, когда я писал.

Вы можете найти меня в: