I am new to Unity3d and I’m playing around with a proof of concept project.
I’m currently stuck because I use a blank terrain prefab (easily instantiable) that I may want to include having its own scripts.
When my worldcreator object (blank object with script) starts instantiating the terrain pieces in a grid I’m noticing something very odd.
When I instantiate the terrain prefab, alter its height map and move on to instantiating the next piece, the next instantiating piece is carrying over heightmap terrain data from the previous instantiation. When I go to the unity3d editor and drag the prefab to the scene, it as well has the altered heightmap data from the last play.
I’m kind of lost as to why this would happen and I’m wondering if I’m not understanding what exactly instantiating really is or why the prefab in my project would be altered. Before today I thought prefabs were “read only” from a code perspective till they were instantiated and then altered based on in-game variables.
Here is my code.
#pragma strict
public var maxStrength: float = 1;
public var numOfTerrainBySide: int = 4;
public var terrainXsize = 500; //not used
public var terrainZsize = 500;
public var terrainYsize = 50;
public var terrainHeightMapSize = 512;
public var worldPiece: Terrain; //Prefab blank terrain linked from /prefabs/worldpiece
private var wploc : Vector3;
private var wprot : Quaternion;
function Start()
{
//get starting position of blank object "WorldCreator"
wploc = transform.position;
wprot = transform.rotation;
buildWorld();
}
function buildWorld()
{
//for each numOfTerrainBySide on X axis
for(var z = 1; z-1 < numOfTerrainBySide; z ++)
{
//for each numOfTerrainBySide on Z axis per X
for(var x = 1; x-1 < numOfTerrainBySide; x++)
{
var newloc = Vector3(terrainXsize * x - terrainXsize, wploc.y, terrainZsize * z - terrainZsize);
buildWorldPiece(newloc,wprot,x,z);
}
}
}
function buildWorldPiece(wploc,wprot,gridx,gridz)
{
//create terrain from prefab object
var newterrain : Terrain = new Instantiate(worldPiece, wploc, wprot);
//name object based on it's grid location
newterrain.name = "wp_" + gridx + "_" + gridz;
var xRes = newterrain.terrainData.heightmapWidth;
var yRes = newterrain.terrainData.heightmapHeight;
var heights = newterrain.terrainData.GetHeights(0, 0, xRes, yRes);
for (var x: int = 0; x < yRes; x++)
{
for (var z: int = 0; z < xRes; z++)
{
//proof of concept to put border around edges of multiple terrains
if (gridx == 1 && z == 0)
{
heights[x,z] = Random.Range(1.0f, terrainYsize);
}
if (gridz == 1 && x == 0)
{
heights[x,z] = Random.Range(1.0f, terrainYsize);
}
if (gridx == numOfTerrainBySide && z == terrainHeightMapSize)
{
heights[x,z] = Random.Range(1.0f, terrainYsize);
}
if (gridz == numOfTerrainBySide && x == terrainHeightMapSize)
{
heights[x,z] = Random.Range(1.0f, terrainYsize);
}
}
}
newterrain.terrainData.SetHeights(0, 0, heights);
}