The Shape

I was working on a project where I needed to arrange chairs around a pillar in a hotel or condo lobby. While I was contemplating the procedural layout, I thought it would be interesting to arrange objects based on various geometric shapes. I initially began with a circle and eventually developed concentric rings around a radius to create what could potentially be stadium seating.


Blueprint Node

Determined to streamline the process when it came to working in the blueprint graph, I created blueprint function library functions for different types of potential shapes, each with the appropriate structs for parameters that correspond to those shapes. I plan to encapsulate this functionality into a component where you can simply select the specific shape via an enumerator, and the relevant settings will be displayed accordingly. I intend to revisit this concept in the near future. The idea is to enable artists to add objects or actors to the world in the form of a 2D or 3D layout. Furthermore, artists will have the capability to add objects around specific vector points, but I’ll discuss that in more detail in a separate post.

For now this is the result that we’re shooting for.


  1. What are the uses
  2. Usage


struct FCageVectorSphereParams
    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    int32 LatitudeSegments;
    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    int32 LongitudeSegments;
    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    float Radius;
    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    bool bTop;
    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    bool bBottom;
/** Create Vector Sphere */
UFUNCTION(BlueprintCallable, BlueprintPure, meta=(DisplayName = "Create Vector Sphere"), Category="CageTools|Object Placement")
static TArray CreateVectorSphere(int32 LatitudeSegments, int32 LongitudeSegments, float Radius, bool bTop, bool bBottom);


TArray UCageUtilities::CreateVectorSphere(int32 LatitudeSegments, int32 LongitudeSegments, float Radius, bool bTop, bool bBottom)
    TArray SphereTransforms;
    for (int32 lat = 0; lat <= LatitudeSegments; ++lat)
        for (int32 lon = 0; lon <= LongitudeSegments; ++lon)
            // Calculate the spherical coordinates
            float Theta = 2 * PI * float(lon) / float(LongitudeSegments);
            float Phi = PI * float(lat) / float(LatitudeSegments);
            // Convert to Cartesian coordinates
            float X = Radius * sin(Phi) * cos(Theta);
            float Y = Radius * sin(Phi) * sin(Theta);
            float Z = Radius * cos(Phi);
            FVector Vertex(X, Y, Z);
            if ((bTop && Vertex.Z >= 0.0f) || (bBottom && Vertex.Z <= 0.0f) || (!bTop && !bBottom))
                // Create a transform with the forward vector pointing outward on the Z-axis
                FTransform Transform(FRotator(0.0f, 0.0f, 0.0f), Vertex);
    return SphereTransforms;