[ 日本語 / English (US) ]
Cluster Creator Kitを活用し、多彩なアイテムやワールドの作成が可能です。 これらにJavaScriptを使うことで高度なインタラクションを実装できます。
本ドキュメントでは、JavaScriptからアクセス可能なAPIについて詳細に説明します。 Creator Kitで使用するコンポーネントについては、Creator Kit ドキュメントをご覧ください。
JavaScriptから利用できるJavaScriptの標準組み込みオブジェクトについては説明を省略します。 JavaScriptの使い方を調べる際は、 MDNのJavaScript リファレンス などを参照してください。
Beta
型やメソッドがベータ版で提供される機能が許容された環境でのみ使用可能であることを示します。
(許可されていない場合、ClusterScriptErrorが発生します。)
Item
型やメソッドが Scriptable Itemコンポーネント のスクリプト内でのみ使用可能であることを示します。
Player
型やメソッドが Player Scriptコンポーネント のスクリプト内でのみ使用可能であることを示します。
全てのスクリプトは個々のアイテム(item)で実行され、アイテムの外側で動作するスクリプトは存在しません。
各アイテムのスクリプトは独自のステート($.state
)を保有し、空間内に存在する間は並列実行されます。
アイテムはAPIやコンポーネントを通じて、自身の見た目を変える能力を有します。 また、各アイテムは自己のステートに対して自由に操作を行うことができます。 他のアイテムのステートを読み書きすることはできず、特定のAPIを通じた情報交換や空間内での物理的な相互作用に限定されます。
clusterの空間は、アイテム間の独立性とプレイヤー体験を保護するために、各アイテムのCPU時間やメモリを制限します。 これにより、制限を超えたアイテムがあっても、他のアイテムの動作やフレームレートが維持されます。 ただし、制限を超過すると例外が発生するか、一時的に実行が停止する可能性があります。
APIは使い方に制限がある場合があります。
これらの制限を超えた場合、ClusterScriptErrorが発生し操作は失敗します。 個々の制限値については各APIのドキュメントを参照してください。
制限値はワールドがCreator Kit製ワールドかワールドクラフトかによって異なる場合があります。 また、制限値は事前告知の上で変更されることがあります。
ベータ機能を許容する設定がされた空間でのみ有効になるAPIです。 正式リリース前に使用感に対してフィードバックをいただき開発を促進させる目的で提供されています。
ベータ機能について詳細は Creator Kit ドキュメント の ベータ機能の項目 をご覧ください。
ScriptableItemから利用できるAPIは以下の3つに分類されます。
$.onStart
や $.onUpdate
など。$.state
、 $.getPosition
、ItemHandle.send
など。$.subNode
、 new Vector3
など。コールバックのみで利用できるAPIは、トップレベルで呼び出した場合はサポートされません。 そのような場合、警告ログがコンソールに表示されます。
Cluster Creator Kitから提供されないJavaScript標準のAPIはトップレベルで利用できます。
ただし、 Math.random()
や、 new Date()
など、呼び出すたびに異なる値を返すJavaScriptのAPIをトップレベルで利用することは推奨されません。
代わりに、コールバックの設定と SubNode
などの取得のみをトップレベルで行い、それらを除くアイテムの初期化処理は $.onStart
内に記述してください。
PlayerScriptから利用できる全てのAPIは、PlayerScriptのトップレベルとコールバックの両方で利用できます。
ClusterScriptでは空間インスタンスに存在する他の物体を指し示すスクリプトから扱える参照値をハンドルと呼び、ItemHandleとPlayerHandleがそれにあたります。
(MaterialHandle
やCameraHandle
など、名前にHandle
を含む型が他にも存在します。
これらはアイテムやプレイヤーの一部であるという意味でここで述べるハンドルとは異なります。)
以下のAPIは、ItemHandle
またはPlayerHandle
のいずれかの型の値を返します。
sender
引数ItemHandle.type と PlayerHandle.type を利用して、ItemHandleとPlayerHandleを区別できます。
この場合、RaycastResult.handle
などの値はnull
である場合もあることに気をつけてください。
$.onReceive((messageType, arg, sender) => {
if (sender.type === "item") {
$.log(`message from item: ${messageType}`);
} else if (sender.type === "player") {
$.log(`message from player: ${messageType}`);
}
}, { player: true });
または、JavaScriptのinstanceof
演算子を利用して、ItemHandleとPlayerHandleを区別できます。
$.onReceive((messageType, arg, sender) => {
if (sender instanceof ItemHandle) {
$.log(`message from item: ${messageType}`);
} else if (sender instanceof PlayerHandle) {
$.log(`message from player: ${messageType}`);
}
}, { player: true });
PlayerScriptのItemIdとPlayerIdも同様の方法で区別できます。
ハンドルに対するset...
,add...
,reset...
など、状態の変更を伴うメソッドの呼び出しを「ハンドルに対する操作」と呼びます。
ひとつのアイテムから、他のハンドルに対する操作の合計は最大で10回/秒に制限されています。 瞬間的にこの制限を超えることはできますが、平均回数はこの制限を下回るようにしてください。 この制限を超えた場合、ClusterScriptErrorが発生します。
ItemHandle.send
には「ハンドルに対する操作」とは独立した制限が適用されます。
つまり、「ハンドルに対する操作」とItemHandle.send
それぞれで最大10回/秒の呼び出しを行うことが可能です。
ワールドクラフト内のアイテムで、 スクリプトが実行されるタイミングとステートについて解説します。
空間中に存在している間は常にスクリプトが実行されます。 誰もいない空間のスクリプトは実行されません。 (将来的に、負荷軽減のため遠方などのアイテムのスクリプト動作を一時停止する可能性はあります)
Scriptの初期化及び各コールバック関数の実行時間には最大値が設定されています。
また、実行時間が最大値以下であっても、一定のしきい値を超える実行時間を検出した際には警告ログがコンソールに表示されます。 アイテムの作者には警告ログが出ないようにスクリプトを軽量に作ることが推奨されています。
警告ログが出るしきい値は50msです。 実行時間の最大値及び推奨値は今後変更される可能性があります。
以下の場合、空のステートで開始されます。
createItem
でアイテムが生成されたとき以下の場合、ステートは維持されます。
「クラフトモード」におけるアイテムのコピーはステートをコピーしません。 新規設置と同様にアイテムは空のステートから開始します。
ワールドクラフトとCreator Kit製ワールドでonStartの呼び出される条件が異なります。
ワールドクラフト
投稿されたワールドクラフト製ワールド
Creator Kit製ワールド
Collision
オブジェクトで表現されます。Unityではトリガーでないコライダー同士の衝突に対応します。Overlap
オブジェクトで表現されます。Unityではトリガーコライダーへの重なりに対応します。「クラフトモード」でアイテムを移動する間はアイテムは衝突も重なりも発生しません。これは新規に作成しているアイテムも既に空間に設置されたアイテムを移動するときも含まれます。
空間のスクリプトは世界中で実行される可能性があります。 実行環境に依存した時刻を扱うスクリプトを書くと、スクリプトが予期しない動作をすることがありますのでご注意ください。
時刻を取得する際に次のように書くと予期しない挙動になることがあります。
const date = new Date();
$.log(`${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`);
次のようにタイムゾーンを明示的に指定したスクリプトを書きましょう。
// スクリプトを実行する環境によらずUTCを取得する関数
function getUTCDate() {
const date = new Date();
return {
timezone: "Etc/UTC",
hours: date.getUTCHours(),
minutes: date.getUTCMinutes(),
seconds: date.getUTCSeconds(),
};
}
// スクリプトを実行する環境によらず日本時刻を取得する関数
function getJSTDate() {
const date = new Date();
// Etc/GMT-9の時刻へ変換 (時差+9時間)
date.setTime(date.getTime() + 3600000 * 9);
return {
timezone: "Etc/GMT-9",
hours: date.getUTCHours(),
minutes: date.getUTCMinutes(),
seconds: date.getUTCSeconds(),
};
}
// スクリプトを実行する環境によらず米国東部標準時を取得する関数
function getESTDate() {
const date = new Date();
// Etc/GMT+5の時刻へ変換 (時差-5時間)
date.setTime(date.getTime() + 3600000 * -5);
return {
timezone: "Etc/GMT+5",
hours: date.getUTCHours(),
minutes: date.getUTCMinutes(),
seconds: date.getUTCSeconds(),
};
}
function logDate(date) {
const hours = date.hours.toString().padStart(2, "0");
const minutes = date.minutes.toString().padStart(2, "0");
const seconds = date.seconds.toString().padStart(2, "0");
$.log(`${date.timezone}: ${hours}:${minutes}:${seconds}`);
}
$.onInteract((player) => {
const dateUTC = getUTCDate();
logDate(dateUTC);
const dateJST = getJSTDate();
logDate(dateJST);
const dateEST = getESTDate();
logDate(dateEST);
// 下記は実行される環境によって結果が異なるので使わない
// const date = new Date();
// $.log(`local: ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`);
});
プレイヤーに設定されたポストエフェクトは、UnityのPostProcessingのGlobalなVolumeとして表現されます。
そのVolumeのPriorityは100であり、ワールドに設定されているPriorityが100より小さいPostProcessVolumeを上書きします。
PostProcessEffectsの各設定がsetValue()
されていない、もしくはclear()
が呼ばれている場合、ワールドに配置されているPostProcessVolumeの値が使用されます。
PlayerHandleに対して設定したPostProcessEffectsのDepthOfFieldSettingsのエフェクト設定は、カメラ機能の被写界深度に上書きされます。
PlayerHandleに対して設定したPostProcessEffectsのBloomSettingsやColorGradingSettingsのエフェクト設定は、それぞれワールドクラフトの光の強さやカラーエフェクトに上書きされます。
$.setPlayerScript
で付与したPlayerScriptの有効期間について$.setPlayerScript
で付与したPlayerScriptは、その$.setPlayerScript
を呼び出したアイテムが空間に存在する間のみ有効です。
アイテムが削除されると、そのアイテムが付与したPlayerScriptも削除されます。
また、$.setPlayerScript
が複数回呼ばれると、先に呼ばれた$.setPlayerScript
で付与されたPlayerScriptは削除されて、あとから呼ばれた$.setPlayerScript
のスクリプトで上書きされます。
PlayerScriptが削除された場合、そのPlayerScript内部で設定したカメラの設定やボタン表示の設定はリセットされます。
PlayerScriptはベータの機能であるため、PlayerScriptが削除された場合の挙動などは将来的に変更される場合があります。
エディタの入力補完を使いたい方向けに、npmでTypeScript型定義ファイルを公開しています。
https://www.npmjs.com/package/@clustervr/cluster-script-types
Generated using TypeDoc