Unity关于飞行效果的小思路(上)

最近在处理飞行效果的需求,类似【完美世界】里的飞行(五连跳?),起初是自己琢磨其中每一段飞行的轨迹并分解成不同数学模型,实现了直线匀变速、二阶贝塞尔曲线、抛物线轨迹效果,其代码如下:

一、直线匀变速(我就不整合向上向下了,亦或者归结为90度的斜抛物运动轨迹)

// startPos 起始位置

// curShowPoint 当前位置

// startDir 起始朝向

// 当前朝向

// dt 该段轨迹开始到当前的时间

private Vector3 getShowPosByLineUp(Vector3 startPos, Vector3 curShowPoint, float startDir, float curDir, float dt)
    {
        if (sLen == -1)
        {
            sLen = Mathf.Sqrt(height * height + distance + distance);
        }
        if (startSpeed == -99999)// 直线向上运动
        {
            startSpeed = speed;//(sLen + accSpeed * time * time / 2) / time;
        }
        curSpeed = startSpeed - accSpeed * dt;
        float d = startSpeed * dt - accSpeed * dt * dt / 2;
        float rate = d / sLen;
        float rotAngle = (float)((curDir - startDir) * Math.PI / 180);
        Vector3 vec = Quaternion.AngleAxis(rotAngle, new Vector3(curShowPoint.x, startPos.y, curShowPoint.z)) * startPos;
        rotAngle = (float)(curDir * Math.PI / 180);
        float posx = vec.x + distance * rate * Mathf.Cos(rotAngle);
        float posy = startPos.y + height * rate;
        float posz = vec.z + distance * rate * Mathf.Sin(rotAngle);
        return new Vector3(posx, posy, posz);
    }

二、二阶贝塞尔曲线

private Vector3 getShowPosByBezier(Vector3 startPos, Vector3 curShowPoint, float startDir, float curDir, float dt)
    {
        float rotAngle = (float)((curDir - startDir) * Math.PI / 180);
        Vector3 v0 = Quaternion.AngleAxis(rotAngle, new Vector3(curShowPoint.x, startPos.y, curShowPoint.z)) * startPos;
        double a = curDir * Math.PI / 180;
        float cosD = (float)Math.Cos(a);
        float sinD = (float)Math.Sin(a);
        Vector3 v1 = new Vector3(v0.x + distance * 0.3f * cosD, height + v0.y, v0.z + distance * 0.3f * sinD);
        Vector3 v2 = new Vector3(v0.x + distance * cosD, v0.y, v0.z + distance * sinD);

        float t = MapUtil.GetGroundY3(v2 * Direction2D.MAP_RATE);
        if (t != -9999999)
        {
            v2.y = t * Direction2D.MAP_RATE_MUL;
        }
        return calculateCubicBezierPoint(dt, v0, v1, v2);
    }

public Vector3 calculateCubicBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2)
    {
        float u = 1 - t;
        float tt = t * t;
        float uu = u * u;

        Vector3 p = uu * p0;
        p += 2 * u * t * p1;
        p += tt * p2;

        return p;
    }

三、抛物线

private Vector3 getShowPosByParaCurve(Vector3 startPos, Vector3 curShowPoint, float startDir, float curDir, float dt)
    {
        if (startSpeed == -99999)// 抛物线运动
        {
            startSpeed = speed;
        }
        curSpeed = startSpeed;
        float d = startSpeed * dt * Mathf.Cos(paraCurveAngle);
        float h = startSpeed * dt * Mathf.Sin(paraCurveAngle) - (accSpeed * dt * dt) / 2;
        float rotAngle = (float)(curDir * Math.PI / 180);
        float posx = startPos.x + d * Mathf.Cos(rotAngle);
        float posy = startPos.y + h;
        float posz = startPos.z + d * Mathf.Sin(rotAngle);
        return new Vector3(posx, posy, posz);
    }

上面三种是强行用用数学模型计算飞行轨迹,效率未知,但对于需求千变万化不太适应,所以一直查找其它方式实现。起初想结合itween,后来发现AnimationCurve更适合,会在后续贴出;

(非常抱歉我的数学烂,该处的旋转是存在问题的,不是居于当前玩家位置的xz和初试位置的y构成的点进行旋转的,所以最终飞行过程中转向效果不对,因为暂时有更紧急的事要处理暂时放这,希望有大神帮忙解决下)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值