0
\$\begingroup\$

I am stuck on a problem that might be quite simple yet it's getting on my nerves. I want to spawn crops on different plane shapes like in the attached screenshot. enter image description here

So far my progress is that I am able to spawn crops with random distance with a certain number of rows and columns.

[ContextMenu("Generate Field")]
public void GenerateField()
    {
        GameObject wheatField = new GameObject();
        wheatField.transform.position = transform.position;
        int counter = 0;
        for(int i = 0; i < rows; i++)
        {
            for (int j = 0; j < column; j++)
            {
                xDelta = Random.Range(0.4f, 0.5f);
                yDelta = Random.Range(0.4f, 0.6f);
                float yPos = Random.Range(-0.25f, 0.25f);
                GameObject tempWheat = Instantiate(wheatPrefab, new Vector3(xDelta * i, 0, yDelta * j), Quaternion.identity
                    ,wheatField.transform);
                counter++;
            }
        }
        Debug.Log("TOTAL CROPS PLACED = " + counter);
    }

I want to do this in editor time, not runtime.

Below is the sample mesh I have where Orange, White, and Green are separate meshes. enter image description here

\$\endgroup\$
3
  • \$\begingroup\$ Do you have different meshes with vertices arranged in these shapes? Or are you using a flat square with a texture to cut out a shape inside it? \$\endgroup\$
    – DMGregory
    Nov 4, 2021 at 13:52
  • \$\begingroup\$ @DMGregory I actually have meshes with vertices of these shapes. Not just a texture on a simple plane. \$\endgroup\$ Nov 4, 2021 at 13:54
  • \$\begingroup\$ @DMGregory Updated question with a screenshot of sample mesh. \$\endgroup\$ Nov 4, 2021 at 13:59

1 Answer 1

1
\$\begingroup\$

You can use rejection sampling for this.

Iterate over the area covered by the mesh's bounding box, placing your rows of crops.

Each time you try to place a plant, using code similar to what you have now, first check to see whether it's on top of the mesh. You could do this by...

  • Adding a MeshCollider, and calling ClosestPoint to snap the randomized crop position to a point on the mesh shape. If the snapped point is farther from your randomly chosen point than a threshold you set, consider this "outside" the mesh and skip to the next row/column cell.

  • Iterating over the triangles of the mesh, and checking whether your (x,z) point is inside any of those triangles, using conventional point-in-triangle tests. If the point is not on any triangles, skip to the next row/column cell.

    You can accelerate this check with a spatial partition if needed, but for low-poly shapes like you've shown in your example that optmization might not be necessary.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .