2014-08-28 1 views
11

У меня есть массив объектов Sprite в Unity. Их размер зависит от загруженного изображения. Я хочу объединить их бок о бок, как плиточную карту в одно изображение. Я хочу, чтобы они были макетом, как будто вы формируете линию изображений один за другим. (обратите внимание: НЕ один на другой) Как я могу это сделать?Объединить массив объектов Sprite в One Sprite - Unity

Причина, по которой я совмещаю (только для тех, кто хочет знать), заключается в том, что я использую коллайдер polygon2D. Поскольку есть некоторые странные поведения, происходящие, когда я использую несколько коллайдеров бок о бок, я решил просто объединить изображения, прежде чем добавлять один большой коллайдер многоугольника. Обратите внимание, что все это происходит во время выполнения. Я не могу просто создать большое изображение и загрузить его, потому что порядок изображений определяется только во время выполнения.

Надеюсь получить некоторую помощь. Благодарю.

+0

Вы пробовали комбинировать только коллайдеры? это была бы моя первая попытка, поскольку они кажутся проблемой. Если спрайты довольно просты, просто создайте пути вручную, если не прочитайте пути от исходных polygonColliders и добавьте их все в новый или существующий и удалите остальные. – Tom

+0

@ То, что я пробовал, но не смог найти способ комбинировать коллайдеры. Я написал код, который получает все точки, тогда я удаляю дублированные точки, и я не получил результат, который хотел. Когда я посмотрел на него, я понял, что мне нужно найти способ определения допустимых путей. Я должен игнорировать путь, который закрывает каждое изображение. Но как мне это сделать, когда мои изображения различаются по форме и размерам (состоит из множества точек), вы могли бы указать мне в правильном направлении/лучше, но помогите мне с этим. Благодарю. – cessmestreet

+0

в зависимости от количества путей, которые вы получаете от всех коллайдеров, вы можете просто скопировать их без изменения: сориентируйте пути всех коллайдеров вместе, затем установите путьCount вашего нового коллайдера на это число, затем пройдите по всем путям и установите их в новый коллайдер с SetPath(). Мое предположение было бы <50-100 путей все еще хорошо. Я столкнулся с проблемами, когда алгоритм создал 1000+ путей, так как навсегда потребовалось бы объединение сетки с путями. – Tom

ответ

5

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

// your textures to combine 
// !! after importing as sprite change to advance mode and enable read and write property !! 
public Sprite[] textures; 
// just to see on editor nothing to add from editor 
public Texture2D atlas; 
public Material testMaterial; 
public SpriteRenderer testSpriteRenderer; 

int textureWidthCounter = 0; 
int width,height; 
void Start() { 
    // determine your size from sprites 
    width = 0; 
    height = 0; 
    foreach(Sprite t in textures) 
    { 
     width += t.texture.width; 
     // determine the height 
     if(t.texture.height > height)height = t.texture.height; 
    } 

    // make your new texture 
    atlas = new Texture2D(width,height,TextureFormat.RGBA32,false); 
    // loop through your textures 
    for(int i= 0; i<textures.Length; i++) 
    { 
     int y = 0; 
     while (y < atlas.height) { 
      int x = 0; 
      while (x < textures[i].texture.width){ 
       if(y < textures[i].texture.height){ 
        // fill your texture 
        atlas.SetPixel(x + textureWidthCounter, y, textures[i].texture.GetPixel(x,y)); 
       } 
       else { 
        // add transparency 
        atlas.SetPixel(x + textureWidthCounter, y,new Color(0f,0f,0f,0f)); 
       } 
       ++x; 
      } 
      ++y; 
     } 
     atlas.Apply(); 
     textureWidthCounter += textures[i].texture.width; 
    } 
    // for normal renderers 
    if(testMaterial != null)testMaterial.mainTexture = atlas; 
    // for sprite renderer just make a sprite from texture 
    Sprite s = Sprite.Create(atlas,new Rect(0f,0f,atlas.width,atlas.height),new Vector2(0.5f, 0.5f)); 
    testSpriteRenderer.sprite = s; 
    // add your polygon collider 
    testSpriteRenderer.gameObject.AddComponent<PolygonCollider2D>(); 
} 
+0

Спасибо за это. Я это попробую. Как дорого это будет? Будет ли это сильно влиять на производительность моей игры? Если да, то я думаю, что я просто использую это как инструмент, чтобы я мог создать коллайдер многоугольника для моего объекта и просто сохранить его как сборник. Но в любом случае, вы удивительны. Благодарю. – cessmestreet

+0

Сохранение как prefab будет лучше, я думаю, так как метод использует n кубический вложенный цикл, это может вызвать некоторые проблемы, если вы создаете большие текстуры. Вы должны проверить и найти то, что лучше для вашей ситуации. – nexx

+0

Yah. Я просто решил использовать его в качестве инструмента и сохранить его как сборный. Я заметил, что он не может создавать большие текстуры. Но это сработало и благодарит вас за это. По крайней мере мне было бы легче создать многоугольник. Благодарю. – cessmestreet