Unity3D中Vector3.SmoothDamp原理,适用于CocosCreate、LayaBox等引擎

 写在最前:本文已将Unity3D中的Vector3.SmoothDamp翻译为CocosCreate(TS语言)版本,并将三维向量更改为二维,三维运算方式相同。

private _currentVelocity : cc.Vec2 = new cc.Vec2(0, 0);
private doSmoothDamp()
{
    let nowTime = new Date().getTime(); // 保存当前时间
    let nowX = this._data._chacheX.length > 0 ? this._data._chacheX.shift() : 
    this._data.PosX; // 保存当前位置X轴
    let nowY = this._data._chacheY.length > 0 ? this._data._chacheY.shift() : 
    this._data.PosY; // 保存当前位置Y轴
    // 调用缓动函数,修改node位置
    this.node.position = this.SmoothDamp( this.node.position, new cc.Vec2(nowX, nowY), 
          this._currentVelocity, 0.34, 14.4 * 20, 
            (nowTime - this._lastUpadtePosTime) / 1000);
    this._lastUpadtePosTime = nowTime; // 保存上一次时间,用于计算时间间隔
}

// current: 当前的位置
// target: 我们试图接近的位置
// currentVelocity: 当前速度,这个值在每次调用这个函数在函数内被修改
// smoothTime: 到达目标的大约时间,较小的值将快速到达目标,假设客户端帧为每秒60帧,
//               服务器帧为每 秒20帧,smoothTime = 20/60;
// maxSpeed: 选择允许你限制的最大速度,假设帧率同smoothTime,
//             maxSpeed = 20 * 14.4(角色每帧行走的像素)
// deltaTime: 自上次调用这个函数的时间。默认为 Time.deltaTime(Unity内置函数,这里使用 
//             客户端当前时间计算得出)
private SmoothDamp(current: cc.Vec2, target: cc.Vec2, currentVelocity: cc.Vec2,                         
                     smoothTime: number, maxSpeed: number, deltaTime: number)
{
    smoothTime = Math.max(0.0001, smoothTime);
    let finalVelocity = currentVelocity;
    let num1: number = 2 / smoothTime;
    let num2: number = num1 * deltaTime;
    let num3: number =  (1.0 / (1.0 + num2 + 0.479999989271164 * num2 * num2 
                            + 0.234999999403954 * num2 * num2 * num2));

    let vector: cc.Vec2 = current.sub(target);
    let vector2_1: cc.Vec2 = new cc.Vec2(target.x, target.y);
    let maxLength = maxSpeed * smoothTime;
    let vector2_2: cc.Vec2  = this.ClampMagnitude(vector, maxLength);
    target = current.sub(vector2_2);
    let vector2_3: cc.Vec2 = (currentVelocity.add(vector2_2.mul(num1))).mul(deltaTime);
    currentVelocity = (currentVelocity.sub(vector2_3.mul(num1))).mul(num3);
    let vector2_4: cc.Vec2 = target.add(vector2_2.add(vector2_3).mul(num3));

    let dot = vector2_1.sub(current).dot(vector2_4.sub(vector2_1));
    if ( dot > 0.0)
    {
        vector2_4 = vector2_1;
        currentVelocity = vector2_4.sub(vector2_1).mul(1 / deltaTime);
    }

    finalVelocity.x = currentVelocity.x;
    finalVelocity.y = currentVelocity.y;
    return vector2_4;
}

private ClampMagnitude(vec2 : cc.Vec2, maxLength : number) : cc.Vec2
{
    let v2 = vec2.normalize();
    let nowLen = vec2.mag();
    nowLen =  nowLen > maxLength ? maxLength : nowLen;
    v2.x = v2.x * nowLen;
    v2.y = v2.y * nowLen;
    return v2;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章