Получить мировую позицию пикселя из texture2d / sprite - PullRequest
0 голосов
/ 23 марта 2019

Я настраиваю автоматическую систему, чтобы иметь возможность прикреплять спрайт, и он будет собирать все свои цвета и мировое положение каждого спрайта.Был создан список / класс всех используемых цветов, но как бы получить положение всех этих спрайтов?

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

Sprite ColouredSpriteTexture = ColoredSprite.GetComponent<SpriteRenderer>().sprite;
        Texture2D ColouredTexture = ColouredSpriteTexture.texture;
        float XsizeF = ColoredSprite.transform.localScale.x;
        int Xsize = (int)XsizeF;
        float YsizeF = ColoredSprite.transform.localScale.y;
        int Ysize = (int)YsizeF;
        List<Color> TempList = new List<Color>();

    //Could spawn pixels by getting x and y size and dividing them by 100 50/100 = 0.50f
    //if the tile has a color then spawn pixel if not 0.50 += 0.50
    //TODO test if this logic will work

    float PixelSize = XsizeF / 100;
    float currentPos = PixelSize;

    for (int x = 0; x < Xsize; x++)
    {
        for (int y = 0; y < Ysize; y++)
        {
            int listAmount = TempList.Count;
            Color ColoredTex = ColouredTexture.GetPixel(x, y);
            float TextureAlpha = ColoredTex.a;

            if (!TempList.Contains(ColoredTex) && TextureAlpha != 0)
            {
                TempList.Add(ColoredTex);
                ColorByNumber tempColor = new ColorByNumber();
                tempColor.Color = ColoredTex;
                tempColor.ColorNumber = listAmount;
                ColorOptions.Add(tempColor);

            }

            if(TextureAlpha == 1)
            {
                GameObject ColorPixel = Instantiate(PixelPrefab);
                ColorPixel.transform.localScale = new Vector3(XsizeF, YsizeF, 0);
                ColorPixel.transform.SetParent(this.transform);
                ColorPixel.name = "Pixel (" + x.ToString() + "," + y.ToString() + ")";
            }

        }
    }

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

1 Ответ

1 голос
/ 23 марта 2019

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

Каждое графическое изображение в Unity имеет PPU, это и масштаб объекта будут огромным фактором. Ради аргумента я собираюсь четко определить их для 1 объекта.

  • Размеры изображения: 128х128
  • ППУ: 64
  • Масштаб: 1,1,1
  • Границы объекта: будет исходить из рендера, который я не уверен, если это уже ограничивает учитывает масштаб (скорее всего), однако в случае, если вы не может использовать то, что вы можете рассчитать ObjectBoundsWidth или высоту просто разделив ширину или высоту текстуры на PPU. Это должно дать вам границы текстуры в мировом пространстве.

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

Мировое положение пикселя, расположенного на 2,10. Согласно документации, координаты пикселей начинаются с нижнего левого угла, это означает, что 0,0 - это левый нижний угол, а 2,10 - это 2 пикселя влево и 10 пикселей вверх.

EDIT: Таким образом, я включил все это в лист Google и определил, что предыдущий алгоритм, который я предоставил, был неправильным, здесь правильный в формате псевдокода

// This function takes in either the x or y, and the width or height of 
// the bounds, then the x or y position of the object attached to.

// It also assumes the pivot is the center of the sprite.
float CalculateWorldPosOfPixelCoordinate(int coord, float boundsSize, float position, float scale)
{
    float PixelInWorldSpace = 1.0f / PPU;
    float startPos= position - (boundsSize* 0.5f * scale);

    return startPos + (PixelInWorldSpace * coord) * scale;
}

Это использование объектных границ, которые мы сами определили, поэтому умножаем на масштаб.

это даст использование мировой позиции: -0,97, -0,84

Алгоритм, на мой взгляд, тот же, что и для Y, просто замените координаты позицией Y, а границы - высотой вместо ширины.

Как я и сказал, это может быть неправильно, поскольку у меня не было возможности проверить это, это также не учитывает вращение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...