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;
}

 

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