Publishして誰でも見れるように公開!
プロジェクトを作成してビルドまでやってくれるのもPlayCanvasのすごいところ。
ここまで作成したものをPlayCanvasの公開環境に公開してみましょう。
左のメニュー、またはシーンの左上のManage Scenesから以下のPublish画面を開きます。
PUBLISH TO PLAYCANVASを選択して、一番下のPUBLISH NOWをクリックしてビルドは完了です。
URLでPC、スマホ、他ユーザーにもログインすることなく共有することができます。
以上がチュートリアルの大枠となる説明でした。
おつかれさまでした。
以降はWebサイトとして追加したいものを説明するおまけです。
おまけ
SCENEの名前を変更する
sceneの名前もUntitledのままじゃカッコがつかないですね。
これはPlayCanvasの設定から変更ができます。
左上のPlayCanvasのロゴをクリックするとメニューが開きます。
その中のSettingsでインスペクター上にSETTINGSを開き、上のScene Nameから名前を変更できます。
headerの処理
headerのhtmlも追加しているので、同じようにglobal変数を使って同じように実装していきます。
addhtml.jsのinitializeに以下に書き換えます。
さらに、headerのナビゲーションをクリックするためgnavClickのイベントの処理も追加します。
headerのナビゲーションではどのsceneを選択したのかを、data-scene属性を作成して参照します。
Addhtml.prototype.initialize = function() { // init
globalPc.scene = 0; // どのシーンページを開いているか保管
var htmlNameArr = []; // attributesのデータの名前を配列にします
var arrIndex = Addhtml.attributes.index;
for(var i = 0; i < Object.keys(arrIndex).length; i++){ // attributesのデータを取得してfor文で回す
if(!Object.keys(arrIndex)[i].indexOf("scene")){ // 名前にhtmlが入っているデータをif文
htmlNameArr.push(Object.keys(arrIndex)[i]); // htmlデータの名前だけ配列化する
}
}
var head = document.getElementsByTagName("head")[0]; // headタグ取得
var body = document.getElementsByTagName("body")[0]; // bodyタグ取得
var wrapper = document.createElement("div"); // DOMを囲う要素を作成
wrapper.className = "wrapper"; // クラス名指定
body.appendChild(wrapper); // bodyタグの最後に要素を追加
container = document.createElement("main"); // DOMを囲う要素を作成
container.className = "container"; // クラス名指定
wrapper.appendChild(container); // bodyタグの最後に要素を追加
var style = document.createElement("style"); // cssのstyleタグ
wrapper.insertAdjacentHTML("afterbegin", this.header.resource); // attrで追加したヘッダーを追加
// ヘッダー内のgnaviを取得
var gnavLists = document.querySelector(".gnav_lists");
gnavLists.innerHTML = ""; // .gnav_lists内のhtmlを空っぽに
var gnavItem = document.createElement("div"); // gnavの各リンクのdivを作成
gnavItem.className = "gnav_item"; // gnavリンク要素のclass名を指定
var gnavItemCl = []; // gnav_itemを整理する
style.append(this.css._resources[0]);
head.appendChild(style); // headの最後にstyleを追加
for(var i = 0; i < htmlNameArr.length; i++){
container.insertAdjacentHTML("beforeend", this[htmlNameArr[i]].resource); // アセットから取得したhtmlを追加
// 今回はgnavのリンクの数とhtmlのアセットの数が同じなのでどう処理を行う。
gnavItemCl[i] = gnavItem.cloneNode(true); // gnavItemのクローンを作成
gnavItemCl[i].innerHTML = '<label for="menu"><span>' + htmlNameArr[i] + '</span></label>'; // innerHTMLを作成
gnavItemCl[i].setAttribute("data-scene",i+1); // scene1,scene2,scene3を切り替えるため数値をdata-sceneに追加
gnavLists.append(gnavItemCl[i]); // gnav_lists内に追加
gnavItemCl[i].addEventListener("click", gnavClick, false); // gnav_item各々にイベントをセット
}
};
function gnavClick(e){ // gnav_itemをクリックしたら発火
if(globalPc.scene === 0) {
globalPc.scene = this.getAttribute("data-scene"); // クリックしたgnav_itemのdata-sceneを取得
}
}
ホバーとクリックのアクションを追加
クリックでhtmlにイベントを取得させましたが、アニメーションを追加します。
ホバーすればscaleが少し大きくなり、クリックすればワイヤーフレームになるといった感じです。
このアクションではもっと色んな広がりを見せることができます。
PlayCanvasではアニメーションを作れるTweenライブラリが公開されていますのでご参照ください。
https://developer.playcanvas.com/en/tutorials/tweening/
hotspot.jsを以下にまるっと書き換えます。
var Hotspot = pc.createScript('hotspot');
// canvasのclickやhoverなどの処理を行う
Hotspot.attributes.add("cameraEntity", {type: "entity", title: "Camera Entity"}); // カメラのentityを取得
Hotspot.attributes.add("radius", {type: "number", title: "Radius"}); // entityのヒットエリアの範囲を指定
Hotspot.prototype.initialize = function() { // init
this.hitArea = new pc.BoundingSphere(this.entity.getPosition(), this.radius); // ヒットエリアを作成。BoundingSphereがentityの境界エリアを作成(Photoshopでいうバウンディングボックス的な)
this.ray = new pc.Ray(); // cameraからentityへ直進する線のデータを作成。(Rayは光線の意でstart pointからentityまでの距離を測ったりすることが可能)
this.directionToCamera = new pc.Vec3(); // Vector座標の型を取得
this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseHover, this); // マウスカーソルがホバーした時
this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this); // クリックが押された時
this.localScale = this.entity.getLocalScale().clone(); // 初期のscaleを保持
this.hoverScale = this.localScale.clone().scale(1.2); // ホバー時のentityのscaleを保持
};
Hotspot.prototype.update = function(dt) { // update
this.cameraPosition = this.cameraEntity.getPosition(); // cameraのポジション(座標)を取得
this.directionToCamera.sub2(this.cameraPosition, this.entity.getPosition()); // 2つの3次元ベクトルの値を互いに減算
this.directionToCamera.normalize(); // 3次元ベクトルを単位ベクトルに変換
if(globalPc.scene === 0){ // sceneが選択されていない場合
for (var i = 0; i < this.entity.model.meshInstances.length; i++) {
this.entity.model.meshInstances[i].renderStyle = pc.RENDERSTYLE_SOLID; // レンダラーのスタイルをソリッドに変更
}
}
if(this.entity.tags._list[0].replace(/[^0-9]/g, '') === globalPc.scene) { // gnav_itemから選択されたsceneを参照
this.entity.model._model.generateWireframe(); // モデルのワイヤーフレームを準備
for (var j = 0; j < this.entity.model.meshInstances.length; j++) { // モデルのメッシュを取得
this.entity.model.meshInstances[j].renderStyle = pc.RENDERSTYLE_WIREFRAME; // ワイヤーフレームにレンダリング
}
}
};
Hotspot.prototype.doRayCast = function (screenPosition) { // レイキャスト処理(ある地点から特定方向に直線で線を引いて、その線上で物体があるか検知する処理)
if (this.hitArea.intersectsRay(this.ray)) {
globalPc.scene = this.entity.tags._list[0].replace(/[^0-9]/g, ''); // entityで設定したタグを取得し、s1、s2...の数字以外をreplaceで削除し数字のみ代入
this.entity.model._model.generateWireframe(); // モデルのワイヤーフレームを準備
for (var i = 0; i < this.entity.model.meshInstances.length; i++) { // モデルのメッシュを取得
this.entity.model.meshInstances[i].renderStyle = pc.RENDERSTYLE_WIREFRAME; // ワイヤーフレームにレンダリング
}
}
};
Hotspot.prototype.onMouseHover = function(screenPosition) { // マウスホバー時
this.cameraEntity.camera.screenToWorld(screenPosition.x, screenPosition.y, this.cameraEntity.camera.farClip, this.ray.direction); // ポジションを2Dスクリーンから3D空間へ変換
this.ray.origin.copy(this.cameraEntity.getPosition()); // レイのオリジナルのポジションにカメラのポジションをコピー
this.ray.direction.sub(this.ray.origin).normalize(); // 3次元ベクトルを他の場所から減算し、単位ベクトルに変換
if (this.hitArea.intersectsRay(this.ray) && globalPc.scene === 0) { // sceneが選択されていなくて、ヒットエリアとレイが交差した場合
this.entity.setLocalScale(this.hoverScale); // entityのスケールを大きく
}else{
this.entity.setLocalScale(this.localScale); // entityのスケールを小さく
}
};
Hotspot.prototype.onMouseDown = function(event) { // クリックが押されている時
if (event.button == pc.MOUSEBUTTON_LEFT) { // 左クリックが押された時
this.doRayCast(event); // レイキャストを呼ぶ
}
};
さらにおまけで、マウスのクリックボタンの判定を以下のように取っていましたが、
CameraMove.prototype.onMouseDown = function (event) { // クリックダウンしたら
if (event.button === pc.MOUSEBUTTON_LEFT) {} // 左クリック
if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};
以下のようにもっと簡単に左・中・右クリックのbooleanを取ることもできます。
CameraMove.prototype.onMouseDown = function (event) { // クリックダウンしたら
if (event.buttons[0]) {} // 左クリック
if (event.buttons[1]) {} // 中クリック
if (event.buttons[2]) {} // 右クリック
};
3Dオブジェクトのモデルを変えたい!
PlayCanvasにはAssets Storeなるものがあり、ここから指定のプロジェクトのAssetsライブラリにアセットを追加することができます。
http://store.playcanvas.com/
アセットを選択し、Downloadをするとログインしているアカウントが所有しているプロジェクトの一覧が表示されますので、指定のプロジェクトを選択することでアセットが使用できます。