Однопиксельные горизонтальные разделительные линии мерцают с 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.

Другие вопросы по тегам