So it looks as though after learning all about SplatPrototype’s in Unity it turns out that the SplatPrototype is now depreciated!

 

 

 

The (old) method I (just) learned using Unity 2018 goes something like:

SplatPrototype[] newSplatPrototypes;
newSplatPrototypes = new SplatPrototype[splatHeights.Count];
int spindex = 0;
foreach (SplatHeights sh in splatHeights)
{
    newSplatPrototypes[spindex] = new SplatPrototype();
    newSplatPrototypes[spindex].texture = sh.texture;
    newSplatPrototypes[spindex].tileOffset = sh.tileOffset;
    newSplatPrototypes[spindex].tileSize = sh.tileSize;
    newSplatPrototypes[spindex].metallic = 0.5f;
    newSplatPrototypes[spindex].texture.Apply(true);
    spindex++;
}
// apply textures back into the terrain data
terrainData.splatPrototypes = newSplatPrototypes;

If you try to run this code in Unity 2019 you’ll get an error complaining about an obsolete API call to SplatPrototype. In order to get this to work in Unity 2019 you need to move away from SplatPrototype to the new (and so I’ve read improved) TerrainLayer. I guess having multiple layers on a terrain would make it look more realistic as opposed to alpha blending.

Trying to use the above code in Unity 2019 will get you into compiler trouble:

Terrain Layers cannot be populated at the same time as the splats
UnityEngine.TerrainData:set_splatPrototypes(SplatPrototype[])
CustomTerrain:SplatMaps() (at Assets/CustomTerrain.cs:896)
CustomTerrainEditor:OnInspectorGUI() (at Assets/Editor/CustomTerrainEditor.cs:273)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

Heading over to the code editor (Microsoft Visual Studio Community 2019 in my case) the IDE kindly tells me that:

'TerrainData.splayPrototypes' is obsolete: 'Please use the terrainLayers API instead'.

So how do I fix this? Three weeks into learning C# and Unity. I’m certainly no pro! But I managed to hack my way around it trying different things until I finally got it to work. And just so I don’t forget how, here’s the code:

Debug.Log("New Splatmaps function!");

TerrainLayer[] terrainLayer;
terrainLayer = new TerrainLayer[splatHeights.Count];
int terrainIndex = 0;
foreach (SplatHeights sh in splatHeights)
{
    terrainLayer[terrainIndex] = new TerrainLayer();
    terrainLayer[terrainIndex].diffuseTexture = sh.texture;
    terrainLayer[terrainIndex].tileOffset = sh.tileOffset;
    terrainLayer[terrainIndex].tileSize = sh.tileSize;
    terrainLayer[terrainIndex].diffuseTexture.Apply(true);
    string path = "Assets/" + this.gameObject.name + " TerrainLayer " + terrainIndex + ".terrainlayer";
    AssetDatabase.CreateAsset(terrainLayer[terrainIndex], path);
    terrainIndex++;
    Selection.activeObject = this.gameObject;
}
// apply textures back into the terrain data
terrainData.terrainLayers = terrainLayer;

And there we have it. All back and working again, albeit only using one layer of the new multi-layer API.