/// <summary> /// </summary> /// <param name="terrainData"></param> /// <param name="position">Location in the XZ plane (not the XY plane!)</param> /// <param name="sphereRadius"></param> /// <returns></returns> private static Vector3 AdjustSpawnPositionForTerrainShape(TerrainData terrainData, Vector2 position, float sphereRadius) { var height = terrainData.GetInterpolatedHeight(position.x, position.y); var normal = terrainData.GetInterpolatedNormal(position.x, position.y); var offsetAlongNormal = normal * sphereRadius; var positionOnTerrain = new Vector3(position.x, height, position.y); return positionOnTerrain + offsetAlongNormal; }
void checkTerrain(JSONNode mines) { terrain_data = terrain.terrainData; // var pos = mines[0]; // float x = pos[0].AsFloat, y = pos[1].AsFloat, z = pos[2].AsFloat; // Debug.Log ("mine0: x: " + x + ", " + "z: " + z + ", " + "y: " + y); // Debug.Log ("InterpolatedHeight: " + terrain_data.GetInterpolatedHeight((x+150.0f)/300.0f, (z+150.0f)/300.0f)); // // pos = mines[1]; // x = pos [0].AsFloat; y = pos [1].AsFloat; z = pos[2].AsFloat; // Debug.Log ("mine1: x: " + x + ", " + "z: " + z + ", " + "y: " + y); // Debug.Log ("InterpolatedHeight: " + terrain_data.GetInterpolatedHeight((x+150.0f)/300.0f, (z+150.0f)/300.0f)); // // pos = mines[2]; // x = pos [0].AsFloat; y = pos[1].AsFloat; z = pos[2].AsFloat; // Debug.Log ("mine2: x: " + x + ", " + "z: " + z + ", " + "y: " + y); // Debug.Log ("InterpolatedHeight: " + terrain_data.GetInterpolatedHeight((x+150.0f)/300.0f, (z+150.0f)/300.0f)); float[] x = new float[200]; float[] y = new float[200]; int mine_num = 200; for (int i = 0; i < mine_num; i++){ var pos = mines[i]; float px = pos[0].AsFloat, py = pos[1].AsFloat, pz = pos[2].AsFloat; x[i] = terrain_data.GetInterpolatedHeight((px+150.0f)/300.0f, (pz+150.0f)/300.0f); y[i] = py; Debug.Log(i); } float mxy = 0; float mx = 0; float mx2 = 0; float my = 0; for (int i = 0; i < mine_num; i++){ mx += x[i]; mx2 += x[i] * x[i]; my += y[i]; mxy += x[i]*y[i]; } mx /= mine_num; mx2 /= mine_num; my /= mine_num; mxy /= mine_num; float a_up = mxy - mx * my; float a_down = mx2 - mx * mx; float a = a_up / a_down; float b = my - a * mx; Debug.Log("a: "+a); Debug.Log("b: "+b); }
void OnGUI() { if (finalize) { // select created texture Selection.activeObject=AssetDatabase.LoadAssetAtPath(save_path, typeof(Texture2D)); finalize=false; } EditorGUILayout.Space(); sourceTerrain = EditorGUILayout.ObjectField("Source Terrain Data", sourceTerrain, typeof(TerrainData), false) as TerrainData; EditorGUILayout.Space(); if (sourceTerrain) { bool render_flag=false; bool render_flag_npot=false; if (GUILayout.Button("Render heights")) { render_flag=true; } if (GUILayout.Button("Render heights (NPOT exact size 2^n+1)")) { render_flag_npot=true; } if (render_flag || render_flag_npot) { rendered_tex=new Texture2D(sourceTerrain.heightmapResolution-(render_flag_npot ? 0:1), sourceTerrain.heightmapResolution-(render_flag_npot ? 0:1), TextureFormat.RGBA32, false, true); Color32[] cols=new Color32[rendered_tex.width * rendered_tex.height]; for( int x = 0; x < rendered_tex.width; x++ ) { for( int y = 0; y < rendered_tex.height; y++ ) { float _x = 1.0f*x/(rendered_tex.width-1); float _y = 1.0f*y/(rendered_tex.height-1); int _hiP,_loP; float hgt = sourceTerrain.GetInterpolatedHeight( _x,_y )/sourceTerrain.size.y; _hiP = Mathf.FloorToInt( hgt*255.0f ); _loP = Mathf.FloorToInt( (hgt*255.0f - _hiP)*255.0f ); int _Nx, _Nz; Vector3 norm = sourceTerrain.GetInterpolatedNormal( _x,_y ); _Nx = Mathf.RoundToInt( Mathf.Clamp01(norm.x*0.5f+0.5f)*255.0f ); _Nz = Mathf.RoundToInt( Mathf.Clamp01(norm.z*0.5f+0.5f)*255.0f ); cols[y * rendered_tex.width + x] = new Color32( (byte)_hiP, (byte)_loP, (byte)_Nx, (byte)_Nz ); } } rendered_tex.SetPixels32(cols); rendered_tex.Apply(false,false); if (Selection.activeObject is Texture2D && AssetDatabase.GetAssetPath(Selection.activeObject as Texture2D)!="") { save_path=AssetDatabase.GetAssetPath(Selection.activeObject as Texture2D); directory=Path.GetDirectoryName(save_path); file=Path.GetFileNameWithoutExtension(save_path)+".png"; } else { if (save_path=="") { directory=Path.GetDirectoryName(AssetDatabase.GetAssetPath(sourceTerrain)); file=Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(sourceTerrain))+".png"; } } } } if (rendered_tex) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Height(RG) & normal(BA) texture", GUILayout.MinWidth(200)); EditorGUILayout.ObjectField(rendered_tex, typeof(Texture2D), false, GUILayout.MinWidth(150), GUILayout.MinHeight(150), GUILayout.MaxWidth(150), GUILayout.MaxHeight(150)); EditorGUILayout.EndHorizontal(); if (GUILayout.Button("Save texture")) { if (save_path=="") { directory=Path.GetDirectoryName(AssetDatabase.GetAssetPath(sourceTerrain)); file=Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(sourceTerrain))+".png"; } SaveTexture(directory, file); } } }
void SetMines(JSONNode mines) { terrain_data = terrain.terrainData; int mine_num = 200; int n = rocks.Length; for (int i = 0; i < mine_num; i++) { var pos = mines[i]; float x = pos[0].AsFloat, y = pos[1].AsFloat, z = pos[2].AsFloat; y = terrain_data.GetInterpolatedHeight((x+150.0f)/300.0f, (z+150.0f)/300.0f)-14.11622f; /*if (x*x + z*z > 50 * 50) y -= 1; if (x*x + z*z > 100 * 100) y -= 2;*/ Quaternion q = Quaternion.Euler(0,0,0); //Quaternion q = Quaternion.Euler(UnityEngine.Random.Range(0, 360), UnityEngine.Random.Range(0, 360), UnityEngine.Random.Range(0, 360)); GameObject temp = (UnityEngine.GameObject)Instantiate(mine, new Vector3(x,y,z), q); } }
/// <summary> /// Generate trees on the terrain /// </summary> List<TreeInstance> GenerateTrees(TerrainData data, int tileX, int tileZ) { //make sure prototypes have been set if (_treePrototypes.Length < 1) { return null; } var trees = new List<TreeInstance>(); int spacing = 8; var maxHeight = _terrainSettings.TerrainHeight * 0.7f; var minHeight = _terrainSettings.TerrainHeight * 0.1f; for (var x = 0; x < _terrainSize; x += spacing) { for (var z = 0; z < _terrainSize; z += spacing) { var unit = 1.0f / (_terrainSize - 1); var offsetX = Random.value * unit * spacing; var offsetZ = Random.value * unit * spacing; var xNorm = x * unit + offsetX; var zNorm = z * unit + offsetZ; var xWorld = x + tileX * (_terrainSize - 1); var zWorld = z + tileZ * (_terrainSize - 1); //randomizes the spacing spacing = Random.Range(4, 12); // Get the steepness value at the normalized coordinate. var angle = data.GetSteepness(xNorm, zNorm); // Steepness is given as an angle, 0..90 degrees. Divide // by 90 to get an alpha blending value in the range 0..1. var frac = angle / 90.0f; if (frac < 0.7f) { var noise = _treeNoise.FractalNoise2D(xWorld, zWorld, 3, _terrainSettings.TreeFrequency, 1.0f); var height = data.GetInterpolatedHeight(xNorm, zNorm); //no trees on high mountains if (noise > 0.1f && height < maxHeight && height > minHeight) { //Create the tree instance var tree = new TreeInstance() { heightScale = 1, widthScale = 1, prototypeIndex = Random.Range(0, _treePrototypes.Length), lightmapColor = Color.white, color = Color.white, position = new Vector3(xNorm, height, zNorm) }; trees.Add(tree); } } } } return trees; }