Как правильно делать копию эталонного объекта в Unity?
Необходимо при посещении новой области игроком создавать случайный ландшафт. На данный момент пытаюсь решить задачу так: на карте присутствует скрытый объект ландшафта, от которого делается клон, которому уже присваивается случайная карта высот:
public class ChunkLoader : MonoBehaviour
{
public Terrain flat;
void Start()
{
Terrain terrain = Instantiate(flat, new Vector3(0, 0, 0), Quaternion.identity);
HMapGenerator(terrain);
}
Terrain HMapGenerator(Terrain terrain)
{
// ... //
terrain.terrainData.SetHeights(0, 0, heights);
return terrain;
}
}
Однако, сколько я не искал, так и не обнаружил свойства или метода, с помощью которой клон можно отобразить на карте. Либо я в принципе неправильно решаю задачу, либо что-то упустил.
Ответы (1 шт):
В этом примере было сразу две ошибки.
Первая - нет никакой причины оставлять объект на сцене. После создания и настройки эталона достаточно было создать в проекте папку Assets/Prefabs и перетащить в неё эталон их иерархического древа сцены. После этого объект со сцены можно удалить, а эталон брать по необходимости, из файлов проекта.
Вторая - создавая копию объекта следует помнить, что она обладает всеми свойствами эталона, в том числе и ссылками на другие компоненты, которые вы не копировали. В данном конкретном случае объект Terrain связан с тем же компонентом TerrainData, что и префаб, и эти данные сохраняются на диске отдельным файлом. В результате, эта строчка:
terrain.terrainData.SetHeights(0, 0, heights);
изменяет общую карту высот копии и оригинала, что сводит на нет всю затею.
Решением проблемы является создание нового объекта класса TerrainData:
TerrainData tdata = new TerrainData();
изменение его так, как вам нужно, а затем уже создание из него игрового объекта Terrain:
GameObject terrobj = Terrain.CreateTerrainGameObject(tdata);
Затем создайте создайте пустой игровой объект на вашей сцене и присоедините к нему свой скрипт.