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 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.
[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.