1

Since yesterday I have been trying to create a procedural infinite world generation and for my new game and for the moment everything goes pretty well, except that I can't figure out how to add grass to my mesh. My world is generated using procedurally generated meshes of different levels of details. I created my terrain based on 3 "layers", the ground layer, a hills layer and a mountains layer. The texture on top of my terrain is entirely managed by my custom shader (which is very primitive for the moment because there is no blending).

Current results

So I really an't figure out how to add grass to such a world. I tried different technique with grass GameObjects, Planes etc but they all not worked... If someone can help me it could be awesome! I can explain you how I manage my vegetation script. I call the GenerateVegetation() function on the chunk load and I just randomly place the trees on top of the terrain using a raycasting to get the point and the normal (I check the slope with the y axis of the vertex's normal).

Here is my vegetation script (very basic for the moment I just done it now)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

 public class VegetationGeneration {

     public static IEnumerator Generate(Vector2 chunk) {
         // setting up the Vegetation holder child of the global chunk (hierachy);
         Transform vegetationChunk = new GameObject ("Vegetation").transform;
         vegetationChunk.parent = GameSettings.chunks [chunk];

         // Get all the vegetation instances and loop start iterating the placement
         foreach(Vegetation vegetation in MapPreview.instance.vegetation) {
             float amount = Random.Range (vegetation.amount.x, vegetation.amount.y);
             for(int i = 0; i < amount; i++) {
                 // Splitting the generation calculations each 15 trees (Only while playtime) (Performance)
                 if (!Application.isEditor && i % 15 == 0) yield return null;
                 // Getting a random position in the chunk
                 float chunkDiameter = GameSettings.worldChunkSize / 2f;
                 Vector3 position = new Vector3 (Random.Range (-chunkDiameter, chunkDiameter), 0f, Random.Range (-chunkDiameter, chunkDiameter)) + new Vector3(chunk.x, 0f, chunk.y);
                 // Shooting a raycast down to get the hit point and hit normal
                 // Check the slope angle
                 RaycastHit hit;
                 float slope;
                 if(Physics.Raycast(new Ray(position + Vector3.up * 100f, Vector3.down), out hit, 200f, MapPreview.instance.groundLayer) && (slope = hit.normal.y) > vegetation.maxSlope) {
                     // possible to spawn the vegetation at the given point
                     // Spawning the entity with the vegetation chunk parent
                     GameObject prefab = vegetation.vegetation [Random.Range (0, vegetation.vegetation.Length)];
                     GameObject entity = GameObject.Instantiate (prefab, vegetationChunk);
                     // setting parameters
                     entity.transform.position = hit.point;
                     entity.transform.localEulerAngles += new Vector3 (0f, Random.Range (0f, 360f), 0f);
                     // Getting a random scale and converting it to a uniform vector
                     float scale = Random.Range (vegetation.scale.x, vegetation.scale.y);
                     entity.transform.localScale = Vector3.one * scale;
                     // Putting the vegetation into the ground to avoit flying trees
                     entity.transform.position -= Vector3.up * vegetation.depth.Evaluate (slope);
                     // Set to a different layre than the ground to avoid trees over other trees (Raycasting)
                     SetLayer (entity.transform);
                 }
             }
         }
     }

     // A simple Recusrive function that will loop thru every child of the root
     // TRansform and apply the right layer to it
     static void SetLayer(Transform parent) {
         parent.gameObject.layer = LayerMask.NameToLayer (MapPreview.instance.vegetationLayer);
         foreach(Transform child in parent) SetLayer (child);
     }
 }

 // Vegetation Object
 [System.Serializable]
 public class Vegetation {
     public string name;
     [Tooltip("Amount of vegetation per generated chunk (does not represent the real amount because they won't be placed if the place is not survivable)")]
     public Vector2 amount = new Vector2(50,70);
     public GameObject[] vegetation;
     public Vector2 scale;
     [Range(0f,1f)]
     public float maxSlope = 0.7f;
     public AnimationCurve depth = new AnimationCurve(new Keyframe[] { new Keyframe(0f, 0.05f), new Keyframe(1f, 0.25f) });
 }

I would really appreciate some insight.

derHugo
  • 83,094
  • 9
  • 75
  • 115
No Braves Studio
  • 151
  • 1
  • 2
  • 12
  • up up up up up up – No Braves Studio Jul 29 '17 at 14:40
  • If your questions sits here for a couple of days with no responses, consider [requesting migration](https://meta.stackexchange.com/a/10250/228147) to either [GDSE](https://gamedev.stackexchange.com/) or [CGSE](https://computergraphics.stackexchange.com/). Don't [cross post](https://meta.stackexchange.com/questions/64068/is-cross-posting-a-question-on-multiple-stack-exchange-sites-permitted-if-the-qu) or comment bump though. – Pikalek Jul 29 '17 at 15:19

0 Answers0