Mariya Mariya

Dreaman, Спасибо! =)

Dreaman Dreaman

Mariya, законченный вариант реально классно выглядит! Молодец :)

Mariya Mariya

Всем привет!
Сегодня хочу показать законченный вариант домика Сырны.

alexprey alexprey

StarPlosion: Битва с пиратами за планету

Wings' might Wings' might

Всем привет)
Добавил на этой неделе начальное окно, новую валюту и достижения:

alexprey alexprey

shadeborn, может быть они нашли способ как обойти полноценный запуск этих сервисов при запуске игры? Если так, то почему бы и не использовать единый клиент?) В любом случае, чем дальше все идет, там это все больше становится похоже на эту шутку

...
shadeborn shadeborn

Это всё круто, но...зачем? Ок есть Стим. Хорошо, теперь еще и ЕГС есть. Благо, комп не зашкварен Оригином...но у людей и он стоит. И для работы игр внутри этих сервисов нужны, собсно, эти сервисы. Так поверх этих сервисов нужно накатить еще один...

Devion Devion

согласен, есть кейсы которые без них вообще не делаются, не знать или избегать их определенно неправильно

Так точно, либо любое изменение в объекте на стороне редактора.

alexprey alexprey

Devion, только рад за дополнение, Спасибо)

хм, а вот это интересно, не пробовал никогда такой кейс.

Devion Devion

лёш, ты же не против если я дополню? )

скриптаблы, для понимания могут храниться на уровне ассета и на уровне сцены.

Mariya Mariya

Всем привет!
Начали работу над мебелью в домик Сырны, и первым сделали чайный столик с чайным сервизом. А так же продолжаем работу над анимациями.

Wings' might Wings' might

Всем привет)
За неделю в игру было добавлено меню настроек, переделана старая локация, добавлены новые враги и повышена производительности

alexprey alexprey

А мне кажется это такой особый хитрый ход, хотя с другой стороны как разработчики успеют к этому подготовиться получше 🤔

Dreaman Dreaman

Всем привет!
Для проекта "Mental State" разработано новое устройство, которое уже полностью функционирует внутри игрового мира. Оно носит название "Репульсивер". Совместно с очередными большими воротами это устройство образует новую головоломку...

...
Mariya Mariya

Всем привет!
На этой неделе мы научили Сырну летать!

Tartal Tartal

alexprey, кастомизации - создание внешности персонажа? Я всегда любил это, но не думаю, что это будет к месту в мясном шутере)
EfimovMax, да, есть немного)

Tartal Tartal

Jusper, точно не помню, уже как полгода точно) Я вроде в Дискорде немного обсуждал эту тему. Пока немножко попробовал движок - мне очень нравится. Ну, в конце концов, он идеально подходит под жанры, с которыми я хочу работать...

alexprey alexprey

Первая тема крутая очень!

Логотип проекта Unity

Пользовательский интерфейс

Данная статья рассказывает о новой системе пользовательского интерфейса, которая появилась в новых версиях Unity, начиная с Unity 4.6.

Вступление

Раньше весь интерфейс строился на основе кода. В нужных скриптах было необходимо обрабатывать событие OnGUI, отображать и обрабатывать события всех элементов которые нам необходимы. В результате код получался громоздким. Конечно существовали и альтернативы, например nGUI, однако данный компонент предоставляется на платной основе. С выходом Unity 4.6 все изменилось. В Unity теперь добавилась отличная система пользовательского интерфейса, с нужными для этого инструментами. Конечно старая система осталась полностью работоспособной, но не переходить на новую систему я считаю не правильно. Лично меня очень сильно поразили возможности для создания интерфейса. Новая UI System получилась одновременно и гибкой, и простой, и при этом весьма функциональной.

Начало. Canvas.

Создание полотна для интерфейса — Пользовательский интерфейс — Unity — DevTribe: Разработка игр
Создание полотна для интерфейса

