どうもです。タドスケです。
PlayCanvasに関して、前回の記事では基本のチュートリアルを進めました。
今回は「一人称カメラを使った操作と移動」のチュートリアルを改良して、ダッシュとジャンプ機能をつけてみました。
一人称視点での移動方法 | PlayCanvas Developer Site
このアプリケーションは、ファーストパーソンでのキャラクター移動を実装しています。
※軽量化のため、元々あった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アクションゲームが作れそうですね!
引き続き、他のチュートリアルも進めていきます。
コメント