メインコンテンツまでスキップ

エディターAPI

警告

エディターAPI はベータ機能です。ライブプロジェクトで使用する際は注意してください。

現在ベータ版の「Editor API」をエディターからアクセスでき、基本機能を自動化および拡張するのに役立つAPIがあります。

このAPIは、安定版ではなく将来的に変更される可能性がありますが、現在の状態から大きく変更されることはないでしょう。

The Editor APIはGitHubでオープンソース化されています。APIのドキュメントはこちらで見つけることができます。

自動化の例

APIはブラウザの開発者ツールコンソールを介してアクセスでき、繰り返しタスクを自動化することができます。以下の例では、エディタを使用して、タグ「red」を持つすべてのエンティティを検索し、ブラウザコンソールでコードを実行して無効にしています。

Editor API コード:

(function(){
const entities = editor.entities.root.listByTag('red');
for (const entity of entities) {
entity.set('enabled', false);
}
})();

エディタの機能の拡張

エディターに追加の機能を追加し、カスタムインタフェース(ボタンの追加など)を作成することができます。これは、ブラウザー拡張またはユーザースクリプトなどで実行することができます。

これら2つのうち、よりアクセスしやすいのはユーザースクリプトで、エディタの上にカスタムコードを実行することができます。

以下には、Viewportにボタンが追加され、ボックスをシーンにランダムに配置する例があります。

PlayCanvas チームは現在、Violentmonkeyオープンソースブラウザーエクステンションを使用してユーザースクリプトを管理しています。

ブラウザー拡張をインストールしたら、簡単にカスタムコードを追加できます。手順については、Violentmonkeyのドキュメントを参照してください。

上記のユーザースクリプトのコードは次のとおりです。

// ==UserScript==
// @name Example Script
// @namespace Violentmonkey Scripts
// @match https://playcanvas.com/editor/scene/*
// @grant none
// @version 1.0
// @author -
// @description 20/10/2021, 11:40:21
// ==/UserScript==

(function() {
async function generateBoxes(count, position, radius) {
// create box entity
const box = editor.entities.create({ parent: editor.entities.root });
// find box material asset
const boxMaterial = editor.assets.findOne(asset => asset.get('name') === 'boxMaterial');
// add render component
box.addComponent('render', {
type: 'box',
materialAssets: [boxMaterial.get('id')]
});

// add a number of boxes around a point in the scene
let offset = new pc.Vec3();
let rotation = new pc.Quat();
const result = [];

for (let i = 0; i < count; i++) {
const boxCopy = await box.duplicate();
boxCopy.set('name', 'Box ' + (i + 1));
offset.set(1, 0, 0);
rotation.setFromEulerAngles(0, pc.math.random(-360, 360), 0);
offset = rotation.transformVector(offset);
offset.scale(pc.math.random(-radius, radius));
boxCopy.set('position', [position.x + offset.x, position.y + offset.y, position.z + offset.z]);

result.push(boxCopy);
}

// delete original box
box.delete();

return result;
}

function createButton() {
const btn = new pcui.Button({ text: 'Generate Boxes' });
btn.style.position = 'absolute';
btn.style.bottom = '10px';
btn.style.right = '10px';
editor.call('layout.viewport').append(btn);

let boxes;

btn.on('click', () => {
// delete existing boxes
if (boxes) {
editor.entities.delete(boxes);
boxes = null;
}

generateBoxes(10, new pc.Vec3(), 10).then(result => {
boxes = result;
});
});
}

// Wait until the Editor is available before adding the button
editor.once('load', () => createButton());
})();

スクリプトの重要な部分を解説します。

スクリプトの最上部には、他のユーザーとスクリプトを共有する場合の情報ヘッダーがあります。重要な行は、スクリプトがロードされるURLを制御する @match 属性です。このケースでは、任意のPlayCanvasシーンにロードされるように設定されています。これをどのように変更するかの詳細は、Violentmonkeyのドキュメンテーションで見つけることができます。

// ==UserScript==
// @name Example Script
// @namespace Violentmonkey Scripts
// @match https://playcanvas.com/editor/scene/*
// @grant none
// @version 1.0
// @author -
// @description 20/10/2021, 11:40:21
// ==/UserScript==

これは、エディターが完全にロードされたときのイベントを待つためのプライベートなエディターAPI (Editor API)です。このイベントを使用することで、エディター機能を拡張するためのコードが実行される前に、Editor APIが利用可能であることが確保されます。

    // ボタンを追加する前に、エディタが利用可能になるまで待つ
editor.once('load', () => createButton());

作成されるボタンは、エディタも使用しているPCUIフレームワークライブラリからのものです。また、ボタンをアタッチするためのビューポートDOMを取得するために、いくつかのプライベートAPIを使用しています。

    function createButton() {
const btn = new pcui.Button({ text: 'Generate Boxes' });
btn.style.position = 'absolute';
btn.style.bottom = '10px';
btn.style.right = '10px';
editor.call('layout.viewport').append(btn);

let boxes;

btn.on('click', () => {
// delete existing boxes
if (boxes) {
editor.entities.delete(boxes);
boxes = null;
}

generateBoxes(10, new pc.Vec3(), 10).then(result => {
boxes = result;
});
});
}