Unity 3D之实现鱼竿模拟

填坑

背景

之前在刷知乎的时候刷到了一篇问题:如何模拟一根鱼竿
高赞回答只说了通过UE4和蓝图的一种实现。于是就想着自己通过Unity实现一版。


前言

木杆的弯曲,可以通过力学里的Cantilever beams(悬臂梁) algorithm算法进行模拟。
Unity 3D之实现鱼竿模拟_第1张图片
x 2 × ( 3 l − x ) 2 l 2 \frac{x^{2}\times \left ( 3l-x \right )}{2l^{2}} 2l2x2×(3lx)
这个算法其实比较好理解,越靠近顶端权重逼近越快,越靠近起点权重变化越慢。这就很符合鱼竿的特征:顶端比较软,而手柄比较硬,整体表现比较软


实现


对于悬臂梁算法的实现还是比较简单的

x:距离起点的距离
Input(x)
{
	return pow(x,2) * (3 * l - x) / 2 * pow(l , 2);
}

在Unity中去这样方法还是比较简单的:

    public static float GetWidth(float x,float l)
    {
        return Mathf.Pow(x, 2) * (3 * l - x) / (2 * Mathf.Pow(l, 3));
    }

效果如下:
Unity 3D之实现鱼竿模拟_第2张图片
可以看到还是比较像的,这个可以模拟甩杆的效果。


More


那么只有这个模拟还是不够满意,我们希望实现更多的交互,比如收回来的时候回弹动画。这里就需要在Unity中实现一个Spring动画,如下面一样。
Unity 3D之实现鱼竿模拟_第3张图片
那么这个回弹动画该怎么实现?


回弹动画


首先,我们需要知道怎么做回弹效果。
回弹效果其实自需要对于每个顶点做一个回弹动画,让顶点去插值逼近原来的位置就行。
为什么是插值?
插值分为内插和外插,内插就是在 0 − 1 0-1 01的范围内,而外插就是在这个范围外,至于回弹出现的反弹出去的效果,可以通过外插实现。
这里给出一个springback的算法:
2 − 10 x s i n ( x − 0.1 4 ∗ 2 π f a c t i o n ) + 1 2^{-10x}sin\left ( \frac{\frac{x-0.1}{4} *2\pi }{faction} \right ) + 1 210xsin(faction4x0.12π)+1
这个算法在图形上表示为:
Unity 3D之实现鱼竿模拟_第4张图片
可以从图上看到这个函数在y轴上会有一段曲线超出1的范围。这符合我们对于回弹的理解。而且根据调节不同的影响因子,回弹的效果会不同,也就可以模拟不同材质回弹结果
在Unity中进行实现:

    public static float interpolationFaction = 0.3f;

    public static float getInterpolation(float x)
    {
        return (Mathf.Pow(2, -10 * x) * Mathf.Sin((x - 0.1f / 4f) * (2f * Mathf.PI) / interpolationFaction) + 1f);
    }

输入参数是当前回弹的进度,而输出是回弹当前进度的插值权重。


其他


在开发的时候也会遇到其他问题,这里做一个总结。
在Unity中,

Vector3D.lerp

函数没有外插值,范围会进行折叠到 [ 0 − 1 ] [0-1] [01]。因此我们需要自己实现一个Vector3D的线性插值版本:

    public static Vector3 mylerp(Vector3 or, Vector3 tar, float input)
    {
        return tar * input + or * (1.0f - input);
    }

测试通过,可以使用。

你可以通过一下链接找到测试工程:
https://github.com/ThisskyMain/UnityTestProject

你可能感兴趣的:(游戏开发,Unity-进阶)