[ 日本語 / English (US) ]
The Cluster Creator Kit gives you the ability to create Items and Worlds with ease. You can also enhance your creations with advanced interactions by using JavaScript.
This document outlines the APIs that can be accessed from JavaScript. For information on Components used in the Creator Kit, refer to the Creator Kit Documentation.
Note that this document will not cover JavaScript's standard built-in objects. For a guide on general JavaScript usage, please refer to MDN's JavaScript Reference Documentation.
Beta
This denotes that the type or method is only available in environments where the use of Beta features are permitted.
(If they are not permitted, a ClusterScriptError will occur.)
Item
This denotes that the type or method is only available for scripts of the Scriptable Item component.
Player
This denotes that the type or method is only available for scripts of the Player Script component.
All scripts are executed within an individual Item. No script can run outside of items.
Each script, within each Item, holds its own State ($.state
), and will execute concurrently as long as they exist within the world space.
Items have the ability to change their appearances through the use of APIs and components. Each Item can also freely manipulate their own State. However, an item cannot read or write the State of other items. Interaction between Items are limited to exchanging information through specific APIs, and physical interplay within the world space.
To preserve the independent operation of Items and to protect the player experience, Cluster can limit the CPU time and memory allocated to each Item. This ensures that even if some Items exceed their designated resource limits, other items will remain functional and the application will maintain frame rate. However, if limits are exceeded, an exception may occur or the script execution may be temporarily suspended.
API usages may have certain limitations.
If these limits are exceeded, ClusterScriptError will occur and operations will fail. Please refer for documents of each APIs for individual limit values.
Limit values may be different by whether the world is Creator Kit-based or World Craft. Limit value may change with prior notice.
Beta API is only enabled in environments where the use of Beta features are permitted. It is provided for the purpose of gathering feedback on usage before the final release, to accelerate development.
For details on Beta features, Refer to the Beta features section of the Creator Kit documentation.
APIs that can be used from ScriptableItem are classified into three types.
$.onStart
or $.onUpdate
, etc.$.state
, $.getPosition
or ItemHandle.send
, etc.$.subNode
or new Vector3
, etc.APIs that are available only through callbacks are not supported when called at the top level. In such cases, a warning message is logged to script console.
Standard JavaScript APIs not provided by Cluster Creator Kit are available at top level.
However, it is not recommended to call JavaScript APIs that return different values per call, such as Math.random()
or new Date()
.
Instead, register callbacks and retrieve references like SubNode
on top level, and place further item initialization under $.onStart
.
All APIs that can be used from ScriptableItem are available at both top level and callbacks.
In ClusterScript, reference values that can be used from script and point other entities in a space instance are called Handles, and ItemHandle and PlayerHandle are example of this.
Note: There are other types with Handle
in their names, such as MaterialHandle
or CameraHandle
.
They are different from Handles described here in the sense that they are part of an item or player.
Following APIs returns values of type either ItemHandle
or PlayerHandle
:
sender
argument passed to callback of $.onReceiveYou can distinguish between ItemHandle and PlayerHandle by using ItemHandle.type and PlayerHandle.type.
In this case, be aware that values such as RaycastResult.handle
may be 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 });
Alternatively, JavaScript's instanceof
operator can be used to distinguish between ItemHandle and 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 });
ItemId and PlayerId of PlayerScript can be distinguished in a similar manner.
Calling methods such as set...
, add...
, or reset...
, which all modify the handle, are considered "Handle Manipulations".
An Item can perform Handle Manipulations on other Handles up to 10 times per second. This can be exceeded momentarily, but please keep the average below this limit. If the limit is exceeded, a ClusterScriptError will occur.
ItemHandle.send
has a rate limit separated from Handle Manipulations.
In other words, both handle Manipulations and ItemHandle.send
operations can be invoked up to 10 times per second each.
This section will provide detail on the timing of script execution and the State of Items in World Craft.
Scripts will keep executing as long as they exist in the world space. Scripts will not execute if the world it resides in does not have any players present. (In the future, we may impose new measures to reduce processing load, such as temporarily suspending scripts attached to far away Items.)
An Item will start with an empty State in the case of the following:
createItem
An Item will retain its State in the case of the following:
When copying an Item in Craft Mode, its State is not copied over. It will start from a empty State, like other newly created items.
The conditions under which onStart is called differ between World Craft and Creator Kit-developed worlds.
World Craft
Published Worlds (World Craft-based)
Creator Kit-based Worlds
Collision
object. In Unity, this corresponds to collisions between non-trigger colliders.Overlap
object. In Unity, this corresponds to overlaps between colliders configured as triggers.While moving Items in Craft Mode, neither Collisions nor Overlaps will register for that Item. This applies for both newly created Items and already existing Items.
Scripts in the world space may be executed from players all around the globe. Be careful not to write code that makes assumptions about your local time zone, as it may lead to unexpected behavior.
Obtaining the time in the following style may lead to unexpected behavior.
const date = new Date();
$.log(`${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`);
Instead, make sure to write scripts like the following, which explicitly specifies the time zone.
// A script to obtain the date in Coordinated Universal Time (UTC), regardless of the runtime environment
function getUTCDate() {
const date = new Date();
return {
timezone: "Etc/UTC",
hours: date.getUTCHours(),
minutes: date.getUTCMinutes(),
seconds: date.getUTCSeconds(),
};
}
// A script to obtain the date in Japan Standard Time (JST), regardless of the runtime environment
function getJSTDate() {
const date = new Date();
// Convert the date to Etc/GMT-9 (+9 hours difference)
date.setTime(date.getTime() + 3600000 * 9);
return {
timezone: "Etc/GMT-9",
hours: date.getUTCHours(),
minutes: date.getUTCMinutes(),
seconds: date.getUTCSeconds(),
};
}
// A script to obtain the date in US Eastern Standard Time (EST), regardless of the runtime environment
function getESTDate() {
const date = new Date();
// Convert the date to Etc/GMT+5 (-5 hours difference)
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);
// Do NOT use the below, as the results will vary depending on the runtime environment
// const date = new Date();
// $.log(`local: ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`);
});
The post-effects set for a player are represented as a Global Volume in Unity's PostProcessing.
The Priority of this Volume is set to 100, which overrides any PostProcessVolume in the world with a Priority less than 100.
If the settings of PostProcessEffects are not set using setValue()
, or if clear()
is called, the values of PostProcessVolume placed in the world will be used.
The DepthOfFieldSettings of PostProcessEffects set for PlayerHandle is subject to being overridden by the camera's depth of field.
The BloomSettings and ColorGradingSettings of PostProcessEffects set for PlayerHandle are subject to being overridden by the World Craft's light intensity and color effects.
$.setPlayerScript
.A PlayerScript added by $.setPlayerScript
is valid only while the item that has called $.setPlayerScript
is still in the space.
When the item is deleted, the PlayerScript assigned from the item will also be deleted.
If $.setPlayerScript
is called multiple times, the PlayerScript granted by the earlier $.setPlayerScript
will be deleted and overwritten by the script of the later $.setPlayerScript
.
When a PlayerScript is deleted, the camera settings and button display settings configured by the PlayerScript will be reset.
As PlayerScript is a beta feature, the behavior when PlayerScript is deleted may be changed in the future.
We provide TypeScript type declaration files on npm for those who wish to use autocompletion on their code editor apps.
https://www.npmjs.com/package/@clustervr/cluster-script-types
Generated using TypeDoc