カメラを移動させよう
一方向だけから見ても面白みがないですので、
カメラを移動させていろんな方向から見れるようにしてみましょう。
カメラを移動させるための準備
カメラを移動させた先の光景を一つのコンテンツとして作っていきます。
そのために、Entityの親子関係を作成していきます。
Rootを選択してからAdd EntityでEntityを追加します。
新しく作ったEntityは親になります。任意で構いませんが名前を「Scenes」という名前に変更しておきます。
先ほとど同じ要領で、作成した親のEntityを選択してAdd EntityでEntityを追加します。
このEntityは子になります。任意で名前を「scene1」と変更しておきます。
子の中には新しくCameraと他追加した3Dモデルなどを追加して、scene1を作成します。
CameraのPositionとRotationは以下のように設定しています。
Position: x: 0 , y: 2 , z: 25
Rotation: x: -10 , y: 0 , z: 0
これに合わせて元からあるCameraのPositionとRotationにも同じ設定をしておきましょう。
作成した子のEntityであるscene1を複製します。
複製は画像のDuplicate Entityからできますし、 [ctrl] + D でも複製ができます。(Macの場合、[command] + D)
複製した子Entityのscene1は名前を変更して区別しておきます。
区別した子Entityの配置を変更しておきたいので、子EntityのRotationを90度ずつ変更しておきます。
カメラを移動させるスクリプトを作る
これでカメラの移動させるEntityの準備ができました。
次はカメラを移動させるためのスクリプトを作っていきます。
AssetにScriptを作成します。
あらかじめScriptsのディレクトリを選択した状態で作成すると良いです。
スクリプトの名前は「cameraMove.js」にしておきます。
cameraMove.js をEditorで開いて以下に書き換えます
var CameraMove = pc.createScript('cameraMove');
// 属性設定
CameraMove.attributes.add("cameraEntity", { type: "entity" }); // メインカメラのEntity
CameraMove.attributes.add("targetEntityParent", { type: "entity" }); // Scenesの親Entity
CameraMove.prototype.initialize = function() {
var self = this;
self.slide = 0; // 今いくつ目のSceneを見ているか参照する数値
self.slideNum = self.targetEntityParent.children.length; // 子Entityの数
self.app.on("cameraMove:tween", function(num){ // イベント作成
self.slide += num;
if(self.slide >= self.slideNum) { // 子Entityの総数以上なら0に戻る
self.slide = 0;
}else if(self.slide < 0) { // 0以下なら子Entityの総数にする
self.slide = self.slideNum - 1;
}
// ↓子Entityの中のCameraという名前のEntityを参照して引数で渡す
self.tweenTarget(self.targetEntityParent.children[self.slide].findOne("name","Camera"));
}, this);
};
CameraMove.prototype.tweenTarget = function(target) { // カメラの移動する処理
var self = this;
var targetPos = target.getPosition(); // 子EntityのCameraのPosition
var targetRot = target.getEulerAngles(); // 子EntityのCameraのRotation
var t_camera = self.cameraEntity; // メインカメラEntity
// ↓メインカメラのPositionとRotationを子EntityのCameraの値にTweenさせる
t_camera.tween(t_camera.getLocalEulerAngles()).rotate(targetRot, 1.0, pc.SineOut).start();
t_camera.tween(t_camera.getLocalPosition()).to(targetPos, 1.0, pc.SineOut).start();
};
カメラの移動は子Entityのsceneを 1 → 2 → 3 → 4...と移動することを想定する。
cameraMoveではカメラが移動するための処理を書いている。
ここで使用している .tween はあらかじめAssetsに入れていた tween.js というPlayCanvasのTweenライブラリを用いている。
詳細はこちら↓
PlayCanvas Tweenライブラリ
EntityのRootを選択して、ADD COMPONENTからscriptで作成したcameraMove.jsを登録します。
ADD SCRIPTでcameraMoveを設定できたらParseして、cameraEntityとtargetEntityParentを設定します。
カメラを移動させるためのマウスイベントを作る
カメラを移動させるスクリプトを作っただけなので、まだカメラは動きません。
このカメラを移動させるスクリプトを発火させるために、イベントを作成していきます。
ここではマウスやタッチでスワイプしたらカメラが移動する、というイベント処理を書いていきます。
Assetsに「swipeChanger.js」というスクリプトを作成します。
以下のコードに書き換えます。
var SwipeChanger = pc.createScript('swipeChanger');
SwipeChanger.attributes.add("mainCamera",{type:"entity", title:"メインカメラ"}); // メインカメラEntity
SwipeChanger.prototype.initialize = function() {
this.clickFlag = false; // クリックしているかフラッグ
this.moveFlag = false; // 今動いているかフラッグ
this.clickPos = new pc.Vec2(); // クリックしているPosition
this.moveX = 0; // スワイプしたX軸の値
this.moveWheel = 0; // マウスのホイールの値
if(!this.app.touch) { // タッチイベントのif文(スマホなど)
// ↓ マウスクリックがDown・UP・Moveなどの時のイベント発火
this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onDeviceDown, this);
this.app.mouse.on(pc.EVENT_MOUSEUP, this.onDeviceUp, this);
this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onDeviceMove, this);
this.app.mouse.on(pc.EVENT_MOUSEWHEEL, this.onDeviceWheel, this);
} else { // タッチイベント(スマホなどの時)
// ↓ タッチ操作を始めた・終えた・動いた時のイベント発火
this.app.touch.on(pc.EVENT_TOUCHSTART, this.onDeviceDown, this);
this.app.touch.on(pc.EVENT_TOUCHEND, this.onDeviceUp, this);
this.app.touch.on(pc.EVENT_TOUCHMOVE, this.onDeviceMove, this);
}
var self = this;
this.app.on("swipeChange:true", function(){ // TweenのflagをTrueにするイベント作成
self.moveFlag = true;
});
this.app.on("swipeChange:false", function(){ // Tweenflagfalseにするイベント作成
self.moveFlag = false;
});
};
SwipeChanger.prototype.onDeviceDown = function(ev) {
this.clickFlag = true;
// ↓ クリックしたPositionを格納
if(ev.button === pc.MOUSEBUTTON_LEFT) { // マウスクリックが左ボタンの場合
this.clickPos.x = ev.x;
this.clickPos.y = ev.y;
}
if(this.app.touch && ev.touches.length === 1 ){ // タッチ操作が一つの場合(指一本)
this.clickPos.x = ev.touches[0].x;
this.clickPos.y = ev.touches[0].y;
}
// スワイプする方向をリセット
this.swipemove = "";
};
SwipeChanger.prototype.onDeviceUp = function(ev) {
this.clickFlag = false;
if(this.swipemove === "prev") { // スワイプ方向が戻るなら(左)
// ↓ cameraMove.jsで作成したイベントを使用。1つ次のsceneに移動
this.app.fire("cameraMove:tween", 1);
}else if(this.swipemove === "next"){ // スワイプ方向が進むなら(右
// ↓ cameraMove.jsで作成したイベントを使用。1つ前のsceneに移動)
this.app.fire("cameraMove:tween", -1);
}
};
SwipeChanger.prototype.onDeviceMove = function(ev) {
if(this.clickFlag && !this.moveFlag) { // クリックしながらでかつTweenしていない場合
if(this.app.touch){ // タッチ操作の場合
if(ev.touches.length === 1){ // タッチ操作が一つの場合
this.moveX = ev.touches[0].x; // 移動したx軸分
}
} else {
this.moveX = ev.x; // 移動したx軸分
}
if(this.moveX === 0){ // 移動してなければ返す
return;
} else if(this.clickPos.x + 200 < this.moveX) { // 200以上でx軸が移動していたら
self.moveFlag = true; // Tween発火しますのtrue
this.swipemove = "next"; // スワイプ方向を指示
} else if(this.clickPos.x - 200 > this.moveX) { // -200以下でx軸が移動していたら
self.moveFlag = true; // Tween発火しますのtrue
this.swipemove = "prev"; // スワイプ方向を指示
}
}
};
SwipeChanger.prototype.onDeviceWheel = function(ev) {
this.moveWheel += ev.wheel; // マウスホイールの値を取得
if(!this.moveFlag) { // Tweenしていない場合
if(this.moveWheel > 10) { // マウスホイールの値が10以上の場合
this.moveFlag = true; // Tween発火しますのtrue
this.moveWheel = 0; // マウスホイールの値をリセット
this.app.fire("cameraMove:tween", -1); // 一つ前のsceneにTween
}else if(this.moveWheel < -10){ // マウスホイールの値が-10以下の場合
this.moveFlag = true; // Tween発火しますのtrue
this.moveWheel = 0; // マウスホイールの値をリセット
this.app.fire("cameraMove:tween", 1); // 一つ次のsceneにTween
}
}
};
スクリプトが作成できたら、cameraMove.jsと同様にRoot EntityにAdd Scriptします。
Add ScriptしたらParseしてAttributeのメインカメラにCameraを設定します。
このScriptで追加したイベントを cameraMove.js に以下を書き換えます。
CameraMove.prototype.tweenTarget = function(target) { // カメラの移動する処理
var self = this;
var targetPos = target.getPosition(); // 子EntityのCameraのPosition
var targetRot = target.getEulerAngles(); // 子EntityのCameraのRotation
var t_camera = self.cameraEntity; // メインカメラEntity
// ↓メインカメラのPositionとRotationを子EntityのCameraの値にTweenさせる
t_camera.tween(t_camera.getLocalEulerAngles()).rotate(targetRot, 1.0, pc.SineOut).start();
t_camera.tween(t_camera.getLocalPosition()).to(targetPos, 1.0, pc.SineOut).on("complete", function(){
self.app.fire("swipeChange:false"); // swipeChange.jsのイベントをTween完了後に呼び出します
}).start();
};
この状態でLaunchして確認してみますが、カメラは動いてくれません。
なぜかというと、Launchで見ているカメラはscene4のカメラになっているからです。
そこで、カメラの優先順位をつけていきます。
メインカメラのEntityを選択し、Priorityの数値を大きくします。
ここでは10に値を変更しています。
変更後、Launchを確認しマウスやタッチでのイベントを確認してみます。
スワイプするとカメラがscene1,2,3...と設定したカメラの位置に移動しているのが確認できます。
これでおおよそのコンテンツは完成です。
あとは3Dモデルをクリックしてもカメラが移動してくれるようにしてみましょう。
コメント
0件のコメント
サインインしてコメントを残してください。