チュートリアル - 3D空間を使った簡単webサイト 2/5

[前回](https://qiita.com/sutobu000/items/395180c1cb4920c57c57)

#カメラを移動させる
まずはドラッグして3D空間を移動させます。

事前に用意している scripts ディレクトリ内の cameraMove.js を開きます。

ファイル内のコードはファイル作成時にデフォルトで書かれているもので、上から以下になります。

- **initialize** : 初回読み込み
- **update** : 毎フレームごと
- **swap** : scriptファイル更新時（hot reloading）
 
##マウスイベントを取得
PlayCanvasにはエンジンのRootのネームスペースがあります。
https://developer.playcanvas.com/en/api/pc.html

pc.MOUSEBUTTON_LEFTなどからイベントを取得し判別することができます。
以下のコードを追加します。 

```js
CameraMove.prototype.onMouseDown = function (event) { // クリックダウンしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) {} // 左クリックのとき
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseUp = function (event) { // クリックアップしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) {} // 左クリック
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseMove = function (event) { // マウスカーソルが動いたら
  console.log(event);
};
```

上記で追加した関数を使いたいので、initializeでイベントを取得できるようにします。

```js
this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this); // クリックが押された時
this.app.mouse.on(pc.EVENT_MOUSEUP, this.onMouseUp, this); // クリックを押している状態から離れる時
this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseMove, this); // マウスカーソルが動いている時
```

ここのon()はjQueryのon()と同じようなもので、イベント処理を行い、関数を呼び出します。

このままではこのscriptは呼び出されません。対象となるEntityに登録する必要があります。
ヒエラルキーからCameraを選択し、インスペクターのADD COMPONENTからScriptを選択。

![スクリーンショット 2019-06-19 15.37.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/0819e55e-11bf-eb64-5e65-8a4da3a111bf.png)


SCRIPTSの設定のADD SCRIPTからcameraMoveを選択します。
cameraMoveが設定されたらOKです。
ちなみに、名前の横のEditをクリックするとコードエディターを開きます。
そのさらに横のParseをクリックすると設定した scriptを再読み込みします。

![スクリーンショット 2019-06-19 15.41.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/fe3ac2a9-9eb3-d894-1fd4-171383c7974d.png)


Lauch画面をリロードしConsoleを確認するとonMouseMoveのconsole.logがマウスが動くたびに呼び出されています。

 

これをクリックしている間だけに変更し、ドラッグしたら呼び出すようにします。
initializeにクリックしているか判定するフラッグを用意します。

```js
this.f_click = false;
```

これに合わせて、onMouseDownとonMouseUpに適当なものを追加します。
追加すると以下のようなコードになると思います。

```js
var CameraMove = pc.createScript('cameraMove');

// カメラ移動などの処理

CameraMove.prototype.initialize = function() {
    this.f_click = false;

    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this); // クリックが押された時
    this.app.mouse.on(pc.EVENT_MOUSEUP, this.onMouseUp, this); // クリックを押している状態から離れる時
    this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseMove, this); // マウスカーソルが動いている時
};

CameraMove.prototype.update = function(dt) {};

CameraMove.prototype.onMouseDown = function (event) { // クリックダウンしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) { this.f_click = true; } // 左クリックのとき
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseUp = function (event) { // クリックアップしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) { this.f_click = false; } // 左クリック
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseMove = function (event) { // マウスカーソルが動いたら
  if(this.f_click){
    console.log(event);
  }
};
```

これでクリックしドラッグした時だけconsole.logが呼ばれるようになりました。
ここで呼ばれているデータからカメラも移動するようにします。

initializeで以下を設定。
カメラのEntityの情報を取得しています。ここではカメラのPositionを取得します。
https://developer.playcanvas.com/en/api/pc.Entity.html

```js
    this.cameraEntity = this.entity; // このjsを受けているEntityを取得（カメラであることを前提に）
    this.pos = this.cameraEntity.getPosition(); // カメラの座標を取得 
```

onMouseMoveの中身を以下に差し替えます。
クリックされていない場合はreturnするように変更。
eventからベクトル量を取得します。取得したベクトル量からカメラのポジションを再設定します。

```js
    if(!this.f_click) return; // クリックが押されている時
    var posDX = event.dx/500; // x座標の変化量
    var posDY = event.dy/500; // y座標の変化量
    
    var posX = this.pos.x - posDX; // ドラッグ量からカメラの座標を計算
    var posZ = this.pos.z - posDY; // ドラッグ量からカメラの座標を計算

    this.cameraEntity.setPosition(posX,this.pos.y,posZ); // カメラの座標をセット
```

これでカメラの移動ができるようになりました。

最終的にコードは以下のようになります。

```js
var CameraMove = pc.createScript('cameraMove');

// カメラ移動などの処理

CameraMove.prototype.initialize = function() {
    this.f_click = false;

    this.cameraEntity = this.entity; // このjsを受けているEntityを取得（カメラであることを前提に）
    this.pos = this.cameraEntity.getPosition(); // カメラの座標を取得 

    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this); // クリックが押された時
    this.app.mouse.on(pc.EVENT_MOUSEUP, this.onMouseUp, this); // クリックを押している状態から離れる時
    this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseMove, this); // マウスカーソルが動いている時
};

CameraMove.prototype.update = function(dt) {};

CameraMove.prototype.onMouseDown = function (event) { // クリックダウンしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) { this.f_click = true; } // 左クリックのとき
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseUp = function (event) { // クリックアップしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) { this.f_click = false; } // 左クリック
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseMove = function (event) { // マウスカーソルが動いたら
    if(!this.f_click) return; // クリックが押されている時
    var posDX = event.dx/500; // deltaX
    var posDY = event.dy/500; // deltaY
    
    var posX = this.pos.x - posDX; // ドラッグ量からカメラの座標を計算
    var posZ = this.pos.z - posDY; // ドラッグ量からカメラの座標を計算

    this.cameraEntity.setPosition(posX,this.pos.y,posZ); // カメラの座標をセット
};
```

次は3Dオブジェクトをクリックしてイベントを取得する処理です。


[次回](https://qiita.com/sutobu000/items/5c6b5e8bd8125d0ea985)