Crater generation script
unknown
csharp
2 years ago
3.8 kB
62
Indexable
/// <summary> /// Generates a crater at a given world position, of a diameter X meters and a depth of X meters and some dirt all around (percentage of crater's full diameter) /// </summary> /// <param name="p_worldPos"></param> /// <param name="p_holeDiameter"></param> /// <param name="p_depth"></param> void SpawnCrater(Vector3 p_worldPos, float p_holeDiameter, float p_depth, float p_dirtPercentageOnEdges) { float fullCraterSize = p_holeDiameter + (p_holeDiameter * p_dirtPercentageOnEdges); // Base hole diameter + dirt edges // Setting the dirt height on the edges of the crater float dirtHeight = p_holeDiameter > 1 ? 0.25f * p_depth : 0f; // Doing the edges of the crater only if the crater is big enough, otherwise looks pretty bad // Converting real world size (meters) in heightmap size and taking into account resolution fullCraterSize = (_heightMapResolution * fullCraterSize) / _terrainData.size.x; // Converting the real world depth asked in scaled height of the terrain, so that 1m depth is always 1m depth, regardless of the terrain's Y scale / max height p_depth /= _terrainData.size.y; dirtHeight /= _terrainData.size.y; // Converting world coordinates into terrain coordinates int xBase = (int)(((p_worldPos.x - _terrainPos.x) / _terrainData.size.x) * _heightMapResolution); int zBase = (int)(((p_worldPos.z - _terrainPos.z) / _terrainData.size.x) * _heightMapResolution); // Clamping the terrainX and terrainZ values so we don't get errors // Also moving the area to be centered on the real world point (center of our crater to be on the world point) xBase = (int)Mathf.Clamp((float)xBase - fullCraterSize / 2f, 0, _heightMapResolution); zBase = (int)Mathf.Clamp((float)zBase - fullCraterSize / 2f, 0, _heightMapResolution); // Rounding the crater's size to the nearest integer because the terrain array only takes integers int roundedCraterSize = (int)Mathf.Ceil(fullCraterSize); float[,] heights = _terrainData.GetHeights(xBase, zBase, roundedCraterSize, roundedCraterSize); // Getting the heights values we want to modify float radius = fullCraterSize / 2f; // Radius is half of the crater's diameter, useful to get some distance stuff // Cache float tempHeight; float distanceToCenter; float percDistanceToCenter; for (int x = 0; x < roundedCraterSize; x++) for (int z = 0; z < roundedCraterSize; z++) { distanceToCenter = Vector2.Distance(new Vector2(x, z), new Vector2(radius, radius)); if (distanceToCenter <= radius) { percDistanceToCenter = distanceToCenter / radius; // How far from the center this terrain node is // Dirt edge if (percDistanceToCenter >= 1f - p_dirtPercentageOnEdges) tempHeight = heights[x, z] + (p_depth * _craterDirtShape.Evaluate(1f - percDistanceToCenter)); // Smoothing // Crater's hole else tempHeight = heights[x, z] - (p_depth * _craterDepthShape.Evaluate(percDistanceToCenter)); // Smoothing heights[x, z] = Mathf.Clamp(tempHeight, 0, 1); // Setting the new height } } // Using SetHeightsDelayLOD doesn't help at all, doesn't change a thing //_terrainData.SetHeightsDelayLOD(xBase, zBase, heights); //_terrainData.SyncHeightmap(); _terrainData.SetHeights(xBase, zBase, heights); }
Editor is loading...