После перехода с Unity 2018.4.1f1 (64-bit) на Unity 2019.3.2f1 (64-bit) появились шашечки
Мои методы раскраски террейн:
using UnityEngine;
using System.Linq;
using System.IO;
using UnityEditor;
using System.Collections.Generic;
using UnityEngine.Experimental.TerrainAPI;
// used for Sum of array
public class IntArrayComparer : IEqualityComparer<int[]>
{
/// <summary>
/// Equals the specified x and y.
/// </summary>
/// <param name="x">The x coordinate.</param>
/// <param name="y">The y coordinate.</param>
public bool Equals(int[] x, int[] y)
{
if (x.Length != y.Length)
{
return false;
}
for (int i = 0; i < x.Length; i++)
{
if (x[i] != y[i])
{
return false;
}
}
return true;
}
/// <summary>
/// Gets the hash code.
/// </summary>
/// <returns>The hash code.</returns>
/// <param name="obj">Object.</param>
public int GetHashCode(int[] obj)
{
int result = 17;
for (int i = 0; i < obj.Length; i++)
{
unchecked
{
result = result * 23 + obj[i];
}
}
return result;
}
}
public class AssignSplatMap : EditorWindow
{
int brushnamesfield = 0;
float pos = 0.01f;
int texture = 3;
int mode = 0;
[MenuItem("Window/test/TexturingTerrain")]
static void Init()
{
// Get existing open window or if none, make a new one:
AssignSplatMap window = (AssignSplatMap)EditorWindow.GetWindow(typeof(AssignSplatMap));
window.Show();
}
void OnGUI()
{
List<string> brushnames = new List<string>();
DirectoryInfo dir = new DirectoryInfo(Application.dataPath + "/Resources/BrushTexture/TIFF");
foreach (var item in dir.GetFiles("*.tif"))
brushnames.Add("BrushTexture/TIFF/" + item.Name.Split('.')[0]);
brushnamesfield = EditorGUILayout.Popup(brushnamesfield, brushnames.ToArray());
// pos = EditorGUILayout.FloatField(pos);
// texture=EditorGUILayout.IntField(texture);
mode = EditorGUILayout.IntField(mode);
if (GUILayout.Button("TerrainTexturing"))
{
TerrainTexturing();
}
if (GUILayout.Button("TexturingBrushLittlePoint"))
{
TexturingBrushLittlePoint();
}
if (GUILayout.Button("TexturingBrush"))
{
TexturingBrush(mode, brushnames);
}
}
void TerrainTexturing(bool selected = true)
{
Terrain[] _terrains;
Dictionary<int[], Terrain> _terrainDict = null;
// Get the attached terrain component
if (_terrainDict == null)
_terrainDict = new Dictionary<int[], Terrain>(new IntArrayComparer());
else
_terrainDict.Clear();
List<Terrain> terrains = new List<Terrain>();
if (selected)
{
foreach (var item in Selection.gameObjects)
{
Terrain terrain = item.GetComponent<Terrain>();
if (terrain != null)
terrains.Add(terrain);
}
}
else
terrains.AddRange(Terrain.activeTerrains);
_terrains = terrains.ToArray();
foreach (var t in terrains)
{
// Debug.Log(t.name);
TerrainData terrainData = t.terrainData;
float[,,] splatmapData = new float[terrainData.alphamapWidth, terrainData.alphamapHeight, terrainData.alphamapLayers];
for (int y = 0; y < terrainData.alphamapHeight; y++)
{
for (int x = 0; x < terrainData.alphamapWidth; x++)
{
float[] splatWeights = new float[terrainData.alphamapLayers];
splatWeights[0] = 0.3f;
splatWeights[1] = 0.5f;
splatWeights[2] = 0.3f;
float z = splatWeights.Sum();
for (int i = 0; i < terrainData.alphamapLayers; i++)
{
splatWeights[i] /= z;
splatmapData[x, y, i] = splatWeights[i];
}
}
}
terrainData.SetAlphamaps(0, 0, splatmapData);
}
}
void TexturingBrush(int mode, List<string> brushnames, bool selected = true)
{
// Get the attached terrain component
Terrain[] _terrains;
Dictionary<int[], Terrain> _terrainDict = null;
System.Random random = new System.Random();
// Get the attached terrain component
if (_terrainDict == null)
_terrainDict = new Dictionary<int[], Terrain>(new IntArrayComparer());
else
_terrainDict.Clear();
List<Terrain> terrains = new List<Terrain>();
if (selected)
{
foreach (var item in Selection.gameObjects)
{
Terrain terrain = item.GetComponent<Terrain>();
if (terrain != null)
terrains.Add(terrain);
}
}
else
terrains.AddRange(Terrain.activeTerrains);
_terrains = terrains.ToArray();
string brushnames1;
string brushnames2;
int texture1;
int texture2;
int maxrand;
int Maxbrushsize;
int Minbrushsize;
for (int coui = 0; coui < 4; coui++)
{
float alpha1 = 1;
float alpha2 = 1;
switch (coui)
{
case 3:
brushnames1 = "BrushTexture/TIFF/brush_35";
brushnames2 = null;
texture1 = 2;
texture2 = 5;
maxrand = random.Next(0, 3);
Minbrushsize = 50;
Maxbrushsize = 600;
break;
case 0:
// brushnames1 = "BrushTexture/TIFF/SimpleFoamBrushNew";
// brushnames2 = "BrushTexture/TIFF/brush_28";
brushnames1 = null;
brushnames2 = null;
texture1 = 11;
texture2 = 8;
maxrand = random.Next(30, 101);
if (maxrand <= 50)
maxrand = -1;
Minbrushsize = 2;
Maxbrushsize = 50;
break;
case 1:
brushnames1 = "BrushTexture/TIFF/brush_5";
brushnames2 = "BrushTexture/TIFF/brush_5";
texture1 = 8;
texture2 = 1;
maxrand = random.Next(3, 10);
Minbrushsize = 500;
Maxbrushsize = 1200;
alpha1 = 1;
alpha2 = 1;
break;
case 2:
brushnames1 = null;
brushnames2 = "BrushTexture/TIFF/brush_5";
texture1 = 11;
texture2 = 2;
maxrand = random.Next(5, 10);
Minbrushsize = 500;
Maxbrushsize = 1200;
alpha1 = 0.5f;
alpha2 = 0.5f;
break;
case 5:
// brushnames1 = "BrushTexture/TIFF/SimpleFoamBrushNew";
brushnames1 = "BrushTexture/TIFF/brush_24";
brushnames2 = "BrushTexture/TIFF/brush_5";
texture1 = 7;
texture2 = 2;
maxrand = random.Next(5, 16);
Minbrushsize = 100;
Maxbrushsize = 700;
alpha1 = 0.2f;
alpha2 = 0.7f;
break;
case 6:
brushnames1 = "BrushTexture/TIFF/brush_2";
brushnames2 = "BrushTexture/TIFF/brush_16";
texture1 = 7;
texture2 = 1;
maxrand = random.Next(0, 3);
Minbrushsize = 500;
Maxbrushsize = 1000;
break;
default:
brushnames1 = "BrushTexture/TIFF/brush_24";
brushnames2 = "BrushTexture/TIFF/brush_5";
texture1 = 7;
texture2 = 5;
maxrand = random.Next(5, 16);
Minbrushsize = 50;
Maxbrushsize = 300;
break;
}
foreach (var terrain in terrains)
{
Debug.Log("Количество " + maxrand);
for (int i = 0; i <= maxrand; i++)
{
float Brushsize = random.Next(Minbrushsize, Maxbrushsize);
float Rotation = random.Next(0, 360);
Vector2 v2 = new Vector2(random.Next(0, 100) * 0.01f, random.Next(1, 100) * 0.01f);
DrawPoint(v2, terrain, texture1, Rotation, Brushsize, alpha1, brushnames1);
Rotation = random.Next(0, 360);
DrawPoint(v2, terrain, texture2, Rotation, Brushsize, alpha2, brushnames2);
}
}
}
}
void TexturingBrushLittlePoint(bool selected = true)
{
// Get the attached terrain component
Terrain[] _terrains;
Dictionary<int[], Terrain> _terrainDict = null;
System.Random random = new System.Random();
// Get the attached terrain component
if (_terrainDict == null)
_terrainDict = new Dictionary<int[], Terrain>(new IntArrayComparer());
else
_terrainDict.Clear();
List<Terrain> terrains = new List<Terrain>();
if (selected)
{
foreach (var item in Selection.gameObjects)
{
Terrain terrain = item.GetComponent<Terrain>();
if (terrain != null)
terrains.Add(terrain);
}
}
else
terrains.AddRange(Terrain.activeTerrains);
_terrains = terrains.ToArray();
int maxrand = random.Next(200, 10000);
int Minbrushsize = 2;
int Maxbrushsize = 15;
List<int> textid = new List<int>() { 2, 5 };
List<string> brs = new List<string>() { "BrushTexture/TIFF/brush_3", "BrushTexture/TIFF/brush_4", "BrushTexture/TIFF/brush_26", "BrushTexture/TIFF/brush_24" };
float alpha = 0.7f;
foreach (var terrain in terrains)
{
Debug.Log("Количество " + maxrand);
for (int i = 0; i <= maxrand; i++)
{
float Brushsize = random.Next(Minbrushsize, Maxbrushsize);
float Rotation = random.Next(0, 360);
Vector2 v2 = new Vector2(random.Next(0, 100) * 0.01f, random.Next(1, 100) * 0.01f);
DrawPoint(v2, terrain, textid[random.Next(0, textid.Count)], Rotation, Brushsize, alpha, brs[random.Next(0, brs.Count)]);
}
}
maxrand = random.Next(200, 1000);
Minbrushsize = 15;
Maxbrushsize = 30;
textid = new List<int>() { 2, 5 };
brs = new List<string>() { "BrushTexture/TIFF/brush_3", "BrushTexture/TIFF/brush_4", "BrushTexture/TIFF/brush_26", "BrushTexture/TIFF/brush_24" };
alpha = 0.7f;
foreach (var terrain in terrains)
{
Debug.Log("Количество " + maxrand);
for (int i = 0; i <= maxrand; i++)
{
float Brushsize = random.Next(Minbrushsize, Maxbrushsize);
float Rotation = random.Next(0, 360);
Vector2 v2 = new Vector2(random.Next(0, 100) * 0.01f, random.Next(1, 100) * 0.01f);
DrawPoint(v2, terrain, textid[random.Next(0, textid.Count)], Rotation, Brushsize, alpha, brs[random.Next(0, brs.Count)]);
}
}
}
static public void DrawPoint(Vector2 v2, Terrain t, int textnum, float Rotation, float Brushsize, float alpha, string brushnames)
{
if (brushnames != null)
{
Debug.Log("PosX " + v2.x + "PosY " + v2.y);
Debug.Log("brush " + Brushsize);
TerrainLayer m_SelectedTerrainLayer = null;
m_SelectedTerrainLayer = t.terrainData.terrainLayers[textnum];//ссылка на слой в Инспекторе
Texture2D brushTexture = Resources.Load<Texture2D>(brushnames);
Material mat = TerrainPaintUtility.GetBuiltinPaintMaterial();
BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(t, v2, Brushsize, Rotation);
PaintContext paintContext = TerrainPaintUtility.BeginPaintTexture(t, brushXform.GetBrushXYBounds(), m_SelectedTerrainLayer);
Vector4 brushParams = new Vector4(0.5f, alpha, 0.0f, 0.0f);
mat.SetTexture("_BrushTex", brushTexture);
mat.SetVector("_BrushParams", brushParams);
TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat);
Debug.Log("Something");
Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, (int)TerrainPaintUtility.BuiltinPaintMaterialPasses.PaintTexture);
TerrainPaintUtility.EndPaintTexture(paintContext, "Terrain Paint - Texture");
}
}
void newTexturing(bool selected = true)
{
// Get the attached terrain component
Terrain[] _terrains;
Dictionary<int[], Terrain> _terrainDict = null;
// Get the attached terrain component
if (_terrainDict == null)
_terrainDict = new Dictionary<int[], Terrain>(new IntArrayComparer());
else
_terrainDict.Clear();
List<Terrain> terrains = new List<Terrain>();
if (selected)
{
foreach (var item in Selection.gameObjects)
{
Terrain terrain = item.GetComponent<Terrain>();
if (terrain != null)
terrains.Add(terrain);
}
}
else
terrains.AddRange(Terrain.activeTerrains);
_terrains = terrains.ToArray();
foreach (var terrain in terrains)
{
// Get a reference to the terrain data
TerrainData terrainData = terrain.terrainData;
// Splatmap data is stored internally as a 3d array of floats, so declare a new empty array ready for your custom splatmap data:
float[,,] splatmapData = new float[terrainData.alphamapWidth, terrainData.alphamapHeight, terrainData.alphamapLayers];
for (int y = 0; y < terrainData.alphamapHeight; y++)
{
for (int x = 0; x < terrainData.alphamapWidth; x++)
{
// Normalise x/y coordinates to range 0-1
float y_01 = (float)y / (float)terrainData.alphamapHeight;
float x_01 = (float)x / (float)terrainData.alphamapWidth;
// Sample the height at this location (note GetHeight expects int coordinates corresponding to locations in the heightmap array)
float height = terrainData.GetHeight(Mathf.RoundToInt(y_01 * terrainData.heightmapResolution), Mathf.RoundToInt(x_01 * terrainData.heightmapResolution));
// Calculate the normal of the terrain (note this is in normalised coordinates relative to the overall terrain dimensions)
Vector3 normal = terrainData.GetInterpolatedNormal(y_01, x_01);
// Calculate the steepness of the terrain
float steepness = terrainData.GetSteepness(y_01, x_01);
// Setup an array to record the mix of texture weights at this point
float[] splatWeights = new float[terrainData.alphamapLayers];
// CHANGE THE RULES BELOW TO SET THE WEIGHTS OF EACH TEXTURE ON WHATEVER RULES YOU WANT
// Texture[0] has constant influence
splatWeights[0] = 0.3f;
splatWeights[1] = 0.5f;
splatWeights[2] = 0.3f;
// Texture[1] is stronger at lower altitudes
splatWeights[2] = Mathf.Clamp01((terrainData.heightmapResolution - height));
splatWeights[6] = Mathf.Clamp01((terrainData.heightmapResolution - height));
// Texture[2] stronger on flatter terrain
// Note "steepness" is unbounded, so we "normalise" it by dividing by the extent of heightmap height and scale factor
// Subtract result from 1.0 to give greater weighting to flat surfaces
splatWeights[6] = 1.0f - Mathf.Clamp01(steepness * steepness / (terrainData.heightmapResolution / 5.0f));
splatWeights[1] = 1.0f - Mathf.Clamp01(steepness * steepness / (terrainData.heightmapResolution / 5.0f));
// Texture[3] increases with height but only on surfaces facing positive Z axis
splatWeights[8] = height * Mathf.Clamp01(normal.z);
splatWeights[6] = height * Mathf.Clamp01(normal.z);
// Sum of all textures weights must add to 1, so calculate normalization factor from sum of weights
float z = splatWeights.Sum();
// Loop through each terrain texture
for (int i = 0; i < terrainData.alphamapLayers; i++)
{
// Normalize so that sum of all texture weights = 1
splatWeights[i] /= z;
// Assign this point to the splatmap array
splatmapData[x, y, i] = splatWeights[i];
}
}
}
// Finally assign the new splatmap to the terrainData:
terrainData.SetAlphamaps(0, 0, splatmapData);
}
}
}
Раскрашиваю в три прохода.Может это возникать из-за того что не все текстуры подхватились?