Я думаю объяснять как создавать сцену нет смысла, поэтому пропустим все лишние действия и перейдем непосредственно к самому интерфейсу. Новая система построена на модулях ввода (Input Module), полотне (Canvas) и самих объектах интерфейса. Для создания интерфейса нам надо знать только про полотно и сами элементы.
Как вы уже догадались нам потребуется полотно, на котором мы будем размещать наши элементы. Для этого идем в меню "GameObject -> UI -> Canvas"
После того, как оно появилось на сцене, выберите его и нажмите F для того, чтобы отобразить его перед камерой, так же удобство можно переключиться в 2D режим Unity. В инспекторе для редактирования доступны следующие очень важные свойства, которые определяют поведение нашего полотна:

Render Mode

В зависимости от этого параметра становятся доступны другие остальные поля. Поэтому сперва рассмотрим значения данного поля.

Screen Space - Overlay

В данном режиме полотно растягивается по размерам экрана и отображается без связи со сценой или камерой (UI будет показан даже в том случае, когда на сцене нету камеры). В случае изменения размера окна, полотно будет растянуто под размеры экрана и размещенные элементы будут перегруппированы. Полотно будет рисоваться поверх всех остальных графических элементов.
Pixel perfect - использовать ли antialiasing

Screen Space - Camera

В данном режиме полотно рисуется на плоскости перпендикулярной взгляду камеры, на некотором расстоянии от точки взгляда. Размер полотна не меняется с изменением расстояния, оно всегда растягивается, чтобы заполнять разрез пирамиды видимости у камеры (camera frustrum view). Интерфейс будет заслоняться любыми 3D элементами, которые находятся перед плоскостью интерфейса.
Pixel perfect - использовать ли antialiasing.
Render camera - камера с помощью которой будет отображен интерфейс.
Plane distance - дистанция плоскости нашего интерфейса от камеры.

World Space

В данном режиме полотно располагается в мировых координатах и является плоским 3D объектом на который действую законы обычного процесса визуализации.
Event camera - камера с помощью которой будут происходить обработки событий ввода пользователя.

Все немного сложно, да? По скриншотам, представленных ниже, Вы с легкостью сможете разобраться, что к чему. Красный прямоугольник - это часть нашего полотна. Во всех случаях объекты и камера были не подвижны. Менялись лишь настройки нашего полотна.

С полотном мы разобрались, можно приступать к созданию простого интерфейса.

Начало. Элементы.

Для начало нам надо принять удобную позу. Поэтому заварите себе кружечку горячего чая, откиньтесь на спинку вашего мягкого кресла (или не менее мягкую деревянную спинку стула :) ) и расслабьтесь. Расслабились? Отлично, теперь возвращаемся к Unity. Если у вас полотно используется в режиме мировых координат (World Space), то выберите его и нажмите F и дальше просто подгоните камеру как вам удобно. В другом случае лучше сделать так. Установить режим использования камеры, указать любую камеру, и поставить дистанцию равную 1.0 и нажимаем F, так же не забываем переключиться в 2D режим для удобства работы с интерфейсом. Подгоняем вид как нам удобно, желательно чтобы было видно всю область полотна, и переходим к созданию элементов.

В нашем распоряжении есть классический набор элементов, без которых не возможно существование ни одного нормального интерфейса:

вот так вот они выглядят — Пользовательский интерфейс — Unity — DevTribe: Разработка игр
вот так вот они выглядят
  • Panel - требуется для группировки элементов на себе.
  • Button - обычная типичная кнопка.
  • Text - просто текст.
  • Image - изображение, используются спрайты.
  • RawImage - изображение, используется текстура, для которой можно задать UV координаты.
  • Slider - ползунок для изменения какого-либо значения.
  • ScrollBar - ползунок, но с шаговыми значениями.
  • Toggle - флажок.
  • InputField - поле для ввода

Все эти элементы можно создать из меню "GameObject -> UI -> ...".
После того как вы создадите элемент, надо будет переключиться на новый инструмент Rect tool

Пользовательский интерфейс — Unity — DevTribe: Разработка игр

