--- title: PlayCanvas Editorに外部スクリプトを読み込む新機能が追加されたので開発方法を考える。- Reduxを組み込む tags: redux PlayCanvas JavaScript author: yushimatenjin slide: false --- ## はじめに PlayCanvas EditorにExternal Scriptsという外部スクリプトを読み込むための機能が追加されました。 この機能ではエディターで設定をした外部のスクリプトを、起動時にタグに挿入する機能となっております。機能自体はこの歯車の設定画面に追加されています。 ### 外部スクリプトを追加する 今までのPlayCanvasではJavaScriptを埋め込む場合にはエディター上で埋め込むスクリプトを書かなければいけませんでしたがこのアップデートによりjQueryやFirebaseなどのSDKを埋め込む場合にもURLで指定が指定できるため、常に最新版を取ってくることができたりと便利になりました。 ![firebaseauth](https://user-images.githubusercontent.com/39250588/62590667-9f733200-b8bc-11e9-8a12-097d6e85b97b.PNG) 追加したスクリプトはエディター上で起動をしたときにタグのPlayCanvasが読み込まれる前に挿入されます。 ![Head123](https://user-images.githubusercontent.com/39250588/62590852-40fa8380-b8bd-11e9-87a3-6fc62916cbdf.PNG)

朝起きたらPlayCanvasで外部スクリプトを読み込むのが簡単になったのでFirebaseとつないでみました。
https://t.co/c2GmILSFK7

— はが (@Mxcn3) August 6, 2019
## PlayCanvasのプロジェクトはこちらになります。

External Scriptsで外部スクリプトを追加できるようになったのでRedux x PlayCanvasを試してみた。
Stateの値によってカメラが寄るサンプルです。 #playcanvashttps://t.co/WaT9W5Gzbj

— はが (@Mxcn3) August 7, 2019
(公開リポジトリなのでフォークができます) [https://playcanvas.com/project/631609/](https://playcanvas.com/project/631609/) ### counter-vanillaを追加する PlayCanvasはReactではないので、Reduxのサンプルの中の[counter-vanilla](https://github.com/reduxjs/redux/tree/master/examples/counter-vanilla)を使用してReduxの導入をします。 ```counter-vanilla/index.html Redux basic example

Clicked: 0 times

``` `counter-vanilla/index.html`はindex.htmlだけあれば特にフレームワークを必要としないサンプルとなっています。 それではこのScriptをPlayCanvasに組み込んでいきましょう 1. External ScriptsへReduxの最新版を追加 index.html内のScript srcで読み込まれているスクリプトをExternal Scriptsの中へ追加します。 `https://unpkg.com/redux@latest/dist/redux.min.js` 2.HTML, CSSをPlayCanvas Editorに追加します。 ```index.html

Clicked: 0 times

``` ```style.css #counter{ position: absolute; z-index: 1; color: red; } button{ padding: 10px; } ``` 3. Store, HTML,CSSの表示をする部分のScriptを追加しAttributesに追加をする HTMLをPlayCanvas上に追加をする為にAttributesとしてEditor上で先ほどEnditor上に追加をしたHTMLとCSSセットします。 ```Ui.js constUi = 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" }); const counter = (state, action) => { if (typeof state === 'undefined') { return 1 } switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } } const store = Redux.createStore(counter) Ui.prototype.initialize = function() { const body = document.getElementsByTagName("body")[0]; const head = document.getElementsByTagName("head")[0]; const style = ``; body.insertAdjacentHTML("afterbegin", this.html.resource); head.insertAdjacentHTML("afterbegin", style); //HTML, CSSを挿入する var valueEl = document.getElementById('value') function render() { valueEl.innerHTML = store.getState().toString() } render() store.subscribe(render) document.getElementById('increment') .addEventListener('click', function () { store.dispatch({ type: 'INCREMENT' }) }) document.getElementById('decrement') .addEventListener('click', function () { store.dispatch({ type: 'DECREMENT' }) }) }; ``` このScriptを追加することでPlayCanvas上にカウンターが追加されました。 ## コンポーネントにStateの値を適用させる ### テキストコンポーネント このままだと、HTMLを上にかぶせているだけです、Reduxの状態を参照してインクリメントした文字に変更するエンティティを追加します。   1. `2D Screen`を追加   2. `2D Screen`以下に`Text`エンティティを追加 3. フォントを追加   4. 4.Scriptを追加する `Text`エンティティに対して`text.js`というスクリプトを追加します。 ```text.js const Text = pc.createScript('text'); Text.prototype.update = function(dt) { this.entity.element.text = store.getState().toString() }; ``` ### カメラの値を変更する 1. `Camera`エンティティに`camera.js`を追加する ```camera.js const Camera = pc.createScript('camera'); Camera.prototype.update = function() { this.entity.camera.fov = store.getState() * 2 - 30 }; ``` これでReduxのアクションにより`Camera`エンティティの`fov`が寄る、`Text`エンティティの値を変更することができました ![output](https://user-images.githubusercontent.com/39250588/62592654-80c46980-b8c3-11e9-95c3-df0cc7ffcc44.gif) ## PlayCanvasのプロジェクトはこちらになります。

External Scriptsで外部スクリプトを追加できるようになったのでRedux x PlayCanvasを試してみた。
Stateの値によってカメラが寄るサンプルです。 #playcanvashttps://t.co/WaT9W5Gzbj

— はが (@Mxcn3) August 7, 2019
### 疑問 Update関数で毎秒評価しているのはどうなんだろう Reduxの3原則は守れてそう - Single source of truth - State in read-only - Changes are made with pure functions