Как сделать чтоб клавиши на экране принимали horizontal и vertical unity

Добавил пользователь Евгений Кузнецов
Обновлено: 04.10.2024

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

Вступление

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

Начало. Canvas.

Создание полотна для интерфейса

Я думаю объяснять как создавать сцену нет смысла, поэтому пропустим все лишние действия и перейдем непосредственно к самому интерфейсу. Новая система построена на модулях ввода (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 - камера с помощью которой будут происходить обработки событий ввода пользователя.

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

Screen Space - Overlay Screen Space - Camera World Space

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

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

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

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

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

Пользовательский интерфейс — Unity — DevTribe: инди-игры, разработка, сообщество

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

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

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

якорь находится в центре якорь находится слева

окно пресетов

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

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

состояние 1 состояние 2 иерархия

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

панель кнопка

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

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

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

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

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

Image

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

оригинал Horizotal + Left Vertical + Bottom Radial90 + Bottom Left Radial180 + Bottom Radial360 + Bottom

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

Button

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

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

  • Normal - обычное состояние.
  • Highlighted - на кнопку наведена мышка или кнопка была выбрана.
  • Pressed - кнопка была нажата.
  • Disabled - кнопка заблокирована и на нее нельзя нажать и выбрать.

Пользовательский интерфейс — Unity — DevTribe: инди-игры, разработка, сообщество

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

Slider

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

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

Input Field

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

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

Scrollbar

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

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

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

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

вид из редактора иерархия объектов вид в инспекторе вид из игры, активно вид из игры, перезаряжается

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

В заключении

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

Я пытался найти решение этой проблемы какое-то время без везения.

Я хочу, чтобы иметь возможность двигаться в 8 направлениях, но по какой-то нечетной причине мой игрок хочет двигаться только в 6 направлениях.

Когда я нажимаю:

W + D или W + A, он перемещается в верхнем правом углу.

S + D или S + A, он перемещается в левый нижний угол.

Вертикальные и горизонтальные движения работают отлично. Это всего лишь два из четырех диагональных движений, которые становятся болью.

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

enter image description here

enter image description here2

enter image description here3

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

Вы не назначили viewport своему компоненту ScrollRect . Вам также может понадобиться Content Size Fitter на GridList и сделать его размером Vertical , а затем прикрепить его к верхней части PanelStore .

1 ответ

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

Во-первых, вот схема моей иерархии:

Чтобы понять, почему у меня все настроено, я разбиваю каждый объект и прикрепленные компоненты, привязку, окраску и т. Д.

Панель_маска

Самая внешняя часть вашего свитка должна быть Mask . Вы можете использовать компонент Mask , если геометрия вашего спрайта непрямоугольная, или вы можете использовать Rect Mask2D , который намного эффективнее, но будет работать правильно только в том случае, если ваш пользовательский интерфейс представляет собой прямоугольник. Вы также заметите, что цвет моего компонента маски почти полностью ясен. Вам не нужно этого делать, но цвет настроен так, что альфа-канал равен (1/255) . Если у вас есть Mask на объекте, а альфа - 0 , все дочерние объекты не появятся. Я установил цвет фона своего свитка на ScrollRect вместо этого.

Panel_Scroll

Следующим слоем будет ваш ScrollRect . Поскольку Mask - это вся видимая часть вашего пользовательского интерфейса, ScrollRect определяет пространство, в котором пользователь может прокручивать пользовательский интерфейс. В этом случае я установил якоря на растяжение по размеру, чтобы максимизировать пространство, в котором будет работать прокрутка. Наряду с этим, есть еще три важных шага при настройке ScrollRect . Во-первых, проверьте, в каком направлении вы хотите прокручивать: horizontal или vertical . Затем вам нужно будет назначить Viewport вашего пользовательского интерфейса. Viewport - это просто место, где прокрутка видна пользователю. Поскольку есть компонент Mask , видимая часть - это что угодно внутри этого Mask , поэтому назначьте Panel_Mask в качестве области просмотра. Наконец, вам нужно будет назначить Content прокрутки, то есть фактические данные, которые прокрутка будет содержать и позволяющие пользователю перемещаться между ними. Здесь должен быть назначен объект, привязанный к Panel_Scroll , Panel_Content .

Panel_Content

Последней частью настройки прокрутки будет наш контент. Контент - это объект, содержащий все данные, которые пользователь может прокручивать. Поскольку количество объектов может быть переменным, вам нужно будет присвоить HorizontalLayoutGroup , VerticalLayoutGroup или GridLayoutGroup , в зависимости от ваших потребностей. В вашем случае VerticalLayoutGroup подойдет, так как ваша прокрутка имеет вертикальное движение. Вы можете испортить определенные настройки группы макетов, но для имеющейся у меня настройки я сделал объекты содержимого прокрутки подходящими по ширине их контейнера и определил их собственную высоту. Я также добавил небольшой интервал, чтобы различать объекты в прокрутке. Поскольку мне обычно нравится, чтобы контент начинался с верхней части моего контейнера пользовательского интерфейса, я также устанавливаю точки привязки контента, которые выровнены по верхнему краю, что означает, что он будет заполнять ширину своего родителя и всегда будет включаться. верх родительского контейнера. Последний компонент - это ContentSizeFitter , что заставляет объект изменять размер до размеров его дочерних объектов. По мере того, как список объектов в вашем списке растет, ContentSizeFitter будет расти вместе с ним, аналогично, если он сжимается, будет расти и Panel_Content .

Image_Data

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

Вот гифка готового продукта в виде свитка:

Позже на гифке я показал вид сцены, чтобы показать, как работает компонент Mask , когда я прокручиваю список вверх и вниз. Дайте знать, если у вас появятся вопросы.

объект движется за счет импульса.

rigidbody.AddForce(Vector3.forward * 10.00f *Time.deltaTime * inputDevice.LeftStickY, ForceMode.Impulse);
rigidbody.AddForce(Vector3.right * 10.00f *Time.deltaTime * inputDevice.LeftStick.Right, ForceMode.Impulse);
rigidbody.AddForce(Vector3.left * 10.00f *Time.deltaTime * inputDevice.LeftStick.Left, ForceMode.Impulse);


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

if(Input.GetMouseButton(1)) <
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
>
y = ClampAngle(y, yMinLimit, yMaxLimit);

как сделано допустим когда поворачиваешь камеру, но по объекту не видно то что он крутится, а он все равно при движении прямо движется куда камера смотрит? Вот мне нужно тоже самое, но не выходит. поворот камеры делаю так:

что это "как сделано допустим когда поворачиваешь камеру, но по объекту не видно то что он крутится, а он все равно при движении прямо движется куда камера смотрит?"
это уже реализовано в какой-то игре или патент получать будешь?

тебе нужно, чтобы при повороте камеры персонаж поворачивался в направлении, куда смотрит камера?
персонаж является target для камеры?
возьми направление камеры и через Lerp выставляй направление для персонажа (вертикальную ось исключить, чтобы персонаж не наклонялся вбок, вперед-назад; если персонажу и не нужно отклоняться от оси z, то замораживай z ось и Lerp'ь по всем трем осям).

Читайте также: