【PlayCanvas】FPS風マップ移動システム

ゲーム

どうもです。タドスケです。

PlayCanvasに関して、前回の記事では基本のチュートリアルを進めました。

今回は「一人称カメラを使った操作と移動」のチュートリアルを改良して、ダッシュとジャンプ機能をつけてみました。

一人称カメラを使った操作と移動 | Learn PlayCanvas

※軽量化のため、元々あったUIや背景テクスチャなどは削っています。




完成品

まずは完成品から。

操作方法

  • WASD:プレイヤーの移動
  • Shift:ダッシュ
  • Space:ジャンプ
  • マウス:カメラの向き

コード

元々あったコードに手を加えて、以下のようにしています。
(コメントも補足しました)

var FirstPersonMovement = pc.createScript('firstPersonMovement');

//---------------------------------------------------
// エディタ設定項目の登録
//---------------------------------------------------
FirstPersonMovement.attributes.add('camera', {
    type: 'entity',
    description: 'カメラ'
});

FirstPersonMovement.attributes.add('power', {
    type: 'number',
    default: 2500,
    description: 'プレイヤーの移動速'
});

FirstPersonMovement.attributes.add('lookSpeed', {
    type: 'number',
    default: 0.25,
    description: 'カメラの回転速'
});

FirstPersonMovement.attributes.add('jumpPower', {
    type: 'number',
    default: 1.0,
    description: 'プレイヤーのジャンプ力'
});

//---------------------------------------------------
// 初期化時に呼ばれる
//---------------------------------------------------
FirstPersonMovement.prototype.initialize = function() {
    this.force = new pc.Vec3();   // プレイヤーに加える力
    this.eulers = new pc.Vec3();  // カメラの方向
    this.isGround = true;         // 接地しているか
    
    var app = this.app;
    
    // マウスイベントの登録
    app.mouse.on("mousemove", this._onMouseMove, this);

    // 地面との衝突イベントの登録
    this.entity.collision.on('collisionstart', this.onCollisionStart, this);
    
    // マウスカーソルを非表示にする(Escで表示)
    app.mouse.on("mousedown", function () {
        app.mouse.enablePointerLock();
    }, this);            

};

//---------------------------------------------------
// 毎フレーム呼ばれる
//---------------------------------------------------
FirstPersonMovement.prototype.update = function(dt) {
    var force = this.force;
    var app = this.app;

    // カメラの向いている方向
    var forward = this.camera.forward;
    var right = this.camera.right;

    // プレイヤー移動量
    var x = 0;
    var z = 0;
    var y = 0;

    // WASDでプレイヤーを移動させる
    if (app.keyboard.isPressed(pc.KEY_A)) {
        x -= right.x;
        z -= right.z;
    }

    if (app.keyboard.isPressed(pc.KEY_D)) {
        x += right.x;
        z += right.z;
    }

    if (app.keyboard.isPressed(pc.KEY_W)) {
        x += forward.x;
        z += forward.z;
    }

    if (app.keyboard.isPressed(pc.KEY_S)) {
        x -= forward.x;
        z -= forward.z;
    }

    // Spaceでジャンプ
    if(app.keyboard.wasPressed(pc.KEY_SPACE) && this.isGround){
        y = 1;
        this.isGround = false;
    }
    
    // プレイヤーを移動させるための力を加える    
    if (x !== 0 || z !== 0 || y !== 0) {
        // Shiftで高速移動
        var movePw = this.power;
        if(app.keyboard.isPressed(pc.KEY_SHIFT)){
            movePw *= 2;
        }
        
        force.set(x * movePw, y * this.jumpPower, z * movePw);
        this.entity.rigidbody.applyForce(force);
    }
    
    // マウス移動量に応じてカメラの角度を変更
    this.camera.setLocalEulerAngles(this.eulers.y, this.eulers.x, 0);
};


//---------------------------------------------------
// マウスカーソルが動いた
//---------------------------------------------------
FirstPersonMovement.prototype._onMouseMove = function (e) {
    // カーソルが消えている時だけカメラを動かす
    if (pc.Mouse.isPointerLocked() || e.buttons[0]) {
        this.eulers.x -= this.lookSpeed * e.dx;
        this.eulers.y -= this.lookSpeed * e.dy;
    }            
};

//---------------------------------------------------
// 地面と衝突した
//---------------------------------------------------
FirstPersonMovement.prototype.onCollisionStart = function (e) {
    console.log(e.other.name);
    if(e.other.name === "Ground"){
        // 接地状態にする
        this.isGround = true;
    }
};

ポイントは、Y方向の力を加えるようにしていることと、地面との接地判定を行うためにonCollisionStartイベントを使うようにしていることです。

まとめ

ブロックとかエネミーとか加えたら、ちょっとした3Dアクションゲームが作れそうですね!

引き続き、他のチュートリアルも進めていきます。

コメント

タイトルとURLをコピーしました