Как сделать прокрутку в unity

Добавил пользователь Алексей Ф.
Обновлено: 04.10.2024

Продолжаем делать наш Unity for dummies платформер.

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

Если вы не в курсе, как работают хуки жизненного цикла в Unity, вы можете ознакомиться с данной статьёй.

Затем выбираем наш объект Player слева, в меню иерархии, и закрепляем инспектор (меню справа), нажав на замок в верхнем правом углу.

Пока закрываем все ненужные компоненты (Box Collider 2D, etc), нажимая на стрелочку у каждого из них.

Теперь перетаскиваем наш скрипт в инспектор, и он прикрепляется к объекту Player (если вы не выполнили предыдщуий пункт с закрепением меню, то вы этого сделать не сможете).

Если зайти в Edit => Project Settings => Input Manager, то мы можём увидеть настройки управления. Например, прыжок (Jump) назначен на пробел, в то время, как движение по горизонтали назначено на a, d, ←,→.

Запомним это для того, чтобы затем использовать в коде (названия инпутов Jump, Horizontal).

Пора покодить. Два раза нажимаем на наш скрипт PlayerBehaviour, и Unity отдаст его в руки Visual Studio.

Честно, данную IDE я не люблю. Потому я открываю его в VScode (а вы хоть в VIMе пишите - это ваш выбор).

Я не буду часто использовать try/catch в этом коде, но вам очень советую - сильно экономит время.

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

Мне не нравится, что персонажа переворачивает. Исправим.

Заходим в инспектор, открываем Rigidbody2D и ставим галочку на Freeze Rotation Z.

Жить можно, но есть проблема - камера не двигается за персонажем.

Есть два основных способа научить камеру двигаться за персонажем.

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

2. Задать движение камеры за персонажем програмно.

Создаём скрипт CameraBehaviour, и привязываем его к объекту Main Camera (добавляем через инспектор).

Открываем наш новый скрипт, и начинаем кодить (да, мне на работе не хватает, продолжаю и после).

Фиксируем объект камеры на замок в инспекторе, и перетаскиваем наш объект Player в GameObject.

Теперь камера двигается за игроком.

Однако камера постоянно вылезает за пределы уровня, показывая синий фон.

Я не уверен, что моё решение правильное. Буду рад, если кто-нибудь поделится своими соображениями на данный счёт.

Если у камеры пропала рамка (у меня, внезапно, случилась такая оказия - потратил аж 2 минуты на решение проблемы), надо зайти в Gizmos и отметить чекбокс на камере.

Добавляем в наш скрипт CameraBehaviour следующий код:

[Header("Camera position restrictions")] public float minY; public float maxY; public float minX; public float maxX;

Двигаем камеру, и снимаем наши измерения ее положений.

На скрине ниже камера стоит в левом нижнем углу сцены.

Исходя из поля Position, я выбираю минимум по Х = -12, по Y = -0.5 (числа округлены их -12.09 и -0.84) соответсвенно.

Проставляем снятые позиции для камеры (мои и ваши позиции будут отличаться).

Теперь обновим метод UpdateCameraPosition в скрипте CameraBehaviour

Mathf.Clamp принимает первым аргументом позицию объекта, за которым следует игрок, вторым и третим аргументами минимум и максимум - этими значениями метод будет ограничивать число, которые по итогу получит камера в качестве своей координаты.

Отлично, камера перестала "гулять". Работаем дальше.

Всё бы хорошо, но наш персонаж может летать - надо всего лишь жать кнопку прыжка. Добавим проверку на нахождение на земле.

Выбираем наш Foreground, и создаём новый слой 'Ground' в инспекторе.

Снова тыкаем на Foreground, и выбираем в поле Layer наш только что созданный слой.

Переходим к коду.

Добавим в PlayerBehaviour такую строчку.

Теперь в объекте Player мы можем выбрать наш свежесозданный слой.

Обновляем наш PlayerBehaviour. Добавим коллайдер (rigidBody мы создавали ранее).

Теперь мы можем обновить обработку перемещения персонажа в методе updatePlayerPosition

Тут я вспомнил, что забыл глянуть, как "наделся" Box Collider на персонажа. Кажется, все ок - линии идут ровно по персонажу (жёлтая рамка). Если что, всегда можно ткнуть на Edit Collider и подтянуть его.

