スニーク

    From Minecraft Parkour Wiki
    This page is a translated version of the page Sneaking and the translation is 76% complete.
    Other languages:

    スニークは、移動速度が減少し、ブロックの縁から落ちなくなる仕組みである。


    発動

    スニークはスニークキーを押すと即座に発動し、押している間は発動したままになる。

    スニーク中はダッシュできない(1.14以降を除く)。


    効果

    地面にいる間は、スニークしていると1マス以上の段差からは落下しなくなる。

    • ブロック縁に対してスニークしている間は速度が保持されるため、助走なし3+1などのジャンプに有用。
    • 1.11で、高さの下限値が0.6bに変更された。
    • スニーク中にブロック縁に着地すると、「shift glitch」が発生し、落下する場合がある(1.16.2で修正)。
    • 地面でのスニーク中に、予期せず落下する場合がある()。 - 1.16.2で一部修正。

    スニーク中は、はしごとツタに掴まることができる。

    • 登ることは通常通りできるが、ブロック範囲内にいる限り落下しなくなる。
    • 一般に、はしご系のジャンプはスニークすることで簡単になる。

    1.9以降は、スニークするとプレイヤーの身長が1.65mに低下する。1.14以降は更に低くなり、1.5mになる。


    速度

    ダッシュは歩きより70%遅く、基本加速度は0.03である。ただし、適用方法は歩きやダッシュとは異なる:

    • 前方にスニークしている場合、地面での加速度は0.03×0.98 = 0.0294となり、予期される通り。
    • 斜めにスニークしている場合、地面での加速度は0.0294×2 ≒ 0.0416となる。


    ソースコード

    スニークの実装方法となぜ欠陥があるのかを示す。

    /* Entity.java内、無関係なコードは削除済 */
    public void moveEntity(double dX, double dY, double dZ)
    {
        double dX_intended = dX;
        double dY_intended = dY;
        double dZ_intended = dZ;
        boolean sneakingOnGround = this.onGround && this.isSneaking();
        
        if (sneakingOnGround)
        {
            double increment = 0.05;
    
            <div lang="en" dir="ltr" class="mw-content-ltr">
    //check for furthest ground under player in the X axis (from initial position)
            while(dX != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(dX,-1,0)).isEmpty())
            {
                if (dX < increment && dX >= -increment)
                    dX = 0.0D;
                else if (dX > 0.0D)
                    dX -= increment;
                else
                    dX += increment;
    </div>
    
                <div lang="en" dir="ltr" class="mw-content-ltr">
    dX_intended = dX;
            }
                    
            //check for furthest ground under player in the Z axis (from initial position)
            while(dZ != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(0,-1,dZ)).isEmpty())
            {
                if (dZ < increment && dZ >= -increment)
                    dZ = 0.0D;
                else if (dZ > 0.0D)
                    dZ -= increment;
                else
                    dZ += increment;
    </div>
    
                <div lang="en" dir="ltr" class="mw-content-ltr">
    dZ_intended = dZ;
            }
                    
                    
            //calculate definitive dX and dZ based on the previous limits.
            while(dX != 0.0D && dZ != 0.0D && getCollidingBoundingBoxes(this.boundingBox.offset(dX,-1,dZ)).isEmpty())
            {
                if (dX < increment && dX >= -increment)
                    dX = 0.0D;
                else if (dX > 0.0D)
                    dX -= increment;
                else
                    dX += increment;
                dX_intended = dX;
    </div>
    
                        
                <div lang="en" dir="ltr" class="mw-content-ltr">
    if (dZ < increment && dZ >= -increment)
                    dZ = 0.0D;
                else if (dZ > 0.0D)
                    dZ -= increment;
                else
                    dZ += increment;
                dZ_intended = dZ;
            }
        }
    </div>
    
        <div lang="en" dir="ltr" class="mw-content-ltr">
    ... //move the player with the new values of dX and dZ (order of collisions: Y-X-Z)
    }
    
    Illustration of the code presented above. The red blocks are necessary for the player to sneak on top of the green block.