[unity3d] Портируем террейн /или/ Дербаним *.unr файлы (часть 3)


Часть#3 : Импорт в Unity3D
Первое, что с что нужно усвоить  - это то, что у unity, и у unreal разная система координат :
  • относительно terraina центр координат в Unity (далее просто u5) находится в нижнем левом углу, а в Unreal2 (далее ue2) строго по центру "куба" карты
  • ось yaw инвертирована
  • оси Y в UE2 - это Z в Unity  и наоборот 
Из данных трех пунктов можно заключить, что перевод координат из ue2 в u5 будет выглядеть следующим образом :
new Vector3(ue2_vector3.x, ue2_vector3.z, -ue2_vector3.y)



Так же следует принять во внимание, что в мире ue2 всё меряется в т.н. unreal unit'ах (uu):
256 UU = 487.68 cm = 16 feet.
1 meter = 52.5 UU
1 foot = 16 UU
1 cm = 0.525 UU
1 UU = 0.75 inches

Перейдем непосредственно к terrain'у:
Размер террейна представлен квадратом со стороной 32768 UU. Откуда я получил это число ?
Pазмер height map равен 256х256 px, а в TerrainInfo0 имеется property TerrainScale :
"TerrainScale":"X":128.0,"Y":128.0,"Z":72.0. 
Решив простую арифметическую задачу 128*256 получим то самое число 32768.
Стоит отметить, что между картами есть шов толщиной в 1px, равный 128UU (или 8 футов),  который в ue строится автоматически, с линейной интерполяцией hmap и масок.

Все текстуры распределяются по маскам или alphamap layers. Обычно их количество не больше 10 (исключение - это Lobby т.к. имеет до 23 слоев). И хотя официальный мануал по unity3D рекомендует не превышать пяти, мы не будем отходить от оригинала.


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


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

текщий_слой + сумма_всех_предыдущих_слоев = 1
текщий_слой = const

соответственно с каждым новым слоем мы пересчитываем сумму предыдущих слоев.

Таким образом, после импорта масок в terrainData необходимо прогнать цикл нормализации весов:

for (int z 0sizez++)                                                             
{                                                                                           
    for (
int x 0sizex++)                                                         
    {                                                                                       
                                                                                           
        for (
int layer 0layer layerslayer++)                                       
        {                                                                                   
            
float last_lay_sum alphamaps[zxlayer];                               
            for (
int last_layer 0last_layer layerlast_layer++)                     
            {                                                                               
                if (
last_lay_sum != 0){                                                     
                    
alphamaps[zxlast_layer] = alphamaps[zxlast_layer] * last_lay_sum;                                 
                }                                                                           
                else{                                                                       
                    
alphamaps[zxlast_layer] = 0;                                       
                }                                                                           
            } 
                                                                                
             
                                                                                 
        } 
                                                                                    
    } 
                                                                                        
}  
                                                                                           

В результате мы получим прекрасный результат !


Осталось только напомнить, что после импорта текстур следует соотнести масштаб в соответствии с параметрами "UScale" ,"VScale" и "DrawScale".

                var tileSize_x = UScale * DrawScale;
                var tileSize_y = VScale * DrawScale;

                prototype.tileOffset = new Vector2(0, 0);
                prototype.tileSize = new Vector2(tileSize_x, tileSize_y);

Вот и всё !

Комментарии

  1. Не очень понятно, как именно вы импортировали маски?

    ОтветитьУдалить
    Ответы
    1. Задай вопрос более конкретно.

      Удалить
  2. Можно как то в автоматическом режиме экспортировать список StaticMeshActor-ов из urn?

    ОтветитьУдалить

Отправить комментарий