前回はPlayCanvasにDOMを追加するまでを行います。
今回はVue.jsを使ってモデルの切り替わりなどを実装してきます。
Vue.jsで3Dモデルを切り替える
現在は3Dモデルが一つだけしか確認することができないので、複数の3Dモデルを追加します。
ヒエラルキーからEntityを追加していきます。
ヒエラルキー上部の[+]ボタンか右クリックからAdd Entity → Entityを選択します。
「New Entity」という名前で追加されたと思います。
Entitiesなど任意の名前に変更などして差別化します。
Entitiesの中にModelを追加します。
ヒエラルキーのModelをDrag&DropでEntitiesの中に追加します。
3Dモデルを複数使用したいため、先ほどのModelを複製、またはPrimitiveなBoxなどを追加します。
複製はEntityを選択して、ヒエラルキー上部のDuplicate Entityをクリック。
Primitiveを追加するにはAdd EntityからPrimitiveを選択します。
上記の操作を行うと以下のようになります。
追加したモデルが重なり合っていますので、追加したEntities内のEntityのインペクターからEnabledのチェックを外し非表示にしておきます。
3Dモデルを追加できたら、次はVue.jsを使ってそれらを操作していきます。
Vue.jsを使うために、PlayCanvasにVue.jsのCDNを使います。
EXTERNAL SCRIPTSという項目がありますのでこちらから登録します。
CDN : https://cdn.jsdelivr.net/npm/vue
Vue.jsを書いていく前に、Vue.jsがわからない人のために簡単に説明をします。
Vue.jsはプログレッシブフレームワークと言われるライブラリとフレームワークの中間のもので、フレームワークとは異なり適所に少しずつVueを適用することができます。
詳しく知りたい方はVue.jsの公式ページから参照いただけたらと思います。
https://jp.vuejs.org/
Vueを使って切り替えるために、index.jsをいかに書き換えます。
[index.js]
varIndex=pc.createScript('index');Index.attributes.add("baseHtml",{type:"asset",assetType:"html"});// 登録したhtmlを取得Index.attributes.add("target",{type:"entity"});// 参照するEntityを登録Index.prototype.initialize=function(){varself=this;// this書き換えvarcanvas=document.getElementsByTagName("canvas")[0];// canvasを取得canvas.classList.add("pcCanvas");// canvasにclass名を指定varwrapper=document.createElement("div");// div作成wrapper.classList.add("wrapper");// 作成したdivにwrapperというclass名を指定wrapper.innerHTML=self.baseHtml._resources[0];// 事前に登録していたhtmlをwrapperに流し込みdocument.body.appendChild(wrapper);// bodyにwrapperを追加varnowEntity="";// どのEntityが選択されているか保管varapp=newVue({// Vue呼び出しel:'#app',// id名がappの要素を参照data:{// 使用するdataを登録clickFlag:false,// クリックされたかentities:self.target.children// 属性で追加したEntityの子どもを参照},methods:{// イベントハンドラ作成onEntityClick:function(target,index){// Entityを選択された時varv_self=this;// thisを保管if(nowEntity){nowEntity.enabled=false;// 今表示されているEntityを非表示に}target.enabled=true;// 選択したEntityを表示nowEntity=target;// 選択したEntityを保管}}});};属性を追加したので、EntityのRootからindex.jsをParseします。
Parseしたら属性のtargetにEntitiesを登録します。
Vueを使ってイベントハンドラを作っていますので、これをHTML側で使用します。
index.htmlをいかに書き換えます。
[index.html]
<divid="app"><headerclass="header"><nav><ol><liv-for="(entity,index) in entities"@click="onEntityClick(entity,index)"><span>{{entity.name}}</span></li></ol></nav></header><mainclass="main"><divclass="container"><section>content01</section><section>content01</section><section>content01</section></div></main></div>ここで、index.jsで呼び出したVueのdataが確認できます。
entitiesというのが、index.jsで属性追加したEntityです。
それをv-forを使って一つずつ呼び出しています。
呼び出すli要素にはonEntityClickを@clickのクリックイベントで呼び出すように書き加えています。
これでLaunchを確認すると、先ほど設定した属性要素のEntitiesの子要素であるEntityの名前が並んでいます。
これらをクリックするとクリックしたモデルに変更されるのが確認できます。
EditorからEntitiesにEntityを追加すると、PlayCanvasのリアルタイムレンダリングによりLaunchをリロードしなくても追加されます。
試しにEntitiesにPrimitiveを追加してみるとわかりやすいでしょう。
Vueを使って3Dモデルの切り替えができましたが、
パッと切り替わってしまうので見応えがありません。
そこで、切り替わる際にアニメーションを入れたいと思います。
切り替え時の動きを作る
Webでアニメーションといえばライブラリが数多く用意されています。
PlayCanvasにもTweenライブラリが用意されていて、これを使うことで現在の値から指定した値へアニメーションを行うことができます。
PlayCanvas Tween Library
https://developer.playcanvas.com/en/tutorials/tweening/
新しくtween.jsを作り、このTween Libraryのコードをコピペします。
書き換え終えたらOKです。
jsのインスペクターを見るとpreloadにチェックが入っています。
これにチェックを入れているとアプリケーションが読み込まれた時に一度ロードされます。
PlayCanvasに関わる記述以外を一度読み込みます。tween.jsはPlayCanvasに関わる記述がないために、Entityへの登録は必要が無くなります。
では、追加したTween Libraryを使ってアニメーションを追加していきます。
index.jsのVueの箇所を以下のコードに書き換えてください。
[index.js]
varIndex=pc.createScript('index');Index.attributes.add("baseHtml",{type:"asset",assetType:"html"});// 登録したhtmlを取得Index.attributes.add("target",{type:"entity"});// 参照するEntityを登録Index.prototype.initialize=function(){varself=this;// this書き換えvarcanvas=document.getElementsByTagName("canvas")[0];// canvasを取得canvas.classList.add("pcCanvas");// canvasにclass名を指定varwrapper=document.createElement("div");// div作成wrapper.classList.add("wrapper");// 作成したdivにwrapperというclass名を指定wrapper.innerHTML=self.baseHtml._resources[0];// 事前に登録していたhtmlをwrapperに流し込みdocument.body.appendChild(wrapper);// bodyにwrapperを追加varnowEntity="";// どのEntityが選択されているか保管varapp=newVue({// Vue呼び出しel:'#app',// id名がappの要素を参照data:{// 使用するdataを登録clickFlag:false,// クリックされたかentities:self.target.children// 属性で追加したEntityの子どもを参照},methods:{// イベントハンドラ作成onEntityClick:function(target,index){// Entityを選択された時varv_self=this;// thisを保管if(v_self.clickFlag)return;// クリックされて処理中かv_self.clickFlag=true;// クリック処理中self.target.tween(self.target.getLocalRotation()).rotate(newpc.Vec3(180,0,0),0.5,pc.QuadraticIn).on('complete',function(){// tweenでrotateをアニメーション completeで完了後呼び出しif(nowEntity){// Entityが保管されているかnowEntity.enabled=false;}target.enabled=true;// 選択したEntityを表示nowEntity=target;// 選択したEntityを保管self.target.tween(newpc.Vec3(180,0,0)).rotate(newpc.Vec3(360,0,0),1,pc.BounceOut).on('complete',function(){v_self.clickFlag=false;}).start();// 選択したEntityのアニメーション}).start();}}});};今回はTweenを使ってRotateさせて180度開店したら選択したEntityに変わり、また180度回転して元に戻るようにしています。
このTweenのアニメーションはPositionやScale、マテリアルがあればその値も使うことができるので、色んな場で活用できる便利なライブラリです。
ここまで出来たら、せっかくDOMも追加してVueも入れているので
選択した3Dモデルの詳細スペックなどが見れるように新たにDOMが表示されるようにしたいと思います。


