Cluster Creator Kit Script Reference

[ 日本語 / English (US) ]

cluster-script-types

Cluster Creator Kitを活用し、多彩なアイテムやワールドの作成が可能です。 これらにJavaScriptを使うことで高度なインタラクションを実装できます。

本ドキュメントでは、JavaScriptからアクセス可能なAPIについて詳細に説明します。 Creator Kitで使用するコンポーネントについては、Creator Kit ドキュメントをご覧ください。

JavaScriptから利用できるJavaScriptの標準組み込みオブジェクトについては説明を省略します。 JavaScriptの使い方を調べる際は、 MDNのJavaScript リファレンス などを参照してください。

ドキュメントで用いられる記法

  • [beta]: 型やメソッドがベータ版で提供される機能が許容された環境でのみ使用可能であることを示します。(許可されていない場合ClusterScriptErrorが発生します)

ベータAPI

ベータ機能を許容する設定がされた空間でのみ有効になるAPIです。 正式リリース前に使用感に対してフィードバックをいただき開発を促進させる目的で提供されています。

ベータ機能について詳細は Creator Kit ドキュメント の ベータ機能の項目 をご覧ください。

基本概念

全てのスクリプトは個々のアイテム(item)で実行され、アイテムの外側で動作するスクリプトは存在しません。 各アイテムのスクリプトは独自のステート($.state)を保有し、空間内に存在する間は並列実行されます。

アイテムはAPIやコンポーネントを通じて、自身の見た目を変える能力を有します。 また、各アイテムは自己のステートに対して自由に操作を行うことができます。 他のアイテムのステートを読み書きすることはできず、特定のAPIを通じた情報交換や空間内での物理的な相互作用に限定されます。

clusterの空間は、アイテム間の独立性とプレイヤー体験を保護するために、各アイテムのCPU時間やメモリを制限します。 これにより、制限を超えたアイテムがあっても、他のアイテムの動作やフレームレートが維持されます。 ただし、制限を超過すると例外が発生するか、一時的に実行が停止する可能性があります。

また、広範囲に影響を与えるAPIは距離制限を持つことがあります。

ハンドルに対する操作

PlayerHandleItemHandleなどをハンドルと呼びます。 ハンドルに対するset...,add...,reset...など、状態の変更を伴うメソッドの呼び出しを「ハンドルに対する操作」と呼びます。

ひとつのアイテムから、他のハンドルに対する操作の合計は最大で10回/秒に制限されています。 瞬間的にこの制限を超えることはできますが、平均回数はこの制限を下回るようにしてください。 この制限を超えた場合、ClusterScriptErrorが発生します。

ItemHandle.sendは「ハンドルに対する操作」に含まれません。 つまり、「ハンドルに対する操作」とItemHandle.sendそれぞれで最大10回/秒の呼び出しを行うことが可能です。

ワールドクラフトでのスクリプトの動作

ワールドクラフト内のアイテムで、 スクリプトが実行されるタイミングとステートについて解説します。

実行タイミング

空間中に存在している間は常にスクリプトが実行されます。 誰もいない空間のスクリプトは実行されません。 (将来的に、負荷軽減のため遠方などのアイテムのスクリプト動作を一時停止する可能性はあります)

  • 「クラフトモード」でのアイテム操作中、有料アイテムを「試す」している最中、どちらの場合もスクリプトは実行されます

実行時間制限

Scriptの初期化及び各コールバック関数の実行時間には最大値が設定されています。

また、実行時間が最大値以下であっても、一定のしきい値を超える実行時間を検出した際には警告ログがコンソールに表示されます。 アイテムの作者には警告ログが出ないようにスクリプトを軽量に作ることが推奨されています。

警告ログが出るしきい値は50msです。 実行時間の最大値及び推奨値は今後変更される可能性があります。

ステート

以下の場合、空のステートで開始されます。

  • アイテムが新たに空間に現れたとき
    • createItemでアイテムが生成されたとき
    • 「クラフトモード」でアイテムを設置しようとしたとき

以下の場合、ステートは維持されます。

  • 「クラフトモード」でアイテムを移動・回転するとき

「クラフトモード」におけるアイテムのコピーはステートをコピーしません。 新規設置と同様にアイテムは空のステートから開始します。

onStartの呼び出しルールについて

ワールドクラフトとCreatorKit製ワールドでonStartの呼び出される条件が異なります。

  • ワールドクラフト

    • アイテムが新たに空間に現れたときに一度だけ実行されます。
      • アイテムをコピーしたとき、コピーによって新たに作られたアイテムのonStartが実行されます。
      • これは、アイテムを複製したときにステートは複製されないためです。
    • アイテムがonStartを実行したかどうかはステートの一部として保存されるため、再入室時にonStartが再度実行されることはありません。
  • 投稿されたワールドクラフト製ワールド

    • ワールドクラフト製ワールド上でスペースが新規に始まるとき、空間の状態は「投稿した時点でのワールドクラフトの状態」で始まります。
    • そのため、元のワールドクラフトでonStartが実行されているアイテムに対しては、ワールドクラフト製ワールド上で実行されることはありません。
    • スペース開始後に新規に作成されたアイテムに対してはワールドクラフトと同様にonStartが実行されます。
  • CreatorKit製ワールド

    • ワールドに置かれているアイテムに対しては、新しくスペースが始まったときにonStartが実行されます。
    • スペース開始後に新規に作成されたアイテムに対しては、作成されたタイミングでonStartが実行されます。

衝突と重なり

  • 衝突:物理的な衝突を意味します。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()}`);
});

PostProcessEffectsのエフェクトの優先順位について

プレイヤーに設定されたポストエフェクトは、UnityのPostProcessingのGlobalなVolumeとして表現されます。 そのVolumeのPriorityは100であり、ワールドに設定されているPriorityが100より小さいPostProcessVolumeを上書きします。 PostProcessEffectsの各設定がsetValue()されていない、もしくはclear()が呼ばれている場合、ワールドに配置されているPostProcessVolumeの値が使用されます。

PlayerHandleに対して設定したPostProcessEffectsのDepthOfFieldSettingsのエフェクト設定は、カメラ機能の被写界深度に上書きされます。

PlayerHandleに対して設定したPostProcessEffectsのBloomSettingsやColorGradingSettingsのエフェクト設定は、それぞれワールドクラフトの光の強さやカラーエフェクトに上書きされます。

型定義ファイル

エディタの入力補完を使いたい方向けに、npmでTypeScript型定義ファイルを公開しています。

https://www.npmjs.com/package/@clustervr/cluster-script-types

Generated using TypeDoc