1

从昨天开始,我一直在尝试为我的新游戏创建一个程序无限的世界生成,目前一切进展顺利,除了我不知道如何将草添加到我的网格中。我的世界是使用程序生成的不同细节级别的网格生成的。我创建了基于 3 个“层”的地形,即地面层、山丘层和山脉层。我的地形顶部的纹理完全由我的自定义着色器管理(目前非常原始,因为没有混合)。

当前结果

所以我真的不知道如何在这样的世界中添加草。我用草游戏对象、飞机等尝试了不同的技术,但它们都不起作用……如果有人可以帮助我,那就太棒了!我可以向您解释我如何管理我的植被脚本。我在块加载上调用该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) });
 }

我真的很感激一些见解。

4

0 回答 0