Unity3D程序生成:草?

时间:2017-07-28 13:28:01

标签: unity3d mesh terrain procedural-generation grass

从昨天开始,我一直在尝试为我的新游戏创建程序无限的世界一代,而且目前一切都很顺利,除了我无法弄清楚如何在我的网格中添加草。我的世界是使用程序生成的不同级别细节的网格生成的。我基于3"层",地面层,丘陵层和山脉层创建了我的地形。我的地形顶部的纹理完全由我的自定义着色器管理(目前这是非常原始的,因为没有混合)。

Current results

所以我真的没有弄清楚如何将草添加到这样一个世界。我尝试了与草GameObjects,Planes等不同的技术,但它们都没有用......如果有人可以帮助我,它可能会很棒!我可以解释一下我如何管理植被脚本。我在块加载上调用GenerateVegetation()函数,我只是使用光线投射将树随机地放置在地形顶部以获得点和法线(我用顶点的y轴检查斜率'正常)。

这是我的植被脚本(我现在刚刚完成它的时候非常基本)

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) });
 }

我真的很感激一些见解。

0 个答案:

没有答案