PlayCanvasとHTMLを組み合わせる
PlayCanvasとHTMLを組み合わせる方法について紹介をします。
PlayCanvasは特性上、エディターを使用した開発でHTMLを触ろうとすると少し癖があります。JavaScriptのフレームワークと組み合わせることで解消も可能だったりもします。
PlayCanvas界隈では様々な方法が試されていると思いますがその中で自分が、メンテナンス性などのも考えて、使いやすかったものを紹介します。
今回はPlayCanvasの基本的な説明は省いています。
今回作るもの
このような3Dモデルが並んでいるページで、モデルがクリックされたらHTMLの表示を切り替えるものを作ります。
例: https://playcanv.as/p/9uV03p1Y/
モデルがクリックされたらモデルの情報をDOMを切り替えるものになります。
(モデルはサンディちゃんを使用しています。)
HTMLを組み込む
PlayCanvasのエディター上でHTML, CSSを組み込む
HTMLを組み込むためにそれぞれのスクリプトを追加します。
こちらは様々な方法があるかと思いますが、insertAdjacentHTML
を使用してHTMLを組み込みます。
1. ui.js index.html, style.cssを作成する
const Ui = pc.createScript("ui");
Ui.attributes.add("css", {
type: "asset",
assetType: "css",
title: "CSS Asset"
});
Ui.attributes.add("html", {
type: "asset",
assetType: "html",
title: "HTML Asset"
});
Ui.prototype.initialize = function() {
const body = document.getElementsByTagName("body")[0];
const head = document.getElementsByTagName("head")[0];
const style = `<style>${this.css.resource}</style>`;
body.insertAdjacentHTML("beforebegin", this.html.resource);
head.insertAdjacentHTML("afterbegin", style);
};
<div class="container">
<h2 class="title">タイトル</h2>
<h2 class="url">URL</h2>
<img class="image" />
</div>
.container{
position: absolute;
background-color: white;
z-index:1;
}
.container img{
object-fit: cover;
width:300px;
height:300px;
}
スクリプトにCSS
とHTML
を追加する
Root
のエンテティにui.js
を追加します。追加ができたら、style.css
、index.html
を設定します。
スクリプト属性
スクリプトのアトリビュート機能は、スクリプト内で使用する変数をPlayCanvasエディタ内で編集することができるようにする便利な機能です。この機能を使うことで、一度コードを書いた後にエンティティごと作られるインスタンスにそれぞれ違うパラメータを設定する調整ができるようになります。これにより、アーティスト、デザイナーやその他のプログラマーではないチームメンバーがコードを書かずに値を変更できるにプロパティを露出させることができます。
https://developer.playcanvas.com/ja/user-manual/scripting/script-attributes/
情報を保持するためのスクリプトを追加
次に、各モデルに、クリックされた時の情報を追加します。
info.jsを作成
info.js
としてスクリプトを作成します。
このスクリプトの役割は、プログラムを変更せずに変更できる値を保存しておくために存在しています。
/*jshint esversion: 6, asi: true, laxbreak: true*/
const Info = pc.createScript('info');
Info.attributes.add("title", {"type": "string", default: "example"})
Info.attributes.add("url", {"type": "string" , default: "https://example.com"})
Info.attributes.add("image", {"type": "asset"})
スクリプトを適用する
スクリプトを追加すると、それぞれtitle
、url
、image
と値を設定できるようになります。クリックされたときにはエンテティのこの値を使用して表示を切り替えるようにします。
クリックされたときに値を切り替えるスクリプトを追加
最後にクリックされたときに情報を切り替えるためのスクリプトを追加します。
こちらはCAMERA
コンポーネントを持っている持っているエンテティに追加します。
マウスが押されたときに、直接DOMの切り替えを行なっています。
/*jshint esversion: 6, asi: true, laxbreak: true*/
const PickerRaycast = pc.createScript('pickerRaycast');
// initialize code called once per entity
PickerRaycast.prototype.initialize = function() {
// マウスがクリックされたときに、onSelect関数を実行します
this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onSelect, this);
};
PickerRaycast.prototype.onSelect = function (e) {
const from = this.entity.camera.screenToWorld(e.x, e.y, this.entity.camera.nearClip);
const to = this.entity.camera.screenToWorld(e.x, e.y, this.entity.camera.farClip);
// クリックされた位置にエンティティがあれば result.entityにentityの情報が入ります
const result = this.app.systems.rigidbody.raycastFirst(from, to);
if (result) {
const entity = result.entity;
// entityにinfoというスクリプトが含まれているかを調べます。
if(entity.script && entity.script.hasOwnProperty('info')){
// title: string
// スクリプト名 infoの属性 titleを参照します
const title = entity.script.info.title
// url: string
// スクリプト名 infoの属性 url
const url = entity.script.info.url
// image: Asset
// スクリプト名 infoの属性 imageを参照します
// imageのtypeはAssetなので、getFileUrl()関数を使用してAssetのURLを参照します。
const image = entity.script.info.image
const imageUrl = image.getFileUrl()
// ui.jsで追加したHTMLの要素を取得します
const titleElement = document.getElementsByClassName("title")[0]
const urlElement = document.getElementsByClassName("url")[0]
const imgElement = document.getElementsByClassName("image")[0]
// HTMLの要素を書き換えます
titleElement.textContent = title
urlElement.textContent = url
imgElement.src = imageUrl
}
}
};
感想
すべてのモデルで決まった値を表示したい場合にはこちらの方法を使うことで表示を切り替えることができます。
ただ、複雑に切り替わる場合などには向いていないためシンプルに実装したいときに使っております。
今回のプロジェクトで質問や意見がありましたら。@mxcn3まで連絡をお願いします。
PlayCanvas開発で参考になりそうな記事の一覧です。 入門 応用- PlayCanvasのコードエディターでes6に対応する
- Gulpのプラグインを書いたらPlayCanvasでの開発がめちゃくちゃ便利になった
- PlayCanvas Editorに外部スクリプトを読み込む新機能が追加されたので開発方法を考える。- Reduxを組み込む
- React Native + PlayCanvasを使ってスマートフォンゲームを爆速で生み出す
- PlayCanvasのエディター上でHTML, CSSを組み込む方法
- 【iOS13】新しくなったWebVRの使い方
PlayCanvasのユーザー会のSlackを作りました!
少しでも興味がありましたら、ユーザー同士で解決・PlayCanvasを推進するためのSlackを作りましたので、もしよろしければご参加ください!