Почему разновидности и сколько их?
Часто сталкиваюсь с тем, что люди просто не понимают как подвинуть объект в UI на какое то значение, и удивляются что результат зачастую непредсказуем. Или допустим как получить правильные координаты объекта в UI. Если мы через дебагер выведем обычную позицию объекта(position), то она будет сильно отличаться от той что мы видим в инспекторе у UI элемента, так что же мы там видим и как это работает? В итоге перебираются 100500 решений с форумов пока какое либо не подойдет. Хочу придать подобным процессам осмысленное движение.
Суть подвоха заключается в следующем — у обычного Transform есть потомок RectTransform который и отвечает за положение и многие вещи связанные с размером, скейлом и тд — элемента UI. И благодаря ему мы можем получить следующие варианты координат.
- position
- localPosition
- anchoredPosition (есть еще anchoredPosition3D, но его не будем рассматривать отдельно, а будем считать что это подвид test.anchoredPosition
Обычная позиция
Обычная позиция не относится к системе координат UI от слова вообще. Это некие общие координаты объекта во всём мире юнити, и в мире некое представление позиции объекта которое не связано с интерфейсом.Eсли вы захотите сдвинуть объект на его ширину, это не сработает, так как у канваса координаты в пикселях относительно экрана. А в глобальных координатах это не пиксели. Поэтому объект сместится в мире допустим на 200 единиц измерения мира, а не на 200 пикселей, и просто улетит в неведомые дали. Но это можно разумно использовать. Позже расскажу как.
Якорная позиция (anchoredPosition)
То что мы видим в инспекторе — и есть оно.
В юнити можно выставлять якорные точки, это некая точка относительно которой будет позиционироваться UI элемент, в том числе при изменениях размера/пропорций родительского объекта.
Вот тут видно что мы поменяли размер родительского объекта и пропорции, наш объект придерживается центра родительского объекта, и его координаты не изменились, хотя на экране он уже не на том месте что раньше.
Якорная позиция — координаты объекта относительно якоря. Выставим якорь в левый верхний угол и увидим что координаты изменились.
Если вы хотите сместить объект на его ширину, то надо менять anchoredPosition или localPosition. Локальная позиция для UI элементов тоже вычисляется в пикселях, но по другому. Поэтому если вам нужно манипулировать двумя UI элементами относительно друг друга. То лучше использовать локальную позицию. Почему же?
Локальная позиция (localPosition)
Итак, что же такое локальная позиция:
Это система координат, когда в центре родительского объекта находится 0. Правый верхний угол это положительная ширина ректа делённая пополам. Левый верхний отрицательное значение ширины попалам. То есть если ширина ректа 800 пикселей, то посередине x =0, в правом верхнем 400, в левом верхнем -400. Поэтому если вам нужно без учёта якорей посчитать координаты — лучше использовать локальные позиции. При условии что у них общий предок/рект. К слову, якоря можно использовать не только как конкретную точку на родительском объекте, но и как пропорции относительно родительского объекта. Во втором случае anchoredPosition будет возвращать localPosition.
Для чего можно использовать обычный position для UI элементов? Скажем так, в рамках глобальных координат, если одному объекту назначить координаты второго, то они будут находится в одной точке, безотносительно своих якорей или локальных позиций, иногда это удобно — когда элементы находятся на разных канвасах/в разных панелях и системы координат локальные/якорные не совпадают.
Вывод/итог
- В инспекторе у UI элементов показываются anchoredPosition или пропорции относительно родительского объекта. AnchoredPosition считается в зависимости от положения якоря
- localPosition позволяет получить общие координаты относительно родителя, без привязки к якорям.
- position — это глобальня позиция элемента в пространстве сцены, не привязана к UI.
Надеюсь, кому-то поможет :-)