'Unity: Runtime-Terrain-Editor How to raise a circle
I'm trying to create a terrain editor, that works on runtime. At this point I can raise a square but have problems to raise a circle-shape. I saw this post and thoughts thats the solution for my problem, so I transfered it to my code. It really raise a circle somewhere (where I dont click) but its not efficient, because its updating the whole terrain.
The whole function:
public void RaiseTerrain(Terrain terrain, Vector3 location, float effectIncrement)
{
int offset = areaOfEffectSize / 2;
Vector3 tempCoord = (location - terrain.GetPosition());
Vector3 coord;
coord = new Vector3(
(tempCoord.x / GetTerrainSize().x),
(tempCoord.y / GetTerrainSize().y),
(tempCoord.z / GetTerrainSize().z)
);
Vector3 locationInTerrain = new Vector3(coord.x * terrainHeightMapWidth, 0, coord.z * terrainHeightMapHeight);
int terX = (int)locationInTerrain.x - offset;
int terZ = (int)locationInTerrain.z - offset;
int terXInv = (int)locationInTerrain.x + offset;
int terZInv = (int)locationInTerrain.z + offset;
//This raises a square
//float[,] heights = targetTerrainData.GetHeights(terX, terZ, areaOfEffectSize, areaOfEffectSize);
//for (int xx = 0; xx < areaOfEffectSize; xx++)
//{
// for (int yy = 0; yy < areaOfEffectSize; yy++)
// {
// heights[xx, yy] += (effectIncrement * Time.smoothDeltaTime);
// }
//}
//targetTerrainData.SetHeights(terX, terZ, heights);
//This raises a circle
float[,] heights = targetTerrainData.GetHeights(0, 0, terrainHeightMapWidth, terrainHeightMapHeight);
for (int xx = terX; xx < terXInv; xx++)
{
for (int yy = terZ; yy < terZInv; yy++)
{
float currentRadiusSqr = (new Vector2(locationInTerrain.x, locationInTerrain.z) - new Vector2(xx, yy)).sqrMagnitude;
if(currentRadiusSqr < offset*offset)
{
heights[xx, yy] += (effectIncrement * Time.smoothDeltaTime);
}
}
}
targetTerrainData.SetHeights(0, 0, heights);
}
All following lines are just excerpts from above.
I guess my problem is this line:
float[,] heights = targetTerrainData.GetHeights(0, 0, terrainHeightMapWidth, terrainHeightMapHeight);
Because raising a square works fine. I just update a specific area, so its updating the terrain without dropping framerate:
float[,] heights = targetTerrainData.GetHeights(terX, terZ, areaOfEffectSize, areaOfEffectSize);
[...]
targetTerrainData.SetHeights(terX, terZ, heights);
So my question is, how can I raise a circle and update the changes like I did with raising a square? Update only the changed heights?
I tried to use this lines from the square:
float[,] heights = targetTerrainData.GetHeights(terX, terZ, areaOfEffectSize, areaOfEffectSize);
[...]
targetTerrainData.SetHeights(terX, terZ, heights);
in comination with:
for (int xx = terX; xx < terXInv; xx++)
{
for (int yy = terZ; yy < terZInv; yy++)
{
float currentRadiusSqr = (new Vector2(locationInTerrain.x, locationInTerrain.z) - new Vector2(xx, yy)).sqrMagnitude;
if(currentRadiusSqr < offset*offset)
{
heights[xx, yy] += (effectIncrement * Time.smoothDeltaTime);
}
}
}
but it didnt work. Im getting an error:
IndexOutOfRangeException: Index was outside the bounds of the array.
Solution 1:[1]
instead of heights[xx, yy] += (effectIncrement * Time.smoothDeltaTime); try heights[yy, xx] += (effectIncrement * Time.smoothDeltaTime); this seems to work for me
int offset = radious / 2;
int mouseX = (int)((point.x / terrainData.size.x) * heightmapWidth);
int mouseZ = (int)((point.z / terrainData.size.z) * heightmapHeight);
int terX = mouseX - offset;
int terZ = mouseZ - offset;
int terXInv = mouseX + offset;
int terZInv = mouseZ + offset;
float[,] heights = terrainData.GetHeights(0, 0, heightmapWidth, heightmapHeight);
for (int xx = terX; xx < terXInv; xx++)
{
for (int yy = terZ; yy < terZInv; yy++)
{
float currentRadiusSqr = (new Vector2(mouseX, mouseZ) - new Vector2(xx, yy)).sqrMagnitude;
if (currentRadiusSqr < offset * offset)
{
heights[yy, xx] += (strength * Time.smoothDeltaTime);
}
}
}
terrainData.SetHeights(0, 0, heights);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Damon Nomad |