1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using Random = UnityEngine.Random; #if UNITY_EDITOR using UnityEditor; #endif
[ExecuteInEditMode] [RequireComponent(typeof(MeshFilter))] [RequireComponent(typeof(MeshRenderer))] public class TerrainGrass : MonoBehaviour { public int num = 1000; [Range(1, 1000)] public int seed = 1; public Material material; public TerrainMesh terrainMesh; private Vector3 m_center; private float m_size; private List<Vector3> m_points; private Texture2D m_heightMap; [Range(0, 10)] public float gizmosScale = 1;
void Start() { m_center = terrainMesh.gameObject.transform.position; m_size = terrainMesh.terrainGridNum * terrainMesh.terrainGridSize; m_heightMap = terrainMesh.heightMap; GeneratePoints(); }
public void GeneratePoints() { gameObject.transform.position = m_center;
m_points = new List<Vector3>(); var indices = new int[num];
int width = m_heightMap.width; int height = m_heightMap.height; Random.InitState(seed); for (int i = 0; i < num; i++) { var x = Random.value; var y = Random.value; float h = m_heightMap.GetPixel((int) (x * width), (int) (y * height)).grayscale;
var pos = new Vector3( x * m_size - m_size / 2, h * terrainMesh.terrainHeight, y * m_size - m_size / 2);
m_points.Add(pos); indices[i] = i; }
Mesh mesh = new Mesh();
mesh.vertices = m_points.ToArray(); mesh.SetIndices(indices, MeshTopology.Points, 0);
GetComponent<MeshFilter>().mesh = mesh; GetComponent<MeshRenderer>().sharedMaterial = material; }
void OnDrawGizmos() { if (m_points == null || m_points.Count < 1) return; Gizmos.color = Color.green; foreach (var point in m_points) { Gizmos.DrawSphere(point, gizmosScale); } } }
#if UNITY_EDITOR
[CustomEditor(typeof(TerrainGrass))] public class TerrainGrassEditor : Editor { public override void OnInspectorGUI() { EditorGUI.BeginChangeCheck(); base.OnInspectorGUI(); TerrainGrass terrainGrass = target as TerrainGrass; if (!terrainGrass) return;
if (EditorGUI.EndChangeCheck()) { terrainGrass.GeneratePoints(); }
if (GUILayout.Button("Update", GUILayout.MaxWidth(100))) { terrainGrass.GeneratePoints(); } } }
#endif
|