# How to arrange objects along a bezier curve

I’m trying to create a Slay The Spire style targeting arrow for my card game. After some research, it appears that the cubic bezier curve formula is used to achieve the curve on the nodes of the arrow. I’ve found some equations for this, but my math skills are lacking and I have no idea how to actually implement these.

I’ve written a script that creates and positions arrow nodes between an anchor point and the current mouse position in a straight line; but I could use some help figuring out the algorithm for positioning the points along a bezier curve:

``````public class ArrowHandler : MonoBehaviour
{
[SerializeField] private GameObject ArrowNodePrefab;
private RectTransform Rect;
private RectTransform Anchor;
private List<RectTransform> Nodes = new List<RectTransform>();
private float ScaleFactor;
private int NumNodes = 5;
private readonly float ScaleMultiplier = 0.03f;

private void Awake()
{
Rect = GetComponent<RectTransform>();

Anchor = Instantiate(ArrowNodePrefab, transform).GetComponent<RectTransform>();

for (int i = 0; i < NumNodes; i++)
{
}
}

private void Update()
{
// Set anchor point to origin:
Anchor.position = new Vector2(Rect.position.x, Rect.position.y);

// Set arrowhead to mouse position:
position.z += (gameObject.transform.position - position).z;

int i = 0;
foreach (RectTransform node in Nodes)
{
// Lerp nodes so that they are evenly spaced between anchor and arrowhead:
node.position = Vector2.Lerp(Anchor.position, Arrowhead.position, (float)(i + 1) / (Nodes.Count + 1));

// Math magic to position nodes along a cubic bezier curve goes here...

// Set node rotation based on arrowhead (mouse) position:
node.rotation = Quaternion.Euler(new Vector3(0, 0, Vector2.SignedAngle(Vector2.up, node.position - Arrowhead.position)));

// Scale based on number of nodes:
float scale = ScaleFactor * (1f - ScaleMultiplier * (Nodes.Count - 1 - i));
node.localScale = new Vector3(scale, scale, 1);
i++;
}

}
}
``````

Splines are a pretty deep topic, but Catlike Coding has a good tutorial on them: Curves and Splines, a Unity C# Tutorial

There are algorithms in the link for finding the point and direction along a bezier spline.

To evenly distribute along a curve you need to find a point via distance, which requires iterating a long a curve bit by bit, measuring the distance between each point, until you’ve hit said distance.

Unity has a package for splines that may be of use: About Splines | Splines | 2.4.0

4 Likes

If you want to improve your understanding on Bezier curves, Sebastian Lague also made a short video series about implementing those. I always find his explanations and visualizations pretty helpful and, if i remember correctly, i even used this as an entry point when i needed to implement flexible paths for a study in VR back at uni.

There should be plenty of implementations on the asset store if you just need a working bezier curve asset.

Thanks, that tutorial really helped to demystify all of this. My issue was that I was trying to generalize the cubic bezier formula so that it would work with any number of points - not realizing that the formula only works with exactly four control points.

The solution was to:

• Use the cubic bezier formula `B(t) = (1-t)^3 * P0 + 3 * (1-t)^2 * t * P1 + 3 * (1-t) * t^2 * P2 + t^3 * p3` to generate four control points.
• Use those control points to create a spline.
• Position the nodes along the spline; with their positions being a function of the number of nodes.

I ended up using the free asset Bezier Solution to create the spline and get points along it. So instead of lerping, I use `Spline.GetPoint(float)(n + 1) / (Nodes.Count + 1)` to get the interpolated points along the spline.