Click here to Skip to main content
16,022,205 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hello,
I am trying to draw some grass using Graphics.DrawMeshInstanced() and it works, but now i want it to spread all over terrain. But here is my problem. I can not figure out how to use the Terrain.SampleHeight().
Bellow i will post the entire code so you can check for yourselfs.
If you can help with the rotation as well, that would be great.
Thank you.


What I have tried:

C#
<pre>using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class GrassInstancing : MonoBehaviour
{
    public int Instances;
    public Mesh mesh;
    public Material[] Materials;
    private List<List<Matrix4x4>> Batches = new List<List<Matrix4x4>>();
 
    public Vector3 eulerAngles;
 
    public Terrain terrain;
    public float yOffset = 0.5f;
 
    private float terrainWidth;
    private float terrainLength;
 
    private float xTerrainPos;
    private float zTerrainPos;
 
    private void RenderBatches()
    {
        foreach(var Batch in Batches)
        {
            for(int i = 0; i < mesh.subMeshCount; i++)
            {
                Graphics.DrawMeshInstanced(mesh, i, Materials[i], Batch);
            }
        }
    }
 
 
 
 
    // Update is called once per frame
    void Update()
    {
        RenderBatches();
    }
 
 
 
     // Start is called before the first frame update
    void Start()
    {
       
 
        //Get terrain size
        terrainWidth = terrain.terrainData.size.x;
        terrainLength = terrain.terrainData.size.z;
 
        //Get terrain position
        xTerrainPos = terrain.transform.position.x;
        zTerrainPos = terrain.transform.position.z;
 
FROM HERE STARTS MY PROBLEM
        //Generate random x,z,y position on the terrain
        float randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
        float randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);
        float yVal =Terrain.activeTerrain.SampleHeight(new Vector3(randX,0, randZ));
 
        //Apply Offset if needed
        yVal = yVal + yOffset;
 
        Quaternion rotation = Quaternion.Euler(eulerAngles.x - 50, eulerAngles.y, eulerAngles.z);
 
 
        int AddedMatricies = 0;
        Batches.Add(new List<Matrix4x4>());
 
        for(int i = 0; i < Instances; i++)
            {
                if(AddedMatricies < 1000)
                {
                    Batches[Batches.Count -1].Add(Matrix4x4.TRS(new Vector3(Random.Range(xTerrainPos, xTerrainPos + terrainWidth),
                        yVal,
                        Random.Range(zTerrainPos, zTerrainPos + terrainLength)), rotation,
                        new Vector3(Random.Range(1, 3),Random.Range(1, 3), Random.Range(1, 3))));
                        AddedMatricies += 1;
                }
                else
                {
                    Batches.Add(new List<Matrix4x4>());
                    AddedMatricies = 0;
                }
            }
 
        Debug.Log(yVal);
    }
}
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900