Alternate positions on child gameobject

I have a script that generates a super simple mesh (a quad with a texture) and places it on a sphere.
The script meshgenerator is this one:

[RequireComponent(typeof(MeshFilter))]
public class LeafMeshGenerator : MonoBehaviour
{
    Mesh mesh;


    Vector3[] vertices;
    Vector2[] uv;
    int[] triangles;

    private void Start()
    {
        mesh = new Mesh();
        GetComponent<MeshFilter>().mesh = mesh;

        //Material leafMaterial = new Material(Shader.Find("Standard"));
        //leafMaterial.SetColor("_Color", new Color(0f, 0.7f, 0f)); //green main color

        CreateShape();
        UpdateMesh();
    }

    void CreateShape()
    {
        vertices = new Vector3[]
        {
            new Vector3(0,0,0),
            new Vector3(0,0,.2f),
            new Vector3(.2f,0,0),
            new Vector3(.2f,0,.2f)
        };

        uv = new Vector2[]
        {
            new Vector2(1f,0f),
            new Vector2(1f,1f),
            new Vector2(0f,0f),
            new Vector2(0f,1f)
        };

        triangles = new int[]
        {
            0,1,2,
            1,3,2
        };

    }

    void UpdateMesh()
    {
        mesh.Clear();

        mesh.vertices = vertices;
        mesh.uv = uv;
        mesh.triangles = triangles;

        mesh.RecalculateNormals();

    }
}

At a certain moment, a sphere is generated and during this generation, the mesh created with the script above is instantiated at position (see line 6):

        if (!geometry && !tree.skeletonOnly)
        {
            geometry = GameObject.Instantiate(tree.budPrefab);
            geometry.transform.position = transform.position;
            geometry.transform.parent = transform;
            leaf = GameObject.Instantiate(tree.leafPreFab, geometry.transform.position, Quaternion.Euler(new Vector3(0, 0, 0)));
            leaf.transform.position = geometry.transform.position;
            leaf.transform.parent = transform;
        }

After some iterations, I have a bunch of spheres with generated mesh attached:

I want to “alternate” the position of generated mesh along all consecutive spheres (children).
It should look like these (I’ve manually moved the generated meshes for visualization purpose):

I was thinking about something that “remembers” where the mesh is placed on previous sphere in hierarchy.

Thank you

Easiest is just a bool.

// first one could be left or right, randomly
bool onTheRight = Random.value < 0.5f;

// every time you place a leaf... flip it!
while(inside_my_leafmaking_loop)
{
   ... make the leaf
   if (onTheRight)
   {
      .. emplace it on the right
   }
   else
   {
      .. emplace it on the left
   }
   onTheRight = !onTheRight;
}
1 Like

Thanks for the answer, the fact is that the sequence of positions is not random. If a leaf is on the right, the leaf on the subsequent child must be on the left, then on the right again, and so on. Using a random value, there is a chance that two subsequent leaves are placed both on the right or on the left, right?

Nice bamboo btw… another thing you can do is randomly pick left/right every time.

Also, perhaps you could consider not only left/right but a range of angles around the base stem, say from -200 to +200 degrees. In that case just use Random.Range() to create an angle, then rotate the leaf around the +Y:

float angle = Random.Range( -200, 200);

// change the THIRD argument in your instantiate call to contain:

Quaternion.Euler(new Vector3(0, angle, 0)
1 Like

Ah that original code is only for the FIRST position; you can force it to true or false if you always want the first one reliably on one side.

The flip left/right is this code: onTheRight = !onTheRight;

1 Like

I see another “issue” here:
I have no leafmaking_loop so I don’t have a while loop
The leaf is instantiated once when something happens and “attached” to the sphere, see:

        if (!geometry && !tree.skeletonOnly)
        {
            geometry = GameObject.Instantiate(tree.budPrefab);
            geometry.transform.position = transform.position;
            geometry.transform.parent = transform;
            leaf = GameObject.Instantiate(tree.leafPreFab, geometry.transform.position, Quaternion.Euler(new Vector3(0, 0, 0)));
            leaf.transform.position = geometry.transform.position;
            leaf.transform.parent = transform;
        }

That’s why I was talking about to check where the leaf is instantiated on the “previous” sphere in hierarchy and avoid instantiate the leaf in the same position

Somewhere you have a place you can store state that lasts for the duration of building the tree.

That’s where to store the state.

Somewhere you make a leaf.

That’s where to respect the bool, and then to flip the bool.

1 Like