С помощью него можно легко настраивать расположение и размеры элементов. Давайте посмотрим на возможности данного инструмента

  • Вы можете менять положение элементов, перетаскивая сами элементы (Pos X, Pos Y, Pos Z).
  • Вы можете менять размер элементов, перетаскивая их границы или угловые точки (Width, Height).
  • Вы можете вращать элемент, перетаскивая область вне элемента рядом с угловой точкой (Rotation).
  • Вы можете менять центр вращения, чтобы правильно настроить вращение элемента (Pivot).
  • Вы можете настроить точки крепления к родительскому объекту (Anchors).

В принципе если с первыми 3-мя все понятно, то про остальные я думаю стоит рассказать подробнее.
Начнем с точки вращения. Чтобы его изменить нужно перетаскивать синий кружочек (изначально он находится в центре). Сейчас покажу на скриншотах как это работает. Во всех случаях позиция самого элемента не менялась, лишь якорь и угол вращения.

Пользовательский интерфейс — Unity — DevTribe: Разработка игр
окно пресетов — Пользовательский интерфейс — Unity — DevTribe: Разработка игр
окно пресетов

Теперь давайте ка разберемся с точками крепления. Для их изменения придумали такой вот крестик (скриншот справа). Его можно перемещать либо весь, либо только один из его углов. Так же присутствуют так называемые пресеты для данного параметра. При выборе одного из них, позиция якоря будет меняться. Так же можно зажать клавишу Alt во время выбора пресета и тогда будет меняться положение самого элемента. А если еще и зажать Shift - то так же будет изменена позиция точки вращения.

А теперь давайте поговорим о смысле якоря. В принципе если вам абсолютно не важно как ваш интерфейс выглядит, то (стоп, что за бред?) .... К сути: настройки якоря помогают сделать ваш интерфейс адаптивным, чтобы он мог подстраиваться и растягиваться под разные размеры экрана. Вот например если вы оставите у всех элементов точку крепления в центре, то при изменении размеров родительского элемента (будь то панель, или полотно) элементы так и останутся в центре. Если поставить якорь в левом верхнем углу, то и элементы всегда будут там. Но если правильно настроить якорь, то можно добиться классных эффектов. В общем это трудно описать на словах и показать на скриншотах, поэтому советую вам самим поэкспериментировать с данным свойством. Но все же я хочу рассмотреть один не больший пример. Запомните, если вы сможете понять, что к чему, то вам будет не сложно построить интерфейс любой сложности. Давайте рассмотрим такой вот пример:

Как видите расположение кнопок относительное. Но чтобы этого добиться надо немного поразмыслить, как вся эта система работает. Для этого я предлагаю рассмотреть скриншоты слева. На них вы можете видеть 3 линейки разных цветов.

  • Красная - обозначает итоговое расстояние от границы родителя до границы элемента.
  • Синяя - обозначает расстояние от границы родителя до границы якоря.
  • Зеленая - обозначает расстояние от границы якоря до границы элемента.

Принцип их работы прост. Красная высчитывается UI системой. А вот остальные мы задаем сами. Запоминайте:

  • расстояние от границы родителя до границы якоря - всегда в процентном соотношение с размерами родителя.
  • расстояние от границы якоря до границы элемента - всегда фиксировано.

А теперь расскажу как это нужно использовать. Если вам нужно, чтобы элемент растягивался, то разместите якори данного элементы по границам элемента, или около того (тут можно долго экспериментировать). Если вы хотите, чтобы отступ элемента тоже был в процентном соотношении, то просто поместите ваш элемент в пустую панель и поставьте этой панели якорь так, чтобы он растягивался. А самому элементу поставьте якорь в центр панели. И тогда вы добьетесь такого же поведения, как и на скриншотах выше.


После того как вы научились размещать элементы на полотне, я думаю можно поближе познакомится с особенностью элементов. Начнем с самого простого - картинки!

Image

Image — Пользовательский интерфейс — Unity — DevTribe: Разработка игр
Image
  • Source Image - спрайт, который будет использовать для картинки.
  • Color - окрас спрайта, например можно добавить красных тонов картинке, указав здесь красный цвет.
  • Material - можно задать материал для картинки.
  • Image Type - способ отображения изображения
  • Simple - отображение изображения как есть
  • Sliced - спрайт имеющий 9 частей будет отображен в виде повторяющихся частей, что позволяет картинке выглядеть качество при разных размерах элемента
  • Tiled - картинка будет повторяться, чтобы заполнить всю область
  • Filled - один из самых интересных режимов. Как он работает, смотрим на скриншотах

Text

Text — Пользовательский интерфейс — Unity — DevTribe: Разработка игр
Text

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

Button

Button — Пользовательский интерфейс — Unity — DevTribe: Разработка игр
Button

Кнопка состоит из картинки и текста, а так же специального скрипта кнопки (о нем ниже). Текст расположен как отдельный элемент внутри кнопки.

  • Interactable - можно ли на нашу кнопку нажать.
  • Transition - поведение кнопки для каждого из состояния (про состояния см. ниже):
  • ColorTint - добавление цвета фону кнопки в зависимости от состояния.
  • Animation - анимации для каждого из поведения. Нажмите кнопку "Auto Generate Animation" чтобы создать нужные компоненты и анимации для каждого из состояния кнопки. Потом вы сможете их легко редактировать в редакторе анимации.
  • SpriteSwap - замена спрайта кнопки в зависимости от состояния.
  • None - ничего не делать.
  • OnClick() - какие события будут вызываться при нажатии на эту кнопку (см. ниже)

Всего есть 4 состояния:

  • Normal - обычное состояние.
  • Highlighted - на кнопку наведена мышка или кнопка была выбрана.
  • Pressed - кнопка была нажата.
  • Disabled - кнопка заблокирована и на нее нельзя нажать и выбрать.
Пользовательский интерфейс — Unity — DevTribe: Разработка игр

Добавлять события очень легко. Сперва надо нажать "+" в правом нижнем углу. В списке появится новый пункт, первым делом надо перетащить туда объект, а затем выбрать нужный метод, который будет вызван при клике на кнопку.

Slider

Slider — Пользовательский интерфейс — Unity — DevTribe: Разработка игр
Slider

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

  • Direction - направление слайдера.
  • Min Value - минимальное значение, которое будет принимать слайдер.
  • Max Value - максимальное значение, которое будет принимать слайдер.
  • Whole Numbers - если установлено, то слайдер будет принимать только целые значения.
  • OnValueChanged() - какие события будут вызываться при нажатии на эту кнопку. В качестве события должен быть метод, который принимает один параметр типа float**

Input Field

Input Field — Пользовательский интерфейс — Unity — DevTribe: Разработка игр
Input Field

Данный элемент служит для ввода текста.

  • Starting Value - начальное значение поля.
  • InputType
  • Standart - просто текст
  • Password - текст заменяется звездочками
  • Character limit - максимальная длина текста (0 - без ограничения)
  • Multi Line - разрешить использование много-строчного текста

Scrollbar

Scrollbar — Пользовательский интерфейс — Unity — DevTribe: Разработка игр
Scrollbar
  • Size - размер бегунка.
  • Number of steps - кол-во состояний (0 - не ограничено).
  • Value - значение. Всегда в диапазоне от 0 до 1.

Так же имеет событие OnValueChanged, как и у Slider'а.

Пример работы из кода

Тут я хочу вам показать, как можно реализовать кнопку способности, как в Warcraft 3. Для этого нам понадобятся знания полученные выше, немного кривых рук ну и конечно же много экспериментов (вы же хотите научиться делать игры, не так ли? Так что больше экспериментируйте и не бойтесь что-нибудь сломать тут вам всегда смогут помочь).

Приступим:

Сперва надо набросать примерный дизайн:

Затем надо написать скрипт:

csharp - SpellButton.cs
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using System.Collections;

public class SpellButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler 
{
    /// <summary>
    /// Описание способности.
    /// </summary>
    [Multiline]
    public string SpellDescription;

