2025, Nov 18 18:03
Прогресс-бар в Ursina растёт в обе стороны: как исправить origin
Почему прогресс-бар в Ursina масштабируется сразу влево и вправо, и как это исправить. Показываем, как закрепить origin на стороне и получить рост от края.
Масштабировать полосу здоровья, боезапаса или перезарядки в Ursina вроде бы просто — пока она внезапно не начинает увеличиваться сразу в обе стороны. Если при изменении масштаба ваш прогресс‑бар растёт одновременно влево и вправо, виновата почти всегда одна вещь: origin объекта находится в центре.
Кратко о проблеме
Вам нужна полоса, которая отражает меняющееся значение, например время восстановления выстрела. Идея — по мере хода таймера увеличивать масштаб по оси X. Однако вместо заполнения с одного края полоса расширяется симметрично, из‑за чего UI выглядит некорректно.
Минимальный пример, воспроизводящий проблему
Ниже логика, которая обновляет ширину полосы на основе таймера. Имена условные, но поведение полностью повторяет исходную ситуацию.
if can_shoot == False and cooldown >= 0.5:
can_shoot = True
cooldown = 0
elif can_shoot == True and cooldown >= 0.5:
cooldown = 0
if can_shoot == True:
regen_bar.scale_x = 12
if can_shoot == False:
regen_bar.scale_x = cooldown * 24
Player = Avatar()
regen_bar = Entity(model="quad", position=(-13, -9, -2), scale=(12, 0.5, 1), color="FFFF00")
Здесь булевый флаг определяет, можно ли стрелять, а таймер ограничивает выстрел. Длина полосы зависит от значения таймера и сбрасывается, когда всё готово.
Почему полоса растёт в обе стороны
В Ursina масштабирование происходит относительно опорной точки — origin. По умолчанию это origin=(0, 0, 0), то есть центр объекта. Масштабируясь вокруг центра, объект увеличивается поровну влево и вправо — поэтому ваша полоса тянется сразу в две стороны, а не заполняется от одного края.
Если задать другой origin, изменится и точка опоры. Поместите его на левую грань — и полоса останется закреплённой слева, увеличиваясь вправо по мере роста масштаба. Аналогично, origin на правой грани заставит полосу расширяться влево.
Решение: закрепите origin на стороне
Совместите origin полосы с той стороной, которую нужно зафиксировать. Использование origin=(-.5, 0, 0) фиксирует левую сторону и тянет полосу вправо. Использование origin=(.5, 0, 0) фиксирует правую сторону и тянет влево.
if can_shoot == False and cooldown >= 0.5:
can_shoot = True
cooldown = 0
elif can_shoot == True and cooldown >= 0.5:
cooldown = 0
if can_shoot == True:
regen_bar.scale_x = 12
if can_shoot == False:
regen_bar.scale_x = cooldown * 24
Player = Avatar()
regen_bar = Entity(
model="quad",
position=(-13, -9, -2),
scale=(12, 0.5, 1),
origin=(-.5, 0, 0), # закрепляем слева, растём вправо
color="FFFF00"
)
В зависимости от раскладки интерфейса после смены origin может понадобиться подправить position.x, чтобы сохранить выравнивание с остальными элементами.
Почему это важно
Полосы состояния, таймеры и индикаторы прогресса держатся на предсказуемых точках привязки. Когда origin стоит в центре, масштаб зеркалится по обе стороны и ломает привычную модель «заполнения» от одного края. Понимание того, как ведёт себя origin, избавляет от путаницы при создании HUD‑элементов и упрощает их позиционирование и анимацию.
Выводы
Если полоса в Ursina масштабируется сразу в две стороны, причина — стандартный origin в центре. Перенесите origin на левую или правую кромку, чтобы зафиксировать одну сторону и получить односторонний рост. Если новая точка опоры сместила визуальное выравнивание, слегка подкорректируйте позицию. Тогда полосы перезарядки, здоровья или боезапаса будут заполняться именно так, как вы задумывали.