Летать мы разучились, а по платформе больше не скользим. Победа!

  • Из-за слоя Ground персонаж может прыгать от стенок. Не знаю, как это можно решить.
  • Является ли ограничение движения камеры, которое я написал, отимальным.
  • Иногда персонаж застревает на месте. Такое ощущение, что коллайдер видит какой то микропиксель, и персонаж застревает на нём.

Я не уверен, что моё решение правильное. Буду рад, если кто-нибудь поделится своими соображениями на данный счёт

Привет.
Я, конечно, дохуя вовремя, когда у тебя уже пять статей и рефакторинг, но вот щас иду за тобой пока вот на этом месте.
Короче, в ассет-сторе есть проект 2D Game Kit от разрабов движка. Там движение камеры сделано буквально следующим образом, если помню (давно открывал). Уровень завёрнут в коллайдер, ещё один коллайдер на камере. Соответственно, когда она о него стукается, то расслабляется и не двигается. И ещё там угарный камера-лаг стоит, чтоб камера не жёстко следовала за персонажем, а как бы за верёвочку.

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

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

Каким образом можно создать вертикально пролистываемый список из кнопок в unity при помощи UI?Количество кнопок всегда разное и зависит от данных,введенных игроком.

Ответы (3 шт):

Небольшой туториал [EN]

Для этого необходимо создать:

  1. ScrollRect - сам список.
  2. Layout группу. На ваш вкус. В вашем случае это VerticalLayoutGroup .
  3. Создать связь между Layout группой и ScrollRect . Задав в необходимое поле в ScrollRect нашу группу ( ScrollRect.content ).
  4. Создавать дочерними элементами относительно Layout нужные кнопки. button.transform.SetParent(layout.transform);

Так же можете поиграться с LayoutElement , добавив его к вашей кнопке.

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

Создаёте стандартный UI/Scroll View через правую кнопку мыши в иерархии/любым иным привычным способом. На объект content вешаете компоненты [Vertical Layout Group] и [Content Size Fiter][1] На корневой объект префаба вешаете [Layout Element]

Дальше вышеназванные компоненты настраиваете и подгоняете согласно своим запросам. Смотря кто чем из них должен управлять. Прикрепил к компонентам ссылки на их API.

Судя по комментариям, которые я от вас тут увидел, вас вообще интересует возможность добавить объекты в список в процессе игры.

Содержание класса, который будет это делать выглядит примерно так:

[SerializeField] - отображает поле в редакторе, но оставляет его приватным, что в отличии от модификатора public не нарушает инкапсуляцию класса Instantiate - создаёт и возвращает копию объекта. есть перегрузки - можете ознакомиться в документации. После создания объекта, можете делать с ним, что хотите, а после настройки помещаете в дочерние объекты внутрь контента скрул ректа, который автоматически уже включит этот объект в скорлящийся список(Vertical Layout Group) и изменит свой размер(Content Size Fiter)

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

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 , когда я прокручиваю список вверх и вниз. Дайте знать, если у вас появятся вопросы.

Я хочу реализовать scrollview в Unity3D 5 UI с горизонтальными изображениями, загруженными из Интернета, они имеют разные случайные пропорции, но я хочу, чтобы они были постоянной. И ширина будет соответствовать их соотношению сторон, например:

enter image description here

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

Любые идеи, как достичь этого? Благодарю.

Вам нужно использовать ScrollView с включенной горизонтальной прокруткой, а вертикальная прокрутка отключена. Настройте свою иерархию, как показано на рисунке ниже:

enter image description here

В GameObject с именем Content attach Horizontal Layout Group и Content Size Fitter со следующими настройками:

enter image description here

Затем на всех ваших изображениях присоедините компонент " Layout Element и во время выполнения вычислите ширину, используя соотношение сторон изображения и высоты в игровом объекте Content и присвойте этой ширине свойству " Preferred Width компонента " Layout Element : на следующем изображении 300 вычислено ширина для изображения:

enter image description here

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

ps Я написал этот ответ в спешке. Надеюсь, это будет иметь смысл для вас, если не сообщит мне, и я улучшу свой ответ.

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