- Home /
Efficiently change many terrains' textures at once?
I have many terrain tiles in my scene that I want to be able to toggle between different styles of textures. Initially I was just looping through the terrains and setting the diffusetexture of the terrainlayer. This caused a hitch that was unacceptable for a VR application. I tried a few other things, unsuccessfully. Right now I have it running the loop through a coroutine to spread out the load over a few frames. This works, but I would like to have all of the textures change at once. Any tips?
Answer by dan_wipf · May 02, 2019 at 05:59 AM
you do not need to loop through the terrains. Just put your TerrainLayers from the Asset Folder in to an Array and change the Textures via Code.
for Example =>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TerrainLayerTexturesChange : MonoBehaviour
{
public TerrainLayer[] TerrainLayers;
public Texture2D[] diffuseTextures;
public Texture2D[] normalMapTextures;
public void ChangeTextures(){
if(TerrainLayers.Length == diffuseTextures.Length && TerrainLayers.Length == normalMapTextures.Length){
for(int i = 0; i<TerrainLayers.Length;i++){
TerrainLayers[i].diffuseTexture = diffuseTextures[i];
TerrainLayers[i].normalMapTexture = normalMapTextures[i];
}
}
}
}
Or working with Structs
public class TerrainLayerTexturesChangeWithStructs : MonoBehaviour{
[System.Serializable] public struct CustomTerrainLayers{
[SerializeField] public TerrainLayer MyTerrainLayer;
[SerializeField] public LayerTexture[] LayerTextures;
[SerializeField] [HideInInspector] public LayerTexture OriginalTextures;
}
[System.Serializable] public struct LayerTexture{
[SerializeField] public Texture2D DiffuseTexture;
[SerializeField] public Texture2D NormalMapTexture;
}
public CustomTerrainLayers[] TerrainLayers;
public int TextureIndex = 0;
void OnEnable(){
for(int i = 0; i<TerrainLayers.Length;i++){
TerrainLayers[i].OriginalTextures.DiffuseTexture = TerrainLayers[i].MyTerrainLayer.diffuseTexture;
TerrainLayers[i].OriginalTextures.NormalMapTexture = TerrainLayers[i].MyTerrainLayer.normalMapTexture;
}
}
public void ChangeTextures(){
for(int i = 0; i<TerrainLayers.Length;i++){
TerrainLayers[i].MyTerrainLayer.diffuseTexture = TerrainLayers[i].LayerTextures[TextureIndex].DiffuseTexture;
TerrainLayers[i].MyTerrainLayer.normalMapTexture = TerrainLayers[i].LayerTextures[TextureIndex].NormalMapTexture;
}
}
public void ResetLayersToOriginal(){
for(int i = 0; i<TerrainLayers.Length;i++){
TerrainLayers[i].MyTerrainLayer.diffuseTexture = TerrainLayers[i].OriginalTextures.DiffuseTexture;
TerrainLayers[i].MyTerrainLayer.normalMapTexture = TerrainLayers[i].OriginalTextures.NormalMapTexture;
}
}
}
if you fire those functions as a Single Event, this should keep you going quite fast
Your answer
Follow this Question
Related Questions
TerrainData is missing splat texture 3. 1 Answer
offset and misbehaviour Issue with the 'Paint Texture' tool in the Terrain Editor 0 Answers
Why does my .raw heightmap create ugly errors when loaded into a terrain? 1 Answer
Spherical Terrain or screenshot to texture 0 Answers
Terrain Texture (applied programatically) Disappears When Entering Play Mode 0 Answers