游戏爆金币效果

基本思路

在某一个位置点生成一个金币模型,模型按照贝塞尔曲线移动到目标位置,移动过程中使用缓动动画EASE。实现一次爆多个金币的效果,一次生成N个金币,每个金币执行一次上面说的移动动画。

实现Code

贝塞尔曲线函数

    /// <summary>
    /// 根据T值,计算贝塞尔曲线上面相对应的点
    /// </summary>
    /// <param name="t"></param>T值(0 - 1)
    /// <param name="p0"></param>起始点
    /// <param name="p1"></param>控制点
    /// <param name="p2"></param>目标点
    /// <returns></returns>根据T值计算出来的贝赛尔曲线点
    public static  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;
    }

单个金币的移动动画,使用DoTween的动画函数DOVirtual.Float,从0到1,去采样点到贝塞尔曲线中取值。模型到达终点时,做出标记,模型的反弹动画中,限制模型的水平位移,这个更有弹跳的感觉。

public void PlayerBezierMove(Vector3 startPos, Vector3 targetPos)
    {
        StartCoroutine(IEPlayerBezierMove(startPos, targetPos));
    }
    private IEnumerator IEPlayerBezierMove(Vector3 startPos, Vector3 targetPos)
    {

        this.boxCollider.enabled = false;

        Vector3 direction = targetPos - startPos;
        Vector3 ctrlPos = startPos + direction.normalized * 3f;
        ctrlPos.y += 25f;

        bool isToTarget = false;
        bezierTween = DOVirtual.Float(0f, 1f, coinTime, (val) =>
        {
            Vector3 curPos = BezierUtils.CalculateCubicBezierPoint(val, startPos, ctrlPos, targetPos);

            if ((curPos - targetPos).sqrMagnitude < 0.1f)
            {
                isToTarget = true;
            }
            if (isToTarget)
            {
                Vector3 pos = targetPos;
                pos.y = curPos.y;
                selfTransform.position = pos;
            }
            else
            {
                selfTransform.position = curPos;
            }

        }).SetEase(Ease.OutBounce);

        yield return bezierTween.WaitForCompletion();
        this.boxCollider.enabled = true;

    }

一次爆多个金币的效果,一次生成N个金币,计算每个金币的目标角度,位置,然后执行动画函数。

Vector3 moveDirection = CharacterMgr.Instance.transform.forward.normalized;
for (int i = 0; i < count; ++i)
{
    Transform coinTransform = pool.Spawn("Coin");
    coinTransform.gameObject.SetActive(true);
    Coin coin = coinTransform.GetComponent<Coin>();
    coin.SetData(coinValArr[i]);

    //计算移动方向   
    float angle = 72f * i;
    Quaternion rotate = Quaternion.AngleAxis(angle,Vector3.up);
    Vector3 dir = rotate * moveDirection;

   //计算目标位置
    float distance = 8f;
    Vector3 targetPos = pos + distance * dir;
    targetPos.y = 1.5f;

    //coinTransform.position = targetPos;
    coinTransform.position = pos;
    coin.PlayerBezierMove(pos, targetPos); //开始动画
    coinList.Add(coin);
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注