Hello to everybody
this is my first post, so I hope that I’m writing in the correct area.
I am developing with some other students a small game for a university exam and I have a question related to terrains.
The idea is simple: suppose to have a big, desert scenario with a sand-like texture, made with a terrain. Now, when the player makes certain actions, a building is spawned at a defined point on the terrain (i.e. the position of the player), and this is easily done. The painful part is that we want to simulate an anti-desertification process, so when a building is placed, the texture of the adjacent area (a circle of a defined range) on the terrain should change to a grass texture. Does any of you have an idea about how to achieve this, or maybe have already done that? If so, code snippets are reeeeally welcome
(I use C#, if it’s important)
I think that the correct start point lays in the TerrainData APIs, but I wasn’t able to find anything useful by now.
Thanks in advance!
Ok, I somehow managed to make it work.
I’ll just leave a few considerations if someone interested in the same topic should need some help, too.
As I thought, I had to use the Get/SetAlphamap of the TerrainData class. The content of the float[,] array was, actually, the X Y coordinates and a third value representing the splat used by that point, i.e. a number between 0 and the texture count of the terrain. This means that for each 2D point on the terrain surface we have to assign a value between 0 and 1 for each splat to define an alpha value.
Since I had just 2 textures (the former the desert, the latter the grass) I had to put, for each X-Y pair inside the circle, a value of 1 to the grass splat, and 0 to the desert one. Note that the total sum of the values assigned to splats should be 1.
The circle, however, resulted ellipsoid because the alphamap was not squared, so I adopted a different approach. I decided to change the whole terrain texture by gradually showing the grass texture instead of the desert one. The alpha value of each texture is defined by a percentage, which in my case is set by another script.
I’ll leave here the script if someone should need something similar.
using UnityEngine;
using System.Collections;
public class TerrainTerraforming : MonoBehaviour {
private float[,,] alphaData;
private TerrainData tData;
private float percentage;
private const int DESERT = 0; //These numbers depend on the order in which
private const int GRASS = 1; //the textures are loaded onto the terrain
void Start() {
tData = Terrain.activeTerrain.terrainData;
alphaData = tData.GetAlphamaps(0, 0, tData.alphamapWidth, tData.alphamapHeight);
SetPercentage(0);
}
public void SetPercentage(double perc){
percentage = (float) perc /100f;
for(int y=0; y<tData.alphamapHeight; y++){
for(int x = 0; x < tData.alphamapWidth; x++){
alphaData[x, y, DESERT] = 1 - percentage;
alphaData[x, y, GRASS] = percentage;
}
}
tData.SetAlphamaps(0, 0, alphaData);
}
}
1 Like
You just saved me a ton of work… aside from that I was getting agrivated that javascript would not support float[,]…
You sir…are awesome. I hdn’t even thought of doing something like this but I’m definitely going to now:)
This followed in in the respect of procedural terrains. I eventually got this working for a project where I created the height map and then used the steepness and height to define what the texture was. looks great in the end.
That explanation just saved a lot of time for me…
What im trying to do is make grass grow in the same manner as you are trying to set grass texture.
Only difference is that im trying to make the detail grass texture (realistic blades of grass) grow in a circle around the player…
I’ll try stuff with the terraindata API and post here if im successfull…