curve on surface

Hello,
I came across this great prefab by FrictionPointStudios http://www.frictionpointstudios.com/blog/2010/5/20/updated-unity-bezier-curve-now-in-easy-to-use-prefab-form.html that draws bezier curves and displays the full handles. I’m trying to adapt it so that I can draw the curves ‘constrained’ to a surface. Frankly, I’m not quite sure where to start. If anyone could point me in the right direction, it would be greatly appreciated. Thanks!

Hi there,

What does ‘constrained to a surface’ mean? Do you mean all the points are lying on a plane? Like all of them are on the ground (x, 0, z) or on a wall or something?

While of course you could just manually make sure they are in the right places, it looks like your looking for a way to ensure they are constrained while you’re moving them around in the editor? Is that correct?

While someone better at editor programming could make something better, I reckon you could just hack around with OnDrawGizmos (which runs in the editor) to move the points for you.

So assuming that you want all the points constrained to be on a plane. You could create a plane in Unity and attach a collider to it.

Then you would need to get the Normal Vector of the plane. A plane on the ground has a normal vector of (0, 1, 0) so I assume whatever rotation is applied to the plane would also be applied to the NormalVector?!? Anywho, too early for me to check that but let’s assume you could get the normal vector of the plane after it has been rotated.

Then you could hack up some little script that would do a raycast from each point in the bezier curve, along the positive and negative direction of the Normal Vector until it hits the plane. The point that it hits would be where you’d want the point to be, so you could just move it.

Something like…

    Vector3 NormalToPlane = new Vector3(1, 4, 9);

    public bool ConstrainToPlane = false;

    void OnDrawGizmos()
    {
        if (this.ConstrainToPlane)
        {
            RaycastHit thePlanePoint;

            // Check one direction
            if (Physics.Raycast(this.transform.position, NormalToPlane, out thePlanePoint))
            {
                this.transform.position = thePlanePoint.point;
            }
            // Check the other direction
            else if (Physics.Raycast(this.transform.position, -NormalToPlane, out thePlanePoint))
            {
                this.transform.position = thePlanePoint.point;
            }
            else
            {
                // This means it's right on the plane maybe??
            }
        }
    }

I chucked the inspector accessible boolean ConstrainToPlane in there because otherwise the code would run constantly, and probably result in weirdness when you’re moving the points around. This way you would move them to roughly where you wanted, then check and uncheck the ConstrainToPlane thing in the inspector and it would ‘align’ them for you.

Note: I didn’t test any of this code, just thinking through it. Good luck :smile::smile:

Edit: Possibly the Raycast wouldn’t hit the back of the plane. Might need two planes in the same point but opposite rotation.