Однопиксельные горизонтальные разделительные линии мерцают с Unity ScrollRect?
У меня есть некоторые GameObjects внутри ScrollRect (на самом деле внутри объекта контента, который переводит ScrollRect).
Когда localPosition объекта содержимого перемещается, дочерние объекты перемещаются, как и ожидалось, но горизонтальный разделитель, присутствующий в нижней части каждого дочернего объекта, не отображается постоянно. Иногда линии выглядят толще или тоньше и "мерцают" при прокрутке.
Я бы хотел, чтобы горизонтальные линии не менялись заметно. Есть идеи как это сделать?
3 ответа
Я столкнулся с той же проблемой. Поэтому я попытался нормализовать положение контента относительно экрана. Я конвертирую мировую позицию в позицию на экране, округляю ее, чтобы привязать к позициям в пикселях, и конвертирую обратно в мировую позицию. Он обновляет позицию контента каждый кадр
public class PixelPerfectScrollRect : ScrollRect
{
public Camera Camera; // or use Camera.main
protected override void LateUpdate()
{
base.LateUpdate();
EnsurePixelPerfectScroll();
}
void EnsurePixelPerfectScroll ()
{
if (!Camera || !content)
{
return;
}
var pos = content.position;
var screenPoint = Camera.WorldToScreenPoint(pos);
screenPoint.y = Mathf.Round(screenPoint.y);
screenPoint.x = Mathf.Round(screenPoint.x);
pos = Camera.ScreenToWorldPoint(screenPoint);
content.position = pos;
}
}
Я столкнулся с этим вопросом, пытаясь решить аналогичную проблему самостоятельно, поэтому решил, что поделюсь своим решением.
Предполагая, что вы хотите ограничить ScrollRect целыми пикселями, вы можете сделать что-то вроде этого:
public class PixelPerfectScrollRect : ScrollRect
{
protected override void LateUpdate ()
{
base.LateUpdate();
ensurePixelPerfectScroll();
}
void ensurePixelPerfectScroll ()
{
float diff = content.rect.height - viewport.rect.height;
float normalizedPixel = 1 / diff;
verticalNormalizedPosition = Mathf.Ceil(verticalNormalizedPosition / normalizedPixel) * normalizedPixel;
// can also do the same for horizontalNormalizedPosition, using rect.width instead of rect.height
}
}
Прикрепите его к GameObject и используйте его так же, как ScrollRect. Это также предполагает, что каждая единица UI - это один пиксель; вам придется масштабировать
normalizedPixel
если это не относится к вашей игре.
Это работает, потому что ScrollRects может перемещать свои
content
RectTransforms до
diff
в пикселях от их происхождения в локальном пространстве. Если ScrollRects использует значения пикселей, мы могли бы просто округлить их до целых чисел, но поскольку ScrollRects работает с нормализованными позициями, нам нужно нормализовать желаемые значения пикселей. Если в "пиксельном пространстве" вы переместитесь с 0 на
diff
с шагом 1, в "нормализованном пространстве" вам нужно перейти от 0 к 1 с шагом 1/diff
. (Вы делите все пространство на
diff
.) Поэтому нам нужно убедиться, что наше нормализованное значение округлено до ближайшего кратного 1/diff
.
Я считаю, что вы можете использовать свойство Canvas.pixelPerfect, чтобы заставить элементы пользовательского интерфейса соответствовать стандартам pixelperfect.