Curve Deform


Curve deform is like Path deform but instead uses a 2D curve to describe the deformation along a chosen axis, so for example a section of road could be made to have a hump in it, or a rope bridge could be made to sag. The system uses the Unity curve editor and you can add as many points as you like to get the shape you need, and you can also do a little bit of scripting if you wanted to animate the shape. Below is an example script that was used to control the shape of a rope bridge object depending on where about’s an object was on the bridge.

Curve Deform Param Description

Axis

Which axis of the mesh will the curve run along, currently the curve deformation affects the Y Axis so you should only pick X or Z here, any you can use the Gizmo values to reposition the effect or rotate it.

Curve


The curve used to deform the mesh, click the curve to open the curve editor window where you can drag the control points, add and remove points or change tangents.

Max Deviation

Can be used to multiply the effect of the curve value to the deformation

Use Pos

Allow the Pos offset value to be used

Pos

An offset to add to the curve lookup position so you can easily move the effect along the mesh.

public class MegaCurveDeform : MegaModifier
{
    public MegaAxis        axis;
    public AnimationCurve  defCurve;
    public float           MaxDeviation;
    public bool            UsePos;
    public float           Pos;
}

Video showing Curve Deform

Bridge Example

In this example the bridge value is the GameObject with the modifier on, offset is a vertical adjustment for the object to get the feet to line up if needed and smooth controls how the tangents are calculated for the two end points. The curve should have the default 3 points for this to work correctly.

using UnityEngine;

[ExecuteInEditMode]
public class WalkBridge : MonoBehaviour
{
    public GameObject       bridge;
    [HideInInspector]
    public MegaCurveDeform  mod;
    public float offset = 0.0f; // Character offset
    public float smooth = 0.0f;

    void Update()
    {
        if ( bridge )
        {
            // Get the bridge modifier
            if ( mod == null )
                mod = bridge.GetComponent<MegaCurveDeform>();

            if ( mod )
            {
                int ax = (int)mod.axis;
                Vector3 pos = transform.position;

                // Get into local space
                Vector3 lpos = mod.transform.worldToLocalMatrix.MultiplyPoint(pos);

                // Are we on the bridge
                if ( lpos.x > mod.bbox.min.x && lpos.x < mod.bbox.max.x && lpos.z > mod.bbox.min.z && lpos.z < mod.bbox.max.z )
                {
                    // How far across are we
                    float alpha = (lpos[ax] - mod.bbox.min[ax]) / (mod.bbox.max[ax] - mod.bbox.min[ax]);

                    // Deform the bridge
                    SetPos(mod, alpha);
                    // Place object on deformed bridge
                    lpos.y = mod.GetPos(alpha) + (offset * 0.01f);

                    transform.position = bridge.transform.localToWorldMatrix.MultiplyPoint(lpos);
                }
                else
                    SetPos(mod, 0.0f);
            }
        }
    }

    private float easeInOutSine(float start, float end, float value)
    {
        end -= start;
        return -end / 2.0f * (Mathf.Cos(Mathf.PI * value / 1.0f) - 1.0f) + start;
    }

    // Change the keys
    public void SetPos(MegaCurveDeform mod, float alpha)
    {
        float val = 0.0f;

        if ( alpha < 0.5f )
            val = easeInOutSine(0.0f, -mod.MaxDeviation * 0.01f, alpha / 0.5f);
        else
            val = easeInOutSine(-mod.MaxDeviation * 0.01f, 0.0f, (alpha - 0.5f) / 0.5f);

        mod.SetKey(0, 0.0f, 0.0f, Mathf.Tan(0.0f), Mathf.Tan(Mathf.Atan2(val, alpha)));

        float inTangent = Mathf.Lerp(Mathf.Tan(0.0f), Mathf.Tan(Mathf.Atan2(val, alpha)), smooth);
        float outTangent = Mathf.Lerp(Mathf.Tan(Mathf.PI), Mathf.Tan(Mathf.Atan2(val, alpha - 1.0f)), smooth);

        mod.SetKey(1, Mathf.Clamp(alpha, 0.001f, 0.999f), val, inTangent, outTangent);

        mod.SetKey(2, 1.0f, 0.0f, Mathf.Tan(Mathf.Atan2(-val, 1.0f - alpha)), Mathf.Tan(Mathf.PI));
    }
}

You must be logged in to post a comment.