    /// <summary>
    /// Время перезарядки способности.
    /// </summary>
    public float CooldownTime;

    private float timeElapsed;
    /// <summary>
    /// Показывает сколько времени осталось до перезарядки.
    /// </summary>
    public float TimeElapsed { get { return timeElapsed; } }

    /// <summary>
    /// Кнопка способности.
    /// </summary>
    public Button Button;
    /// <summary>
    /// Картинка с процессом кулдауна.
    /// </summary>
    public Image CooldownImage;
    /// <summary>
    /// Текст в подсказке.
    /// </summary>
    public Text DescriptionText;

    /// <summary>
    /// Панель для подсказки.
    /// </summary>
    public GameObject HintPanel;

    /// <summary>
    /// Событие которые вызывается в случае успешного каста.
    /// </summary>
    public UnityEvent OnSpellCasted;

    public void SpellCasted()
    {
        timeElapsed = Mathf.Max(CooldownTime, 0.1f);
        CooldownImage.enabled = true;

        OnSpellCasted.Invoke();
    }

    public void ResetCooldown()
    {
        timeElapsed = 0.0f;
        timeUpdated();
    }

	void Start()
    {
        CooldownImage.enabled = false;
        DescriptionText.text = SpellDescription;
        HintPanel.SetActive(false);
    }

    private void timeUpdated()
    {
        if (timeElapsed <= 0.0f)
        {
            timeElapsed = 0.0f;
            CooldownImage.enabled = false;
        }
        else
        {
            CooldownImage.fillAmount = timeElapsed / CooldownTime;
        }
    }

	void Update() 
    {
        if (timeElapsed > 0.0f)
        {
            timeElapsed -= Time.deltaTime;
        }

        timeUpdated();
	}

    public void OnPointerEnter(PointerEventData eventData)
    {
        HintPanel.SetActive(true);
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        HintPanel.SetActive(false);
    }
}

В заключении

В общем то на этом наверное стоит закончить. Конечно же это только основы, на самом деле функционал данной системе очень большой и охватить её в рамках одной статьи конечно же сложно. Но я думаю вы сами сможете разобраться с остальным, главное не бойтесь экспериментировать, это залог вашего успешного обучения.

Всем спасибо за внимание.



Очень полезно. Долго искал инфу о событиях OnPointerEnter и т.д.

justQd, про события я думаю посвятить отдельную статью

Я так понял, чтобы метод появился в OnClick, он должен быть публичным?

lentinant, абсолютно верно. И это касается не только метода, но и полей. Кст надо бы еще проверить, как будет себя вести с атрибутом HideInInspector

У меня почему то не сработало событие OnPointerEnter, хотелось бы увидеть статью по событиям еще. Этой жирный плюс.

SiT3D:

У меня почему то не сработало событие OnPointerEnter, хотелось бы увидеть статью по событиям еще. Этой жирный плюс.

Если ты создаешь элемент интерфейса через редактор, события надо добавлять с помощью компонента EventTrigger, создать в нем событие OnPointerEnter, и назначить ему методы, которые будут выполняться при этом событии (аналогично кнопке, в которой надо назначать методы для OnClick).

А в статье, что из скрипта добавляли? Из редактора я знаю как =) думал тут расширю свое понимание. А то скачал вчера Юнити, и думаю, что это за UI такой. Просто из редактора немного ограничен выбор методов. Ну тогда вроде все ясно понятно, спасибо.

SiT3D, тогда скрипт должен наследоваться от определенного то ли интерфейса, то ли класса.
SiT3D:

Просто из редактора немного ограничен выбор методов.

Единственное, что надо сделать с методом для выбора с редактора - сделать его публичным.

SiT3D:

У меня почему то не сработало событие OnPointerEnter, хотелось бы увидеть статью по событиям еще. Этой жирный плюс.

Я собирался написать эту статью, но пока что у меня нет времени этим заниматься(

Неплохо, полезная статья, мне как раз пригодилась :)