- Home /
Getting the texture of a certain point on terrain
Hello everyone.
I was wondering if there is way to check what is the texture at a given point on terrain
Thanks.
This is a good question, I don't know why it was downvoted as there is little to no information on reading the splat information of a terrain out there ....
Upvoted by me.
Having said that, I came to this question because I was interested and also wanted to know, meaning I don't have an answer sorry. I have done some work with terrains and shall have a look, as I also want to change the sound of my footstep based on the type of texture I am standing on.
Answer by AlucardJay · May 16, 2013 at 04:28 AM
Using the information provided in the below links, I have made a uJS version of reading the terrain textures at the player position, and returning an integer for the most dominant terrain texture at the players coordinates. The GUI is only there for a visual indicator, that can all be removed.
Reference Links :
http://answers.unity3d.com/questions/34328/terrain-with-multiple-splat-textures-how-can-i-det.html
http://forum.unity3d.com/threads/94723-Detecting-terrain-texture-at-position
http://answers.unity3d.com/questions/14998/how-can-i-perform-some-action-based-on-the-terrain.html
the script ( in Unity JavaScript ) :
// based on the answer here : http://answers.unity3d.com/questions/34328/terrain-with-multiple-splat-textures-how-can-i-det.html
#pragma strict
var surfaceIndex : int = 0;
private var terrain : Terrain;
private var terrainData : TerrainData;
private var terrainPos : Vector3;
function Start()
{
terrain = Terrain.activeTerrain;
terrainData = terrain.terrainData;
terrainPos = terrain.transform.position;
}
function Update()
{
surfaceIndex = GetMainTexture( transform.position );
}
// - just for GUI demonstration -
function OnGUI()
{
GUI.Box( Rect( 10, 10, 25, 25 ), surfaceIndex.ToString() );
}
// ----
function GetTextureMix( worldPos : Vector3 ) : float[]
{
// returns an array containing the relative mix of textures
// on the main terrain at this world position.
// The number of values in the array will equal the number
// of textures added to the terrain.
// calculate which splat map cell the worldPos falls within (ignoring y)
var mapX : int = parseInt( ((worldPos.x - terrainPos.x) / terrainData.size.x) * terrainData.alphamapWidth );
var mapZ : int = parseInt( ((worldPos.z - terrainPos.z) / terrainData.size.z) * terrainData.alphamapHeight );
// get the splat data for this cell as a 1x1xN 3d array (where N = number of textures)
var splatmapData : float[,,] = terrainData.GetAlphamaps( mapX, mapZ, 1, 1 );
// extract the 3D array data to a 1D array:
var cellMix : float[] = new float[ splatmapData.GetUpperBound(2) + 1 ];
for ( var n : int = 0; n < cellMix.Length; n ++ )
{
cellMix[n] = splatmapData[ 0, 0, n ];
}
return cellMix;
}
function GetMainTexture( worldPos : Vector3 ) : int
{
// returns the zero-based index of the most dominant texture
// on the main terrain at this world position.
var mix : float[] = GetTextureMix( worldPos );
var maxMix : float = 0;
var maxIndex : int = 0;
// loop through each mix value and find the maximum
for ( var n : int = 0; n < mix.Length; n ++ )
{
if ( mix[n] > maxMix )
{
maxIndex = n;
maxMix = mix[n];
}
}
return maxIndex;
}
// ----
It was probably down voted because it didn't say much.
But I didn't really know what to add :P
I thought it was pretty straight forward....
Anyway, I'm gonna test this code and get back to you.
This seems to be working pretty well.
But I'm wondering, is there a way I can know the name of texture in the returned index?
I have more the one terrain and the order of texture might not be the same.
terrainData.splatPrototypes[INDEX].texture.name should do it
Thanks, works perfectly.
Here is a C# version if anyone wants:
public int surfaceIndex = 0;
private Terrain terrain;
private TerrainData terrainData;
private Vector3 terrainPos;
// Use this for initialization
void Start () {
terrain = Terrain.activeTerrain;
terrainData = terrain.terrainData;
terrainPos = terrain.transform.position;
}
// Update is called once per frame
void Update () {
surfaceIndex = Get$$anonymous$$ainTexture(transform.position);
}
void OnGUI () {
GUI.Box(new Rect( 100, 100, 200, 25 ), "index: "+surfaceIndex.ToString()+", name: "+terrainData.splatPrototypes[surfaceIndex].texture.name);
}
private float[] GetTexture$$anonymous$$ix(Vector3 WorldPos){
// returns an array containing the relative mix of textures
// on the main terrain at this world position.
// The number of values in the array will equal the number
// of textures added to the terrain.
// calculate which splat map cell the worldPos falls within (ignoring y)
int mapX = (int)(((WorldPos.x - terrainPos.x) / terrainData.size.x) * terrainData.alphamapWidth);
int mapZ = (int)(((WorldPos.z - terrainPos.z) / terrainData.size.z) * terrainData.alphamapHeight);
// get the splat data for this cell as a 1x1xN 3d array (where N = number of textures)
float[,,] splatmapData = terrainData.GetAlphamaps( mapX, mapZ, 1, 1 );
// extract the 3D array data to a 1D array:
float[] cell$$anonymous$$ix = new float[ splatmapData.GetUpperBound(2) + 1 ];
for(int n=0; n<cell$$anonymous$$ix.Length; n++){
cell$$anonymous$$ix[n] = splatmapData[ 0, 0, n ];
}
return cell$$anonymous$$ix;
}
private int Get$$anonymous$$ainTexture(Vector3 WorldPos){
// returns the zero-based index of the most do$$anonymous$$ant texture
// on the main terrain at this world position.
float[] mix = GetTexture$$anonymous$$ix(WorldPos);
float max$$anonymous$$ix = 0;
int maxIndex = 0;
// loop through each mix value and find the maximum
for(int n=0; n<mix.Length; n++){
if ( mix[n] > max$$anonymous$$ix ){
maxIndex = n;
max$$anonymous$$ix = mix[n];
}
}
return maxIndex;
}
:)
OH $$anonymous$$Y GOD! THAN$$anonymous$$ YOU SO $$anonymous$$UCH! I've been literally searching this for months! Lifesaver, man.
Ditto on that! Thanks so much alucardj!
Your answer
Follow this Question
Related Questions
Terrain Texture (applied programatically) Disappears When Entering Play Mode 0 Answers
How to generate multiple Terrain objects with different TerrainData and Splat Texture via C# script? 1 Answer
Terrain prototype goes black when building project 0 Answers
How expand the terrain palette of textures 1 Answer
Alphamaps with new cloned terrain 0 Answers