```lua
example 2
````
##### angularVelocity[β](#angularvelocity "Direct link to angularVelocity")
float **angularVelocity** `get` `set`
*The angular velocity of the particle.*
* Lua
```lua
this = Space.Host.ExecutingObject
OnParticleTrigger = function(GameObject)
ParticlesArray = this.ParticleSystem.GetTriggerParticles(0)
FirstParticle = ParticlesArray[1]
angularVelocity= FirstParticle.angularVelocity
end
this.SubscribeToEvents()
this.OnParticleTrigger(OnParticleTrigger)
```
##### angularVelocity3D[β](#angularvelocity3d "Direct link to angularVelocity3D")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **angularVelocity3D** `get` `set`
*The 3D angular velocity of the particle.*
* Lua
```lua
this = Space.Host.ExecutingObject
OnParticleTrigger = function(GameObject)
ParticlesArray = this.ParticleSystem.GetTriggerParticles(0)
FirstParticle = ParticlesArray[1]
angularVelocity3D= FirstParticle.angularVelocity3D
end
this.SubscribeToEvents()
this.OnParticleTrigger(OnParticleTrigger)
```
---
### SPhysicsHit
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| -------------------------------------------------------------------------------------------------------- |
| SGameObject [**Object** ](/scripting/client-scripting-api-reference/types/sphysicshit.md#object)`get` |
| SVector [**Position** ](/scripting/client-scripting-api-reference/types/sphysicshit.md#position)`get` |
| SVector [**Normal** ](/scripting/client-scripting-api-reference/types/sphysicshit.md#normal)`get` |
| SVector [**UV** ](/scripting/client-scripting-api-reference/types/sphysicshit.md#uv)`get` |
| SVector [**UV2** ](/scripting/client-scripting-api-reference/types/sphysicshit.md#uv2)`get` |
| float [**Distance** ](/scripting/client-scripting-api-reference/types/sphysicshit.md#distance)`get` |
| bool [**ContainsHit** ](/scripting/client-scripting-api-reference/types/sphysicshit.md#containshit)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### Object[β](#object "Direct link to Object")
[SGameObject ](/scripting/client-scripting-api-reference/types/sgameobject.md)**Object** `get`
*Property Description*
* Lua
```lua
this = Space.Host.ExecutingObject
hit = Space.Physics.RayCastSingle(this.WorldPosition,this.Forward,20)
hitGameObject = hit.Object
```
* Lua
```lua
example 2
```
##### Position[β](#position "Direct link to Position")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **Position** `get`
*Where the physics hit occurred*
* Lua
```lua
this = Space.Host.ExecutingObject
hit = Space.Physics.RayCastSingle(this.WorldPosition,this.Forward,20)
hitPosition = hit.Position
```
##### Normal[β](#normal "Direct link to Normal")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **Normal** `get`
*The normal of the hit*
* Lua
```lua
this = Space.Host.ExecutingObject
hit = Space.Physics.RayCastSingle(this.WorldPosition,this.Forward,20)
hitNormal = hit.Normal
```
##### UV[β](#uv "Direct link to UV")
SVector **UV** `get`
*The UV coordinates of where the hit occurred on a mesh.*
danger
This property will currently always return \[0,0] due to a current bug.
* Lua
```lua
this = Space.Host.ExecutingObject
hit = Space.Physics.RayCastSingle(this.WorldPosition,this.Forward,20)
hitUV = hit.UV
```
##### UV2[β](#uv2 "Direct link to UV2")
SVector **UV2** `get`
*The UV2 coordinates of where the hit occurred on a mesh.*
danger
This property will currently always return \[0,0] due to a current bug.
* Lua
```lua
this = Space.Host.ExecutingObject
hit = Space.Physics.RayCastSingle(this.WorldPosition,this.Forward,20)
hitUV2 = hit.UV2
```
##### Distance[β](#distance "Direct link to Distance")
float **Distance** `get`
*How far down a ray or from the collider, the hit occurred*
* Lua
```lua
this = Space.Host.ExecutingObject
hit = Space.Physics.RayCastSingle(this.WorldPosition,this.Forward,20)
hitDistance = hit.Distance
```
##### ContainsHit[β](#containshit "Direct link to ContainsHit")
bool **ContainsHit** `get`
*Whether it was a hit or not*
* Lua
```lua
this = Space.Host.ExecutingObject
hit = Space.Physics.RayCastSingle(this.WorldPosition,this.Forward,20)
hitContainsHit = hit.ContainsHit
```
---
### SPublicRegion
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| -------------------------------------------------------------------------------------------------------------- |
| int [**ID**](/scripting/client-scripting-api-reference/types/spublicregion.md#id) `get` |
| int [**OwnerID** ](/scripting/client-scripting-api-reference/types/spublicregion.md#ownerid)`get` |
| string [**Name** ](/scripting/client-scripting-api-reference/types/spublicregion.md#name)`get` |
| string [**MapPath** ](/scripting/client-scripting-api-reference/types/spublicregion.md#mappath)`get` |
| string [**PreviewPath** ](/scripting/client-scripting-api-reference/types/spublicregion.md#previewpath)`get` |
| int [**RankingScore** ](/scripting/client-scripting-api-reference/types/spublicregion.md#rankingscore)`get` |
| int [**MaxAvatars** ](/scripting/client-scripting-api-reference/types/spublicregion.md#maxavatars)`get` |
| int [**FileSize** ](/scripting/client-scripting-api-reference/types/spublicregion.md#filesize)`get` |
| int [**Memory** ](/scripting/client-scripting-api-reference/types/spublicregion.md#memory)`get` |
| SLandmark\[] [**Landmarks** ](/scripting/client-scripting-api-reference/types/spublicregion.md#landmarks)`get` |
| SSubRegion\[] [**Regions** ](/scripting/client-scripting-api-reference/types/spublicregion.md#regions)`get` |
| string [**Description** ](/scripting/client-scripting-api-reference/types/spublicregion.md#description)`get` |
| SAccessType [**Access** ](/scripting/client-scripting-api-reference/types/spublicregion.md#access)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### ID[β](#id "Direct link to ID")
int **ID** `get`
*The Region ID of this region*
* Lua
```lua
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionID = r.ID
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### OwnerID[β](#ownerid "Direct link to OwnerID")
int **OwnerID** `get`
*The ID of the owner of this region*
* Lua
```lua
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionOwnerID = r.OwnerID
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### Name[β](#name "Direct link to Name")
string **Name** `get`
*The Name of this region*
* Lua
```lua
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionName = r.Name
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### MapPath[β](#mappath "Direct link to MapPath")
string **MapPath** `get`
*Property Description*
* Lua
```lua
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionMapPath = r.MapPath
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### PreviewPath[β](#previewpath "Direct link to PreviewPath")
string **PreviewPath** `get`
*Property Description*
* Lua
```lua
--Make's a UIText show the Preview Path of the user's first available region
textObject = Space.Host.GetReference("TheTextReference")
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionPreviewPath = r.PreviewPath
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### RankingScore[β](#rankingscore "Direct link to RankingScore")
int **RankingScore** `get`
*The Ranking Score of the region.*
* Lua
```lua
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionRankingScore = r.RankingScore
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### MaxAvatars[β](#maxavatars "Direct link to MaxAvatars")
int **MaxAvatars** `get`
*The max number of avatars this region can hold.*
* Lua
```lua
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionMaxAvatars = r.MaxAvatars
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### FileSize[β](#filesize "Direct link to FileSize")
int **FileSize** `get`
*The current MBs the region is using.*
* Lua
```lua
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionFileSize = r.FileSize
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### Memory[β](#memory "Direct link to Memory")
int **Memory** `get`
*Property Description*
* Lua
```lua
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionMemory = r.Memory
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### Landmarks[β](#landmarks "Direct link to Landmarks")
[SLandmark](/scripting/client-scripting-api-reference/types/slandmark.md)\[] **Landmarks** `get`
*An array of Landmarks in the region.*
* Lua
\`\`\` function GetUserRegionsComplete(SUserRegions) local r = SUserRegions.AvailableRegions\[1] regionLandmarks = r.Landmarks end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete) \`\`\`
##### Regions[β](#regions "Direct link to Regions")
[SSubRegion](/scripting/client-scripting-api-reference/types/ssubregion.md)\[] **Regions** `get`
*Returns an array of* [*SSubRegion*](/scripting/client-scripting-api-reference/types/ssubregion.md) *in the region.*
* Lua
```lua
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionSubRegions = r.Regions
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### Description[β](#description "Direct link to Description")
string **Description** `get`
*Returns the description of the region.*
* Lua
```lua
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionDescription = r.Description
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### Access[β](#access "Direct link to Access")
int **Access** `get`
*The access type of the region (such as "Public" or "Approved only")*
*1=* Disabled, 2= FreeForall, 3= FriendsOnly, 4= ApprovedOnly, 5= GroupsOnly
* Lua
```lua
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
regionAccessType = r.Access
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
---
### SQuaternion
#### Index[β](#index "Direct link to Index")
##### Functions Index[β](#functions-index "Direct link to Functions Index")
| Function |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| string [**ToString** ](/scripting/client-scripting-api-reference/types/squaternion.md#tostring)() |
| float [**Angle** ](/scripting/client-scripting-api-reference/types/squaternion.md#angle)(SQuaternion b) |
| SQuaternion [**Lerp** ](/scripting/client-scripting-api-reference/types/squaternion.md#lerp)(SQuaternion b, float t) |
| SQuaternion [**Slerp** ](/scripting/client-scripting-api-reference/types/squaternion.md#slerp)(SQuaternion b, float t) |
| SQuaternion [**RotateTowards** ](/scripting/client-scripting-api-reference/types/squaternion.md#rotatetowards)(SQuaternion b, float delta) |
| float [**Dot** ](/scripting/client-scripting-api-reference/types/squaternion.md#dot)(SQuaternion b) |
| bool [**Equals** ](/scripting/client-scripting-api-reference/types/squaternion.md#equals)(SQuaternion other) |
| |
| **Static Functions** |
| static SQuaternion [**New** ](/scripting/client-scripting-api-reference/types/squaternion.md#new)(float x, float y, float z, float w) |
| static SQuaternion [**Euler** ](/scripting/client-scripting-api-reference/types/squaternion.md#euler)(float x, float y, float z) |
| static SQuaternion [**AngleAxis** ](/scripting/client-scripting-api-reference/types/squaternion.md#angleaxis)(SVector axis, float angle) |
| static SQuaternion [**LookRotation** ](squaternion#lookrotation)(SVector forward)
static SQuaternion [**LookRotation** ](squaternion#lookrotation)(SVector forward, SVector up) |
| static SVector [**operator**](squaternion#operator) *(SQuaternion a, SVector b)*
*static SQuaternion* [***operator***](squaternion#operator) (SQuaternion a, SQuaternion b) |
| static SQuaternion **FromToRotation** (SVector a, SVector b) |
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ---------------------------------------------------------------------------------------------------------------- |
| float [**X**](/scripting/client-scripting-api-reference/types/squaternion.md#x) `get` `set` |
| float [**Y**](/scripting/client-scripting-api-reference/types/squaternion.md#y) `get` `set` |
| float [**Z**](/scripting/client-scripting-api-reference/types/squaternion.md#z) `get` `set` |
| float [**W**](/scripting/client-scripting-api-reference/types/squaternion.md#w) `get` `set` |
| SVector [**EulerAngles** ](/scripting/client-scripting-api-reference/types/squaternion.md#eulerangles)`get` |
| SQuaternion [**Inverse** ](/scripting/client-scripting-api-reference/types/squaternion.md#inverse)`get` |
| |
| **Static Properties** |
| static SQuaternion [**Identity** ](/scripting/client-scripting-api-reference/types/squaternion.md#identity)`get` |
#### Functions[β](#functions "Direct link to Functions")
##### ToString[β](#tostring "Direct link to ToString")
string **ToString** ()
*Converts a quaternion to a human readable string*
* Lua
```lua
aQuaternion = Quaternion.New(0.0, 1.0, 0.0, 0.0)
theString = aQuaternion.ToString()
```
##### Angle[β](#angle "Direct link to Angle")
float **Angle** (SQuaternion b)
*Returns the angle between two quaternions*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local newQuat = Quaternion.New(0.0, 0.707, 0.0, 0.707);
local otherQuat = Quaternion.New(0.0, 1.0, 0.0, 0.0);
angle = newQuat.Angle(otherQuat);
Space.Log(angle);
-- prints 90.0173034667969
```
##### Lerp[β](#lerp "Direct link to Lerp")
SQuaternion **Lerp** (SQuaternion b, float t)
*Linearly interpolates between this and other quaternion, by factor t and returns the result*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
QuatA = Quaternion.New(0.0, 0.707, 0.0, 0.707)
QuatB = Quaternion.New(0.0, 1.0, 0.0, 0.0)
QuatLerpAB = QuatA.Lerp(QuatB, Space.Time * 0.1)
```
* Lua
```lua
local cube = Space.Host.ExecutingObject
local fromQuat = cube.LocalRotation
local toQuat = Quaternion.New(0.0, 0.707, 0.0, 0.707)
local speed = 0.1
-- The cube will rotate 90 degrees from current rotation by speed amount.
local moveCube = function()
cube.LocalRotation = fromQuat.Lerp(toQuat, Space.Time * speed);
end
cube.OnUpdate(moveCube)
```
##### Slerp[β](#slerp "Direct link to Slerp")
SQuaternion **Slerp** (SQuaternion b, float t)
*Spherically interpolates between this and other quaternion, by factor t and returns the result*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
QuatA = Quaternion.New(0.0, 0.707, 0.0, 0.707)
QuatB = Quaternion.New(0.0, 1.0, 0.0, 0.0)
QuatLerpAB = QuatA.Slerp(QuatB, Space.Time * 0.1)
```
* Lua
```lua
local cube = Space.Host.ExecutingObject;
local fromQuat = cube.LocalRotation;
local toQuat = Quaternion.New(0.0, 1.0, 0.0, 0.0);
local speed = 0.1;
-- The cube will rotate 180 degrees from current rotation by speed amount.
local moveCube = function()
cube.LocalRotation = fromQuat.Slerp(toQuat, Space.Time * speed)
end
cube.OnUpdate(moveCube)
```
##### RotateTowards[β](#rotatetowards "Direct link to RotateTowards")
SQuaternion **RotateTowards** (SQuaternion b, float delta)
*Rotates this towards other, by no more than t degrees*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
QuatA = Quaternion.New(0.0, 0.707, 0.0, 0.707)
QuatB = Quaternion.New(0.0, 1.0, 0.0, 0.0)
ARotatedTowardB = QuatA.RotateTowards(QuatB, Space.Time * 0.1)
```
* Lua
```lua
local cube = Space.Host.ExecutingObject
local fromQuat = cube.LocalRotation
local target = Quaternion.New(0.0, 0.707, 0.0, 0.707)
local speed = 10.0
-- The cube will rotate 90 degrees from current rotation by step amount.
local moveCube = function()
local step = speed * Space.Time
cube.LocalRotation = fromQuat.RotateTowards(target, step)
end
cube.OnUpdate(moveCube)
```
##### Dot[β](#dot "Direct link to Dot")
float **Dot** (SQuaternion b)
*Returns the dot product of this and another quaternion*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local quat = Quaternion.New(0.0, 0.707, 0.0, 0.707);
local quatOther = Quaternion.New(0.0, 0.0, 0.0, 1.0);
Space.Log(quat.Dot(quatOther));
-- prints 0.707000017166138
```
##### Equals[β](#equals "Direct link to Equals")
bool **Equals** (SQuaternion other)
*Function Description*
| Parameter | Type | Description |
| --------- | ----------- | ------------------------------------------------ |
| other | SQuaternion | The other Quaternion that we are comparing with. |
* Lua
```lua
QuatA = Quaternion.New(0.0, 0.707, 0.0, 0.707)
QuatB = Quaternion.New(0.0, 1.0, 0.0, 0.0)
isEqual = QuatA.Equals(QuatB)
```
##### New[β](#new "Direct link to New")
static SQuaternion **New** (float x, float y, float z, float w)
*Creates a new Quaternion*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
newQuat = Quaternion.New(0.0, 0.707, 0.0, 0.707)
```
##### Euler[β](#euler "Direct link to Euler")
static SQuaternion **Euler** (float x, float y, float z)
*Creates a quaternion using Euler angles.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
newQuat = Quaternion.Euler(0.0, 90.0, 0.0)
```
##### AngleAxis[β](#angleaxis "Direct link to AngleAxis")
static SQuaternion **AngleAxis** ([SVector](/scripting/client-scripting-api-reference/types/svector.md) axis, float angle)
*Creates a quaternion from an Angle/Axis pair*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
newVector = Vector.New(0.0, 90.0, 0.0)
newQuat = Quaternion.AngleAxis(newVector, 90.0)
```
##### LookRotation[β](#lookrotation "Direct link to LookRotation")
static SQuaternion **LookRotation** ([SVector](/scripting/client-scripting-api-reference/types/svector.md) forward)
static SQuaternion **LookRotation** ([SVector](/scripting/client-scripting-api-reference/types/svector.md) forward, [SVector](/scripting/client-scripting-api-reference/types/svector.md) up)
*Creates a quaternion a forward vector; presuming up is (0,1,0)*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local newQuat = Quaternion.LookRotation(Vector.Forward);
-- or
local newQuat = Quaternion.LookRotation(Vector.Forward, Vector.Up);
```
##### operator\*[β](#operator "Direct link to operator*")
static [SVector](/scripting/client-scripting-api-reference/types/svector.md) **operator**\* (SQuaternion a, [SVector](/scripting/client-scripting-api-reference/types/svector.md) b)
static SQuaternion **operator**\* (SQuaternion a, SQuaternion b)
*The result of using the \* operator.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
newQuat = Quaternion.New(0.0, 1.0, 0.0, 0.0)
newVector = Vector.Forward
rotatedVector = newQuat * newVector
--or
newQuat = Quaternion.New(0.0, 0.707, 0.0, 0.707)
newVector = Vector.New(0.0, 0.0, 0.0)
rotatedVector = newQuat * newQuat
```
##### FromToRotation[β](#fromtorotation "Direct link to FromToRotation")
static SQuaternion **FromToRotation** (SVector a, SVector b)
*Creates a rotation which rotates from a to b.*
*Usually you use this to rotate a transform so that one of its axes eg. the y-axis - follows a target direction b in world space.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
VectorA = Vector.New(0.0,1.0,0.0)
VectorB = Vector.New(1.0,0.0,0.0)
QuaternionFromToRotation = Quaternion.FromToRotation(VectorA, VectorB)
```
#### Properties[β](#properties "Direct link to Properties")
##### X[β](#x "Direct link to X")
float **X** `get` `set`
*X axis*
* Lua
```lua
newQuat = Quaternion.New(0.0, 1.0, 0.0, 0.0)
newQuat.X = 40.0
```
* Lua
```lua
obj = Space.Host.ExecutingObject
originalRot = obj.LocalRotation
onStartMethod = function()
Space.Log(originalRot.x)
-- prints the X component of this object as a float
originalRot.x = 0.25
-- assigns 0.25 value to the X component
obj.LocalRotation = originalRot
-- sets the the new rotation
end
obj.OnStart(onStartMethod)
```
##### Y[β](#y "Direct link to Y")
float **Y** `get` `set`
*Y axis*
* Lua
```lua
newQuat = Quaternion.New(0.0, 1.0, 0.0, 0.0)
newQuat.Y = 40.0
```
* Lua
```lua
obj = Space.Host.ExecutingObject
originalRot = obj.LocalRotation
onStartMethod = function()
Space.Log(originalRot.y);
-- prints the Y component of this object as a float
originalRot.y = 0.25;
-- assigns 0.25 value to the Y component
obj.LocalRotation = originalRot;
-- sets the the new rotation
end
obj.OnStart(onStartMethod);
```
##### Z[β](#z "Direct link to Z")
float **Z** `get` `set`
*Z axis*
* Lua
```lua
newQuat = Quaternion.New(0.0, 1.0, 0.0, 0.0)
newQuat.Z = 40.0
```
* Lua
```lua
local obj = Space.Host.ExecutingObject;
local originalRot = obj.LocalRotation;
obj.SubscribeToEvents();
local onStartMethod = function()
Space.Log(originalRot.z);
-- prints the Z component of this object as a float
originalRot.z = 0.25;
-- assigns 0.25 value to the Z component
obj.LocalRotation = originalRot;
-- sets the the new rotation
end
obj.OnStart(onStartMethod);
```
##### W[β](#w "Direct link to W")
float **W** `get` `set`
*W axis*
* Lua
```lua
newQuat = Quaternion.New(0.0, 1.0, 0.0, 0.0)
newQuat.W = 40.0
```
* Lua
```lua
local obj = Space.Host.ExecutingObject;
local originalRot = obj.LocalRotation;
obj.SubscribeToEvents();
local onStartMethod = function()
Space.Log(originalRot.w);
-- prints the W component of this object as a float
originalRot.w = 0.25;
-- assigns 0.25 value to the W component
obj.LocalRotation = originalRot;
-- sets the the new rotation
end
obj.OnStart(onStartMethod);
```
##### EulerAngles[β](#eulerangles "Direct link to EulerAngles")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **EulerAngles** `get`
*Returns the Euler rotation for this Quaternion*
* Lua
```lua
newQuat = Quaternion.New(0.0, 0.707, 0.0, 0.707)
euler = newQuat.EulerAngles
```
##### Inverse[β](#inverse "Direct link to Inverse")
SQuaternion **Inverse** `get`
*Returns the inverse of this quaternion*
* Lua
```lua
quat = Quaternion.New(0.0, 0.707, 0.0, 0.707)
inverseQuat = quat.Inverse
```
##### Identity[β](#identity "Direct link to Identity")
static SQuaternion **Identity** `get`
*Equivalent of new SQuaternion(0,0,0,1)*
* Lua
```lua
identity = Quaternion.Identity
```
---
### SRay
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ------------------------------------------------------------------------------------------------ |
| SVector [**Origin** ](/scripting/client-scripting-api-reference/types/sray.md#origin)`get` |
| SVector [**Direction** ](/scripting/client-scripting-api-reference/types/sray.md#direction)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### Origin[β](#origin "Direct link to Origin")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **Origin** `get`
*The origin point of the ray.*
* Lua
```lua
ray=Space.Camera.ScreenCoordinatesToRay(Vector.New(0.5,0.5,0))
rayOrigin = ray.Origin
```
* Lua
```lua
--this script will make this object jump to wherever you right click
--(Example: moving objects with right click )
thisGameObject = Space.Host.ExecutingObject
OnUpdate = function()
if Space.Input.GetMouseDown(1) then
clickRay = Space.Camera.ScreenCoordinatesToRay(Space.Input.MousePosition)
rayCastHit = Space.Physics.RayCastSingle(clickRay.Origin, clickRay.Direction, 50.0)
thisGameObject.WorldPosition = rayCastHit.Position
end
end
thisGameObject.SubscribeToEvents()
thisGameObject.OnUpdate(OnUpdate)
```
##### Direction[β](#direction "Direct link to Direction")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **Direction** `get`
*The direction of the ray.*
* Lua
```lua
ray=Space.Camera.ScreenCoordinatesToRay(Vector.New(0.5,0.5,0))
rayDirection = ray.Direction
```
* Lua
```lua
--this script will make this object jump to wherever you right click
--(Example: moving objects with right click )
thisGameObject = Space.Host.ExecutingObject
OnUpdate = function()
if Space.Input.GetMouseDown(1) then
clickRay = Space.Camera.ScreenCoordinatesToRay(Space.Input.MousePosition)
rayCastHit = Space.Physics.RayCastSingle(clickRay.Origin, clickRay.Direction, 50.0)
thisGameObject.WorldPosition = rayCastHit.Position
end
end
thisGameObject.SubscribeToEvents()
thisGameObject.OnUpdate(OnUpdate)
```
---
### SRect
#### Index[β](#index "Direct link to Index")
##### Functions Index[β](#functions-index "Direct link to Functions Index")
| Function |
| ---------------------------------------------------------------------------------------------------------------------------------- |
| bool [**Contains** ](srect#contains)(SVector point)
bool [**Contains** ](srect#contains)(SVector point, bool allowInverse) |
| bool [**Overlaps** ](srect#overlaps)(SRect other)
bool [**Overlaps** ](srect#overlaps)(SRect other, bool allowInverse) |
| bool [**Equals** ](/scripting/client-scripting-api-reference/types/srect.md#equals)(SRect other) |
| string [**ToString** ](srect#tostring)(string format)
string [**ToString** ](srect#tostring)() |
| |
| **Static Functions** |
| static SRect [**New** ](/scripting/client-scripting-api-reference/types/srect.md#new)(float x, float y, float width, float height) |
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ----------------------------------------------------------------------------------------------- |
| float [**X**](/scripting/client-scripting-api-reference/types/srect.md#x) `get` `set` |
| float [**Y**](/scripting/client-scripting-api-reference/types/srect.md#y) `get` `set` |
| float [**Width**](/scripting/client-scripting-api-reference/types/srect.md#width) `get` `set` |
| float [**Height** ](/scripting/client-scripting-api-reference/types/srect.md#height)`get` `set` |
| SVector [**Position** ](/scripting/client-scripting-api-reference/types/srect.md#position)`get` |
| SVector [**Center** ](/scripting/client-scripting-api-reference/types/srect.md#center)`get` |
| SVector [**Min** ](/scripting/client-scripting-api-reference/types/srect.md#min)`get` |
| SVector [**Max** ](/scripting/client-scripting-api-reference/types/srect.md#max)`get` |
| SVector [**Size** ](/scripting/client-scripting-api-reference/types/srect.md#size)`get` |
| float [**XMin** ](/scripting/client-scripting-api-reference/types/srect.md#xmin)`get` |
| float [**YMin** ](/scripting/client-scripting-api-reference/types/srect.md#ymin)`get` |
| float [**XMax** ](/scripting/client-scripting-api-reference/types/srect.md#xmax)`get` |
| float [**YMax** ](/scripting/client-scripting-api-reference/types/srect.md#ymax)`get` |
| float [**Left** ](/scripting/client-scripting-api-reference/types/srect.md#left)`get` |
| float [**Right** ](/scripting/client-scripting-api-reference/types/srect.md#right)`get` |
| float [**Top** ](/scripting/client-scripting-api-reference/types/srect.md#top)`get` |
| float [**Bottom** ](/scripting/client-scripting-api-reference/types/srect.md#bottom)`get` |
#### Functions[β](#functions "Direct link to Functions")
##### Contains[β](#contains "Direct link to Contains")
bool **Contains** ([SVector](/scripting/client-scripting-api-reference/types/svector.md) point)
bool **Contains** ([SVector](/scripting/client-scripting-api-reference/types/svector.md) point, bool allowInverse)
*Returns true if the x and y components of point is a point inside this rectangle. If allowInverse is present and true, the width and height of the Rect are allowed to take negative values (ie, the min value is greater than the max), and the test will still work.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
newRect=Rect.New(0,0,150,150)
otherRect = Rect.New(0,0,150,150)
isContains = newRect.Contains(otherRect)
--or
isContains = newRect.Contains(otherRect , true)
```
##### Overlaps[β](#overlaps "Direct link to Overlaps")
bool **Overlaps** (SRect other)
bool **Overlaps** (SRect other, bool allowInverse)
*Returns true if the other rectangle overlaps this one. If allowInverse is present and true, the widths and heights of the Rects are allowed to take negative values (ie, the min value is greater than the max), and the test will still work.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
newRect=Rect.New(0,0,150,150)
otherRect = Rect.New(0,0,150,150)
isOverlapping = newRect.Overlaps(otherRect)
--or
isOverlapping = newRect.Overlaps(otherRect , true)
```
##### Equals[β](#equals "Direct link to Equals")
bool **Equals** (SRect other)
Returns true if the rectangles are the same.
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
newRect=Rect.New(0,0,150,150)
otherRect = Rect.New(0,0,150,150)
AreEqual = newRect.Equals(otherRect)
```
##### ToString[β](#tostring "Direct link to ToString")
string **ToString** (string format)
string **ToString** ()
Returns string for this Rect.
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
newRect=Rect.New(0,0,150,150)
otherRect = Rect.New(0,0,150,150)
AreEqual = newRect.Equals(otherRect)
```
##### New[β](#new "Direct link to New")
static SRect **New** (float x, float y, float width, float height)
*Constructs a new SRect*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
newRect=Rect.New(0,0,150,150)
```
#### Properties[β](#properties "Direct link to Properties")
##### X[β](#x "Direct link to X")
float **X** `get` `set`
*Property Description*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
newRect.X = 10.0
```
##### Y[β](#y "Direct link to Y")
float **Y** `get` `set`
*Property Description*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
newRect.Y = 10.0
```
##### Width[β](#width "Direct link to Width")
float **Width** `get` `set`
*Property Description*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
newRect.Width = 10.0
```
##### Height[β](#height "Direct link to Height")
float **Height** `get` `set`
*Property Description*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
newRect.Height = 10.0
```
##### Position[β](#position "Direct link to Position")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **Position** `get`
*The X and Y position of the rectangle.*
* Lua
```lua
newRect=Rect.New(50,50,150,150)
positionVector = newRect.position
```
##### Center[β](#center "Direct link to Center")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **Center** `get`
*The position of the center of the rectangle.*
* Lua
```lua
newRect = Rect.New(50,50,150,150)
VectorCenter = newRect.Center
```
##### Min[β](#min "Direct link to Min")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **Min** `get`
*The position of the minimum corner of the rectangle.*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
vectorMin = newRect.Min
```
##### Max[β](#max "Direct link to Max")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **Max** `get`
*The position of the maximum corner of the rectangle.*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
vectorMax = newRect.Max
```
##### Size[β](#size "Direct link to Size")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **Size** `get`
*The width and height of the rectangle.*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
vectorSize = newRect.Size
```
##### XMin[β](#xmin "Direct link to XMin")
float **XMin** `get`
*The minimum X coordinate of the rectangle.*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
floatXMin = newRect.XMin
```
##### YMin[β](#ymin "Direct link to YMin")
float **YMin** `get`
*The minimum Y coordinate of the rectangle.*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
floatYMin = newRect.YMin
```
##### XMax[β](#xmax "Direct link to XMax")
float **XMax** `get`
*The maximum Y coordinate of the rectangle.*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
floatXMax = newRect.XMax
```
##### YMax[β](#ymax "Direct link to YMax")
float **YMax** `get`
*The maximum Y coordinate of the rectangle.*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
floatYMax = newRect.YMax
```
##### Left[β](#left "Direct link to Left")
float **Left** `get`
*Property Description*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
floatLeft = newRect.Left
```
##### Right[β](#right "Direct link to Right")
float **Right** `get`
*Property Description*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
floatRight = newRect.Right
```
##### Top[β](#top "Direct link to Top")
float **Top** `get`
*Property Description*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
floatTop = newRect.Top
```
##### Bottom[β](#bottom "Direct link to Bottom")
float **Bottom** `get`
*Property Description*
* Lua
```lua
newRect=Rect.New(0,0,150,150)
floatBottom = newRect.Bottom
```
---
### SResource
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| --------------------------------------------------------------------------------------------------------------- |
| string [**Name** ](/scripting/client-scripting-api-reference/types/sresource.md#name)`get` |
| string [**Type** ](/scripting/client-scripting-api-reference/types/sresource.md#type)`get` |
| string [**AsText** ](/scripting/client-scripting-api-reference/types/sresource.md#astext)`get` |
| SGameObject [**AsGameObject** ](/scripting/client-scripting-api-reference/types/sresource.md#asgameobject)`get` |
| SMaterial [**AsMaterial** ](/scripting/client-scripting-api-reference/types/sresource.md#asmaterial)`get` |
| float [**TextureWidth** ](/scripting/client-scripting-api-reference/types/sresource.md#texturewidth)`get` |
| float [**TextureHeight** ](/scripting/client-scripting-api-reference/types/sresource.md#textureheight)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### Name[β](#name "Direct link to Name")
string **Name** `get`
*Returns the name of the resource as entered in the scripting runtime*
* Lua
```lua
ResourceName = Space.Resources[1].Name
```
* Lua
```lua
--the below script will search through the Scripting Runtime's resources
--and return the first instance of an Animation Clip
--[You need to add a few resources to the scripting runtime and make one of them an animation]
resources = Space.Resources
for i = 1, #resources do
if resources[i].Type == "AnimationClip" then
Space.Log("Resource #".. i .. " is an Animation Clip. The resource name is: " .. resources[i].Name)
break
end
end
```
##### Type[β](#type "Direct link to Type")
string **Type** `get`
*Returns the type of the resource as a string*
* Lua
```lua
ResourceType = Space.GetResource("Resource Name").Type
```
* Lua
```lua
--the below script will search through the Scripting Runtime's resources
--and return the first instance of an Animation Clip
--[You need to add a few resources to the scripting runtime and make one of them an animation]
resources = Space.Resources
for i = 1, #resources do
if resources[i].Type == "AnimationClip" then
Space.Log("Resource #".. i .. " is an Animation Clip. The resource name is: " .. resources[i].Name)
break
end
end
```
##### AsText[β](#astext "Direct link to AsText")
string **AsText** `get`
*Converts the resource's type from SResource type to string*
* Lua
```lua
Text = Space.GetResource("Resource Name").AsText
```
##### AsGameObject[β](#asgameobject "Direct link to AsGameObject")
[SGameObject](/scripting/client-scripting-api-reference/types/sgameobject.md) **AsGameObject** `get`
*Property Description*
* Lua
```lua
GameObject = Space.GetResource("Resource Name").AsGameObject
```
##### AsMaterial[β](#asmaterial "Direct link to AsMaterial")
[SMaterial](/scripting/client-scripting-api-reference/types/smaterial.md) **AsMaterial** `get`
*Converts the resource's type from SResource to SMaterial*
* Lua
```lua
Material = Space.GetResource("Resource Name").AsMaterial
```
##### TextureWidth[β](#texturewidth "Direct link to TextureWidth")
float **TextureWidth** `get`
*Returns the Texture Width of this resource*
* Lua
```lua
TextureWidth = Space.GetResource("Resource Name").TextureWidth
```
##### TextureHeight[β](#textureheight "Direct link to TextureHeight")
float **TextureHeight** `get`
*Returns the Texture Height of this resource*
* Lua
```lua
TextureHeight = Space.GetResource("Resource Name").TextureHeight
```
---
### SScore
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ----------------------------------------------------------------------------------------------- |
| int [**Rank** ](/scripting/client-scripting-api-reference/types/sscore.md#rank)`get` |
| long [**Score** ](/scripting/client-scripting-api-reference/types/sscore.md#score)`get` |
| string [**Username** ](/scripting/client-scripting-api-reference/types/sscore.md#username)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### Rank[β](#rank "Direct link to Rank")
int **Rank** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Score[β](#score "Direct link to Score")
long **Score** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Username[β](#username "Direct link to Username")
string **Username** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
---
### SScoreRank
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| -------------------------------------------------------------------------------------------------------------------------- |
| int [**Level** ](/scripting/client-scripting-api-reference/types/sscorerank.md#level)`get` |
| SScore\[] [**AllTimeLeaderboard** ](/scripting/client-scripting-api-reference/types/sscorerank.md#alltimeleaderboard)`get` |
| SScore\[] [**DailyLeaderboard** ](/scripting/client-scripting-api-reference/types/sscorerank.md#dailyleaderboard)`get` |
| SScore [**AllTimePlayerRecord** ](/scripting/client-scripting-api-reference/types/sscorerank.md#alltimeplayerrecord)`get` |
| SScore [**DailyPlayerRecord** ](/scripting/client-scripting-api-reference/types/sscorerank.md#dailyplayerrecord)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### Level[β](#level "Direct link to Level")
int **Level** `get`
*The level of current activity.*
* Lua
```lua
Space.Activity.FinishActivity(99956,100,0,function (rank)
Space.Log(rank.Level)
end)
```
##### AllTimeLeaderboard[β](#alltimeleaderboard "Direct link to AllTimeLeaderboard")
SScore\[] **AllTimeLeaderboard** `get`
*The AllTimeLeaderboard of current activity.*
* Lua
```lua
Space.Activity.FinishActivity(99956,100,0,function (rank)
local leaderBoard=rank.AllTimeLeaderboard
for i=1,#leaderBoard do
Space.Log(leaderBoard[i].Rank)
Space.Log(leaderBoard[i].Score)
Space.Log(leaderBoard[i].Username)
end
end)
```
##### DailyLeaderboard[β](#dailyleaderboard "Direct link to DailyLeaderboard")
SScore\[] **DailyLeaderboard** `get`
*The daily Leaderboard of current activity.*
* Lua
```lua
Space.Activity.FinishActivity(99956,100,0,function (rank)
local leaderBoard=rank.DailyLeaderboard
for i=1,#leaderBoard do
Space.Log(leaderBoard[i].Rank)
Space.Log(leaderBoard[i].Score)
Space.Log(leaderBoard[i].Username)
end
end)
```
##### AllTimePlayerRecord[β](#alltimeplayerrecord "Direct link to AllTimePlayerRecord")
SScore **AllTimePlayerRecord** `get`
*The AllTimePlayerRecord of current activity.*
* Lua
```lua
Space.Activity.FinishActivity(99956,100,0,function (rank)
local record=rank.AllTimePlayerRecord
Space.Log(record.Rank)
Space.Log(record.Score)
Space.Log(record.Username)
end)
```
##### DailyPlayerRecord[β](#dailyplayerrecord "Direct link to DailyPlayerRecord")
SScore **DailyPlayerRecord** `get`
*The daily player records of current activity.*
* Lua
```lua
Space.Activity.FinishActivity(99956,100,0,function (rank)
local record=rank.DailyPlayerRecord
Space.Log(record.Rank)
Space.Log(record.Score)
Space.Log(record.Username)
end)
```
---
### SSocialMedia
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property Name |
| --------------------------------------------------------------------------------------------------- |
| string [**Type** ](/scripting/client-scripting-api-reference/types/ssocialmedia.md#type)`get` |
| string [**MediaID** ](/scripting/client-scripting-api-reference/types/ssocialmedia.md#mediaid)`get` |
| string [**Url** ](/scripting/client-scripting-api-reference/types/ssocialmedia.md#url)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### Type[β](#type "Direct link to Type")
string **Type** `get`
*Property Description*
* Lua
```lua
tableOfSSocialMedia = Space.Profile.ActivePlayerProfile.SocialMediaProfiles
profileType = tableOfSSocialMedia[1].Type
```
##### MediaID[β](#mediaid "Direct link to MediaID")
string **MediaID** `get`
*Property Description*
* Lua
```lua
tableOfSSocialMedia = Space.Profile.ActivePlayerProfile.SocialMediaProfiles
profileID = tableOfSSocialMedia[1].MediaID
```
##### Url[β](#url "Direct link to Url")
string **Url** `get`
*Property Description*
* Lua
```lua
tableOfSSocialMedia = Space.Profile.ActivePlayerProfile.SocialMediaProfiles
profileType = tableOfSSocialMedia[1].Url
```
---
### SString
#### Index[β](#index "Direct link to Index")
##### Static Functions Index[β](#static-functions-index "Direct link to Static Functions Index")
| Function Name |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| static string [**MD5** ](/scripting/client-scripting-api-reference/types/sstring.md#md5)(string input) |
| static string [**SHA1** ](/scripting/client-scripting-api-reference/types/sstring.md#sha1)(string input) |
| static string [**Replace** ](/scripting/client-scripting-api-reference/types/sstring.md#replace)(string old, string pattern, string replace) |
| static string [**GenerateGUID** ](/scripting/client-scripting-api-reference/types/sstring.md#generateguid)() |
| static string [**Base64Encode** ](sstring#base64encode)(string input)
static string [**Base64Encode** ](sstring#base64encode)(byte\[] input) |
| static string [**Base64Decode** ](/scripting/client-scripting-api-reference/types/sstring.md#base64decode)(string input) |
| static byte\[] [**GetBytes** ](/scripting/client-scripting-api-reference/types/sstring.md#getbytes)(string input) |
| static string [**GetString** ](/scripting/client-scripting-api-reference/types/sstring.md#getstring)(byte\[] bytes) |
| static string [**EncodeURL** ](/scripting/client-scripting-api-reference/types/sstring.md#encodeurl)(string input) |
| static string [**DecodeURL** ](/scripting/client-scripting-api-reference/types/sstring.md#decodeurl)(string input) |
| static string [**RegexMatchResult** ](/scripting/client-scripting-api-reference/types/sstring.md#regexmatchresult)(string input, string pattern, string replacement) |
#### Static Functions[β](#static-functions "Direct link to Static Functions")
##### MD5[β](#md5 "Direct link to MD5")
static string **MD5** (string input)
*Calculates the MD5Sum of input and returns the result as a hexadecimal string*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
md5 = Space.String.MD5('AString')
```
##### SHA1[β](#sha1 "Direct link to SHA1")
static string **SHA1** (string input)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
sha1 = Space.String.SHA1('AString')
```
##### Replace[β](#replace "Direct link to Replace")
static string **Replace** (string old, string pattern, string replace)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
replaced = Space.String.Replace('AString', 'APattern', 'AReplace')
```
##### GenerateGUID[β](#generateguid "Direct link to GenerateGUID")
static string **GenerateGUID** ()
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
guid = Space.String.GenerateGUID()
```
##### Base64Encode[β](#base64encode "Direct link to Base64Encode")
static string **Base64Encode** (string input)
*Converts input to Base64 and returns the result*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
baseEncodeByte = Space.String.Base64Encode{117, 116, 32, 116, 100, 101})
```
##### Base64Decode[β](#base64decode "Direct link to Base64Decode")
static string **Base64Decode** (string input)
*Converts input from Base64 and returns the result*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
baseDecodedStr = Space.String.Base64Decode('aW5wdXQgdG8gZW5jb2Rl')
```
##### GetBytes[β](#getbytes "Direct link to GetBytes")
static byte\[] **GetBytes** (string input)
*Converts input to bytes using UTF8 encoding*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
stringAsByteArray = Space.String.GetBytes('A String')
```
##### GetString[β](#getstring "Direct link to GetString")
static string **GetString** (byte\[] bytes)
*Converts input to a UTF8 string*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
ByteArrayAsString = Space.String.GetString({115, 111, 109, 101, 32})
```
##### EncodeURL[β](#encodeurl "Direct link to EncodeURL")
static string **EncodeURL** (string input)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
encodedURL = Space.String.EncodeURL('A String')
```
##### DecodeURL[β](#decodeurl "Direct link to DecodeURL")
static string **DecodeURL** (string input)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
decodedURL = Space.String.DecodeURL('A String')
```
##### RegexMatchResult[β](#regexmatchresult "Direct link to RegexMatchResult")
static string **RegexMatchResult** (string input, string pattern, string replacement)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Math.RegexMatchResult('astring', 'astring','astring')
```
---
### SSubRegion
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| --------------------------------------------------------------------------------------------------------------- |
| int [**RegionID** ](/scripting/client-scripting-api-reference/types/ssubregion.md#regionid)`get` |
| int [**Count** ](/scripting/client-scripting-api-reference/types/ssubregion.md#count)`get` |
| string [**ServerLocation** ](/scripting/client-scripting-api-reference/types/ssubregion.md#serverlocation)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### RegionID[β](#regionid "Direct link to RegionID")
int **RegionID** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Count[β](#count "Direct link to Count")
int **Count** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### ServerLocation[β](#serverlocation "Direct link to ServerLocation")
string **ServerLocation** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
---
### STrackInfo
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ----------------------------------------------------------------------------------------------- |
| string [**Title** ](/scripting/client-scripting-api-reference/types/strackinfo.md#title)`get` |
| string [**Artist** ](/scripting/client-scripting-api-reference/types/strackinfo.md#artist)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### Title[β](#title "Direct link to Title")
string **Title** `get`
*Title of the track*
* Lua
```lua
otc = function(trackInfo)
Space.Log(trackInfo.Title)
end
Space.Host.ExecutingObject.Radio.OnTrackChange(otc)
```
##### Artist[β](#artist "Direct link to Artist")
string **Artist** `get`
*Artist of the track*
* Lua
```lua
otc = function(trackInfo)
Space.Log(trackInfo.Artist)
end
Space.Host.ExecutingObject.Radio.OnTrackChange(otc)
```
---
### STuneIn
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ------------------------------------------------------------------------------------------------------ |
| string [**Base** ](/scripting/client-scripting-api-reference/types/stunein.md#base)`get` `set` |
| string [**Basem3u** ](/scripting/client-scripting-api-reference/types/stunein.md#basem3u)`get` `set` |
| string [**Basexspf** ](/scripting/client-scripting-api-reference/types/stunein.md#basexspf)`get` `set` |
#### Properties[β](#properties "Direct link to Properties")
##### Base[β](#base "Direct link to Base")
string **Base** `get` `set`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Basem3u[β](#basem3u "Direct link to Basem3u")
string **Basem3u** `get` `set`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Basexspf[β](#basexspf "Direct link to Basexspf")
string **Basexspf** `get` `set`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
---
### SUIRaycastResult
#### Index[β](#index "Direct link to Index")
##### Functions Index[β](#functions-index "Direct link to Functions Index")
| Function |
| ------------------------------------------------------------------------------------------------------ |
| void [**Clear** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#clear)() |
| string [**ToString** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#tostring)() |
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ---------------------------------------------------------------------------------------------------------------------- |
| float [**Distance** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#distance)`get` |
| float [**Index** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#index)`get` |
| int [**Depth** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#depth)`get` |
| int [**SortingLayer** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#sortinglayer)`get` |
| int [**SortingOrder** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#sortingorder)`get` |
| SVector [**WorldPosition** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#worldposition)`get` |
| SVector [**WorldNormal** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#worldnormal)`get` |
| SVector [**ScreenPosition** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#screenposition)`get` |
| SGameObject [**GameObject** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#gameobject)`get` |
| bool [**IsValid** ](/scripting/client-scripting-api-reference/types/suiraycastresult.md#isvalid)`get` |
#### Functions[β](#functions "Direct link to Functions")
##### Clear[β](#clear "Direct link to Clear")
void **Clear** ()
*Reset all the parameters of this RaycastResult*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Result = Space.UI.Raycast()
Result.Clear()
```
##### ToString[β](#tostring "Direct link to ToString")
string **ToString** ()
*Converts all the properties of this UIRaycastResult into a string*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Result = Space.UI.Raycast().ToString()
```
* Lua
```lua
--This script will update a UIText element with the result of a UIRaycast whenever...
--the player clicks on a Sinespace UI element
thisObject = Space.Host.ExecutingObject
uiText = Space.Host.GetReference("text").UIText --Add this object with UIText component as reference in Scripting Runtime
OnUpdate = function()
if Space.Input.GetMouseDown(0) == true then
result = Space.UI.Raycast()
if result.IsValid then
uiText = result.ToString()
end
end
end
thisObject.OnUpdate(OnUpdate)
```
#### Properties[β](#properties "Direct link to Properties")
##### Distance[β](#distance "Direct link to Distance")
float **Distance** `get`
*Returns the distance of the Raycast result*
* Lua
```lua
Result = Distance = Space.UI.Raycast().Distance
```
* Lua
```lua
--This script will update a UIText element with the Distance of the UIRaycast whenever
--the player clicks on a Sinespace UI element
thisObject = Space.Host.ExecutingObject
uiText = Space.Host.GetReference("text").UIText --Add this object with UIText component as reference in Scripting Runtime
OnUpdate = function()
if Space.Input.GetMouseDown(0) == true then
result = Space.UI.Raycast()
if result.IsValid then
uiText = result.Distance
end
end
end
thisObject.OnUpdate(OnUpdate)
```
##### Index[β](#index-1 "Direct link to Index")
float **Index** `get`
*Returns the Index of the Raycast result*
* Lua
```lua
Index= Space.UI.Raycast().Index
```
* Lua
```lua
--This script will update a UIText element with the Index of the UIRaycast whenever
--the player clicks on a Sinespace UI element
thisObject = Space.Host.ExecutingObject
uiText = Space.Host.GetReference("text").UIText --Add this object with UIText component as reference in Scripting Runtime
OnUpdate = function()
if Space.Input.GetMouseDown(0) == true then
result = Space.UI.Raycast()
if result.IsValid then
uiText = result.Index
end
end
end
thisObject.OnUpdate(OnUpdate)
```
##### Depth[β](#depth "Direct link to Depth")
int **Depth** `get`
*Returns the Depth of the Raycast result*
* Lua
```lua
Depth= Space.UI.Raycast().Depth
```
* Lua
```lua
--This script will update a UIText element with the Depth of the UIRaycast whenever
--the player clicks on a Sinespace UI element
thisObject = Space.Host.ExecutingObject
uiText = Space.Host.GetReference("text").UIText --Add this object with UIText component as reference in Scripting Runtime
OnUpdate = function()
if Space.Input.GetMouseDown(0) == true then
result = Space.UI.Raycast()
if result.IsValid then
uiText = result.Depth
end
end
end
thisObject.OnUpdate(OnUpdate)
```
##### SortingLayer[β](#sortinglayer "Direct link to SortingLayer")
int **SortingLayer** `get`
*Returns the Sorting Layer of the Raycast result*
* Lua
```lua
SortingLayer= Space.UI.Raycast().SortingLayer
```
* Lua
```lua
--This script will update a UIText element with the Sorting Layer of the UIRaycast whenever
--the player clicks on a Sinespace UI element
thisObject = Space.Host.ExecutingObject
uiText = Space.Host.GetReference("text").UIText --Add this object with UIText component as reference in Scripting Runtime
OnUpdate = function()
if Space.Input.GetMouseDown(0) == true then
result = Space.UI.Raycast()
if result.IsValid then
uiText = result.SortingLayer
end
end
end
thisObject.OnUpdate(OnUpdate)
```
##### SortingOrder[β](#sortingorder "Direct link to SortingOrder")
int **SortingOrder** `get`
*Returns the Sorting Order of the Raycast result*
* Lua
```lua
SortingOrder= Space.UI.Raycast().SortingOrder
```
* Lua
```lua
--This script will update a UIText element with the Sorting Order of the UIRaycast whenever
--the player clicks on a Sinespace UI element
thisObject = Space.Host.ExecutingObject
uiText = Space.Host.GetReference("text").UIText --Add this object with UIText component as reference in Scripting Runtime
OnUpdate = function()
if Space.Input.GetMouseDown(0) == true then
result = Space.UI.Raycast()
if result.IsValid then
uiText = result.SortingOrder
end
end
end
thisObject.OnUpdate(OnUpdate)
```
##### WorldPosition[β](#worldposition "Direct link to WorldPosition")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **WorldPosition** `get`
*Returns the World Position vector of the Raycast result*
* Lua
```lua
WorldPosition= Space.UI.Raycast().WorldPosition
```
* Lua
```lua
--This script will update a UIText element with the World Position of the UIRaycast whenever
--the player clicks on a Sinespace UI element
thisObject = Space.Host.ExecutingObject
uiText = Space.Host.GetReference("text").UIText --Add this object with UIText component as reference in Scripting Runtime
OnUpdate = function()
if Space.Input.GetMouseDown(0) == true then
result = Space.UI.Raycast()
if result.IsValid then
uiText = result.WorldPosition
end
end
end
thisObject.OnUpdate(OnUpdate)
```
##### WorldNormal[β](#worldnormal "Direct link to WorldNormal")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **WorldNormal** `get`
*Returns the World Normal vector of the Raycast result*
* Lua
```lua
WorldNormal= Space.UI.Raycast().WorldNormal
```
* Lua
```lua
--This script will update a UIText element with the World Normal of the UIRaycast whenever
--the player clicks on a Sinespace UI element
thisObject = Space.Host.ExecutingObject
uiText = Space.Host.GetReference("text").UIText --Add this object with UIText component as reference in Scripting Runtime
OnUpdate = function()
if Space.Input.GetMouseDown(0) == true then
result = Space.UI.Raycast()
if result.IsValid then
uiText = result.WorldNormal
end
end
end
thisObject.OnUpdate(OnUpdate)
```
##### ScreenPosition[β](#screenposition "Direct link to ScreenPosition")
[SVector](/scripting/client-scripting-api-reference/types/svector.md) **ScreenPosition** `get`
*Returns the Screen Position vector of the Raycast result*
* Lua
```lua
ScreenPosition= Space.UI.Raycast().ScreenPosition
```
* Lua
```lua
--This script will update a UIText element with the Screen Position of the UIRaycast whenever
--the player clicks on a Sinespace UI element
thisObject = Space.Host.ExecutingObject
uiText = Space.Host.GetReference("text").UIText --Add this object with UIText component as reference in Scripting Runtime
OnUpdate = function()
if Space.Input.GetMouseDown(0) == true then
result = Space.UI.Raycast()
if result.IsValid then
uiText = result.ScreenPosition
end
end
end
thisObject.OnUpdate(OnUpdate)
```
##### GameObject[β](#gameobject "Direct link to GameObject")
[SGameObject](/scripting/client-scripting-api-reference/types/sgameobject.md) **GameObject** `get`
*Returns a reference to the GameObject of the Raycast result*
* Lua
```lua
GameObject= Space.UI.Raycast().GameObject
```
* Lua
```lua
--This script will update a UIText element with the name of the UIRaycast
--by accesing it's GameObject whenever the player clicks on a Sinespace UI element
thisObject = Space.Host.ExecutingObject
uiText = Space.Host.GetReference("text").UIText --Add this object with UIText component as reference in Scripting Runtime
OnUpdate = function()
if Space.Input.GetMouseDown(0) == true then
result = Space.UI.Raycast()
if result.IsValid then
uiText = result.GameObject.Name
end
end
end
thisObject.OnUpdate(OnUpdate)
```
##### IsValid[β](#isvalid "Direct link to IsValid")
bool **IsValid** `get`
*Returns whether the Raycast hit a valid UI Raycast target. This will be true if the Raycast hits an element on Sinespace's UI*
* Lua
```lua
IsValid= Space.UI.Raycast().IsValid
```
* Lua
```lua
--This script will check if Raycast result is valid
--and update a UIText element with the result of a UIRaycast whenever
--the player clicks on a Sinespace UI element
thisObject = Space.Host.ExecutingObject
uiText = Space.Host.GetReference("text").UIText --Add this object with UIText component as reference in Scripting Runtime
OnUpdate = function()
if Space.Input.GetMouseDown(0) == true then
result = Space.UI.Raycast()
if result.IsValid then
uiText = result.ToString()
end
end
end
thisObject.OnUpdate(OnUpdate)
```
---
### SUserProfile
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property Name |
| ------------------------------------------------------------------------------------------------------------------------------------ |
| string [**UserName** ](/scripting/client-scripting-api-reference/types/suserprofile.md#username)`get` |
| string [**Title** ](/scripting/client-scripting-api-reference/types/suserprofile.md#title)`get` |
| string [**RealName** ](/scripting/client-scripting-api-reference/types/suserprofile.md#realname)`get` |
| string [**Gender** ](/scripting/client-scripting-api-reference/types/suserprofile.md#gender)`get` |
| string [**Since** ](/scripting/client-scripting-api-reference/types/suserprofile.md#since)`get` |
| string [**Country** ](/scripting/client-scripting-api-reference/types/suserprofile.md#country)`get` |
| string [**City** ](/scripting/client-scripting-api-reference/types/suserprofile.md#city)`get` |
| int [**SocialGold** ](/scripting/client-scripting-api-reference/types/suserprofile.md#socialgold)`get` |
| int [**SocialSilver** ](/scripting/client-scripting-api-reference/types/suserprofile.md#socialsilver)`get` |
| int [**SocialFlower** ](/scripting/client-scripting-api-reference/types/suserprofile.md#socialflower)`get` |
| string [**Interests** ](/scripting/client-scripting-api-reference/types/suserprofile.md#interests)`get` |
| string [**About** ](/scripting/client-scripting-api-reference/types/suserprofile.md#about)`get` |
| SSocialMedia\[] [**SocialMediaProfiles** ](/scripting/client-scripting-api-reference/types/suserprofile.md#socialmediaprofiles)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### UserName[β](#username "Direct link to UserName")
string **UserName** `get`
*Get player profile's Username*
* Lua
```lua
userName = Space.Profile.ActivePlayerProfile.Username
```
##### Title[β](#title "Direct link to Title")
string **Title** `get`
*Get player profile's Title*
* Lua
```lua
userTitle = Space.Profile.ActivePlayerProfile.Title
```
##### RealName[β](#realname "Direct link to RealName")
string **RealName** `get`
*Get player profile's Real Name*
* Lua
```lua
userRealName = Space.Profile.ActivePlayerProfile.RealName
```
##### Gender[β](#gender "Direct link to Gender")
string **Gender** `get`
*Get player profile's Gender*
* Lua
```lua
userGender = Space.Profile.ActivePlayerProfile.Gender
```
##### Since[β](#since "Direct link to Since")
string **Since** `get`
*Get player profile's Since*
* Lua
```lua
userSince = Space.Profile.ActivePlayerProfile.Since
```
##### Country[β](#country "Direct link to Country")
string **Country** `get`
*Get player profile's Country*
* Lua
```lua
userCountry = Space.Profile.ActivePlayerProfile.Country
```
##### City[β](#city "Direct link to City")
string **City** `get`
*Get player profile's City*
* Lua
```lua
userCity = Space.Profile.ActivePlayerProfile.City
```
##### SocialGold[β](#socialgold "Direct link to SocialGold")
int **SocialGold** `get`
*Get player profile's Gold Badge count*
* Lua
```lua
userSocialGold = Space.Profile.ActivePlayerProfile.SocialGold
```
##### SocialSilver[β](#socialsilver "Direct link to SocialSilver")
int **SocialSilver** `get`
*Get player profile's Silver Badge count*
* Lua
```lua
userSocialSilver = Space.Profile.ActivePlayerProfile.SocialSilver
```
##### SocialFlower[β](#socialflower "Direct link to SocialFlower")
int **SocialFlower** `get`
*Get player profile's Flower count*
* Lua
```lua
userSocialFlower = Space.Profile.ActivePlayerProfile.SocialFlower
```
##### Interests[β](#interests "Direct link to Interests")
string **Interests** `get`
*Get player profile's Interests*
* Lua
```lua
userInterests = Space.Profile.ActivePlayerProfile.Interests
```
##### About[β](#about "Direct link to About")
string **About** `get`
*Get player profile's About*
* Lua
```lua
userAbout = Space.Profile.ActivePlayerProfile.About
```
##### SocialMediaProfiles[β](#socialmediaprofiles "Direct link to SocialMediaProfiles")
[SSocialMedia](/scripting/client-scripting-api-reference/types/ssocialmedia.md)\[] **SocialMediaProfiles** `get`
*Get player profile's Social Media Profiles*
* Lua
```lua
tableOfSSocialMedia = Space.Profile.ActivePlayerProfile.SocialMediaProfiles
```
---
### SUserRegions
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ------------------------------------------------------------------------------------------------------------------------------- |
| int [**SubscriptionTier** ](/scripting/client-scripting-api-reference/types/suserregions.md#subscriptiontier)`get` |
| int [**NumberOfRegions** ](/scripting/client-scripting-api-reference/types/suserregions.md#numberofregions)`get` |
| int [**UsersPerRegion** ](/scripting/client-scripting-api-reference/types/suserregions.md#usersperregion)`get` |
| int [**FileSize** ](/scripting/client-scripting-api-reference/types/suserregions.md#filesize)`get` |
| string [**SubscriptionName** ](/scripting/client-scripting-api-reference/types/suserregions.md#subscriptionname)`get` |
| SPublicRegion\[] [**AvailableRegions** ](/scripting/client-scripting-api-reference/types/suserregions.md#availableregions)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### SubscriptionTier[β](#subscriptiontier "Direct link to SubscriptionTier")
int **SubscriptionTier** `get`
*The subscription tier indicates which type of premium memberhsip the player has. (As found in "Region" window)*
* Lua
```lua
--Make's a UIText show this User's Regions' current Subscription Tier
textObject = Space.Host.GetReference("TheTextReference") --add to References section in Scripting Runtime
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.SubscriptionTier
text.UIText.Text = r
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### NumberOfRegions[β](#numberofregions "Direct link to NumberOfRegions")
int **NumberOfRegions** `get`
*The number of regions the player has. (As found in "Region" window)*
* Lua
```lua
--Make's a UIText show this User's Regions' current NumberOfRegions
textObject = Space.Host.GetReference("TheTextReference") --add to References section in Scripting Runtime
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.NumberOfRegions
text.UIText.Text = r
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### UsersPerRegion[β](#usersperregion "Direct link to UsersPerRegion")
int **UsersPerRegion** `get`
*The max number of users allowed per region. ("Concurrency" as found in "Region" window).*
* Lua
```lua
--Make's a UIText show this User's Regions' current UsersPerRegion
textObject = Space.Host.GetReference("TheTextReference") --add to References section in Scripting Runtime
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.UsersPerRegion
text.UIText.Text = r
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### FileSize[β](#filesize "Direct link to FileSize")
int **FileSize** `get`
*The maximum MB size the player's regions can be. ("Max Region SizE" in the "Region" window)*
* Lua
```lua
--Make's a UIText show this User's Regions' current FileSize
textObject = Space.Host.GetReference("TheTextReference") --add to References section in Scripting Runtime
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.FileSize
text.UIText.Text = r
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### SubscriptionName[β](#subscriptionname "Direct link to SubscriptionName")
string **SubscriptionName** `get`
*The name of the current player's premium subscription (as found in "Region" window)*
* Lua
```lua
--Make's a UIText show this User's Regions' current SubscriptionName
textObject = Space.Host.GetReference("TheTextReference") --add to References section in Scripting Runtime
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.SubscriptionName
text.UIText.Text = r
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
##### AvailableRegions[β](#availableregions "Direct link to AvailableRegions")
[SPublicRegion](/scripting/client-scripting-api-reference/types/spublicregion.md)\[] **AvailableRegions** `get`
*Returns an array of SPublicRegion which is a group of data for each of the user's available regions.*
* Lua
```lua
--Make's a UIText show the Name of the user's first available region
textObject = Space.Host.GetReference("TheTextReference")
function GetUserRegionsComplete(SUserRegions)
local r = SUserRegions.AvailableRegions[1]
textObject.UIText.Text = r.Name
end
Space.Grid.GetEnabledUserRegions(GetUserRegionsComplete)
```
---
### SVector
#### Index[β](#index "Direct link to Index")
##### Functions Index[β](#functions-index "Direct link to Functions Index")
| Function |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SVector [**Add** ](svector#add)(SVector other)
SVector [**Add** ](svector#add)(float other) |
| SVector [**Scale** ](svector#scale)(SVector other)
SVector [**Scale** ](svector#scale)(float other) |
| SVector [**Divide** ](svector#divide)(SVector other)
SVector [**Divide** ](svector#divide)(float other) |
| float [**Distance** ](/scripting/client-scripting-api-reference/types/svector.md#distance)(SVector other) |
| float [**SquareDistance** ](/scripting/client-scripting-api-reference/types/svector.md#squaredistance)(SVector other) |
| bool [**InRange** ](/scripting/client-scripting-api-reference/types/svector.md#inrange)(SVector other, float range) |
| SVector [**Cross** ](/scripting/client-scripting-api-reference/types/svector.md#cross)(SVector other) |
| SVector [**Lerp** ](/scripting/client-scripting-api-reference/types/svector.md#lerp)(SVector other, float t) |
| SVector [**Slerp** ](/scripting/client-scripting-api-reference/types/svector.md#slerp)(SVector other, float t) |
| SVector [**MoveTowards** ](/scripting/client-scripting-api-reference/types/svector.md#movetowards)(SVector other, float maxDistance) |
| float [**Dot** ](/scripting/client-scripting-api-reference/types/svector.md#dot)(SVector other) |
| bool [**Equals** ](/scripting/client-scripting-api-reference/types/svector.md#equals)(SVector other) |
| string [**ToString** ](/scripting/client-scripting-api-reference/types/svector.md#tostring)() |
| |
| **Static Functions** |
| static SVector [**New** ](/scripting/client-scripting-api-reference/types/svector.md#new)(float x, float y, float z) |
| static SVector [**operator**](svector#operator+)**+** (SVector a, SVector b)
static SVector [**operator**](svector#operator+)**+** (SVector a, float b) |
| static SVector [**operator**](svector#operator)**-** (SVector a, SVector b)
static SVector [**operator**](svector#operator)**-** (SVector a, float b) |
| static SVector [**operator**](svector#operator-1)\* (SVector a, SVector b)
static SVector [**operator**](svector#operator-1)\* (SVector a, float b) |
| static SVector [**operator**](svector#operator-2)**/** (SVector a, SVector b)
static SVector [**operator**](svector#operator-2)**/** (SVector a, float b) |
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| -------------------------------------------------------------------------------------------------------- |
| float [**X**](/scripting/client-scripting-api-reference/types/svector.md#x) `get` `set` |
| float [**Y**](/scripting/client-scripting-api-reference/types/svector.md#y) `get` `set` |
| float [**Z**](/scripting/client-scripting-api-reference/types/svector.md#z) `get` `set` |
| float [**Magnitude** ](/scripting/client-scripting-api-reference/types/svector.md#magnitude)`get` |
| SVector [**Normalised** ](/scripting/client-scripting-api-reference/types/svector.md#normalised)`get` |
| |
| **Static Properties** |
| static SVector [**Up**](/scripting/client-scripting-api-reference/types/svector.md#up) `get` |
| static SVector [**Down** ](/scripting/client-scripting-api-reference/types/svector.md#down)`get` |
| static SVector [**Left** ](/scripting/client-scripting-api-reference/types/svector.md#left)`get` |
| static SVector [**Right** ](/scripting/client-scripting-api-reference/types/svector.md#right)`get` |
| static SVector [**Forward** ](/scripting/client-scripting-api-reference/types/svector.md#forward)`get` |
| static SVector [**Back** ](/scripting/client-scripting-api-reference/types/svector.md#back)`get` |
| static SVector [**Zero** ](/scripting/client-scripting-api-reference/types/svector.md#zero)`get` |
| static SVector [**One** ](/scripting/client-scripting-api-reference/types/svector.md#one)`get` |
| static SVector [**MaxValue** ](/scripting/client-scripting-api-reference/types/svector.md#maxvalue)`get` |
| static SVector [**MinValue** ](/scripting/client-scripting-api-reference/types/svector.md#minvalue)`get` |
#### Functions[β](#functions "Direct link to Functions")
##### Add[β](#add "Direct link to Add")
SVector **Add** (SVector other)
SVector **Add** (float other)
*Adds this Vector*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local vector = Vector.New(0, 10, 0);
local vectorOther = Vector.New(40, 50, 6);
Space.Log(vector.Add(vectorOther));
-- prints [40, 60, 6]
Space.Log(vector + vectorOther);
-- prints [40, 60, 6]
```
* Lua
```lua
local vectorB = Vector.New(0, 10, 0);
Space.Log(vectorB.Add(5));
-- prints [5, 15, 5]
```
##### Scale[β](#scale "Direct link to Scale")
SVector **Scale** (SVector other)
SVector **Scale** (float other)
*Multiplies this Vector*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local vector = Vector.New(0, 10, 0);
local vectorOther = Vector.New(2, 5, 4);
Space.Log(vector.Scale(vectorOther));
-- prints [0, 50, 0]
Space.Log(vector * vectorOther);
-- prints [0, 50, 0]
```
* Lua
```lua
local vector = Vector.New(0, 10, 0);
Space.Log(vector.Scale(5));
-- prints [0, 50, 0]
Space.Log(vector * 5);
-- prints [0, 50, 0]
```
##### Divide[β](#divide "Direct link to Divide")
SVector **Divide** (SVector other)
SVector **Divide** (float other)
*Divides this Vector*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local vector = Vector.New(10, 10, 10);
local vectorOther = Vector.New(2, 2, 2);
Space.Log(vector.Divide(vectorOther));
-- prints [5, 5, 5]
Space.Log(vector / vectorOther);
-- prints [5, 5, 5]
```
* Lua
```lua
local vector = Vector.New(10, 10, 10);
Space.Log(vector.Divide(2));
-- prints [5, 5, 5]
Space.Log(vector / 2);
-- prints [5, 5, 5]
```
##### Distance[β](#distance "Direct link to Distance")
float **Distance** (SVector other)
*Returns the distance between this vector and other in meters*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local vector = Vector.New(3, 3, 3.5);
local vectorOther = Vector.New(2, 2, 2);
Space.Log(vector.Distance(vectorOther));
-- prints 2.06155276298523
```
* Lua
```lua
--the below script will change the objects color to green if you are near the object
--and change color to red if you are far from the object
thisGameObject = Space.Host.ExecutingObject
function OnUpdate()
positionAvatar = Space.Scene.PlayerAvatar.GameObject.WorldPosition
positionObject = thisGameObject.WorldPosition
if positionAvatar.Distance(positionObject) < 5 then
thisGameObject.Renderer.Material.SetColor("_Color",0,1,0,1)
else
thisGameObject.Renderer.Material.SetColor("_Color",1,0,0,1)
end
end
thisGameObject.OnUpdate(OnUpdate)
```
##### SquareDistance[β](#squaredistance "Direct link to SquareDistance")
float **SquareDistance** (SVector other)
*Returns the square of the distance between this vector and other in meters, considerably faster than distance()*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local vector = Vector.New(3, 3, 3.5);
local vectorOther = Vector.New(2, 2, 2);
Space.Log(vector.SquareDistance(vectorOther));
-- prints 4.25
```
* Lua
```lua
--the below script will change the objects color to green if you are near the object
--and change color to red if you are far from the object
thisGameObject = Space.Host.ExecutingObject
function OnUpdate()
positionAvatar = Space.Scene.PlayerAvatar.GameObject.WorldPosition
positionObject = thisGameObject.WorldPosition
if positionAvatar.SquareDistance(positionObject) < 25 then
thisGameObject.Renderer.Material.SetColor("_Color",0,1,0,1)
else
thisGameObject.Renderer.Material.SetColor("_Color",1,0,0,1)
end
end
thisGameObject.OnUpdate(OnUpdate)
```
##### InRange[β](#inrange "Direct link to InRange")
bool **InRange** (SVector other, float range)
*Returns if other is within range meters of this vector, inclusive*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local vector = Vector.New(370, 30, 0);
local vectorOther = Vector.New(372, 30, 0);
Space.Log(vector.InRange(vectorOther, 2.0));
-- prints True
local vector2 = Vector.New(80, 30, 20);
local vectorOther2 = Vector.New(1, 15, 25);
Space.Log(vector2.InRange(vectorOther2, 1.0));
-- prints False
```
* Lua
```lua
--the below script will change the objects color to green if you are near the object
--and change color to red if you are far from the object
--(example: motion sensor lights)
thisGameObject = Space.Host.ExecutingObject
function OnUpdate()
positionAvatar = Space.Scene.PlayerAvatar.GameObject.WorldPosition
positionObject = thisGameObject.WorldPosition
if positionAvatar.InRange(positionObject, 5.0) then
thisGameObject.Renderer.Material.SetColor("_Color",0,1,0,1)
else
thisGameObject.Renderer.Material.SetColor("_Color",1,0,0,1)
end
end
thisGameObject.SubscribeToEvents()
thisGameObject.OnUpdate(OnUpdate)
```
##### Cross[β](#cross "Direct link to Cross")
SVector **Cross** (SVector other)
*Returns the cross product of this vector and other*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local vector = Vector.New(0, 1, 0);
local vectorOther = Vector.New(1, 0, 0);
Space.Log(vector.Cross(vectorOther));
-- prints [0, 0, -1]
```
##### Lerp[β](#lerp "Direct link to Lerp")
SVector **Lerp** (SVector other, float t)
*Linear interpolates between this and other based on factor t (0-1)*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
lerpVector = currentVector.Lerp(targetVector, 0.5)
```
* Lua
```lua
-- Lua Translation of Unity C# Documentation
--[["StartMarker" and "EndMaker" are game objects set up as endpoints.
These objects are attached to the script in the Object Reference section.
The name fields in that section should match these names for the example. --]]
local startMarker = Space.Host.GetReference("StartMarker");
local endMarker = Space.Host.GetReference("EndMarker");
local ball = Space.Host.ExecutingObject;
local speed = 1.0;
local startTime;
local journeyLength;
ball.SubscribeToEvents();
local onStartMethod = function()
startTime = Space.Time;
journeyLength = startMarker.LocalPosition.Distance(endMarker.LocalPosition);
end
-- This ball object will move from the start endpoint object to the end endpoint.
local moveBall = function()
local distCovered = (Space.Time - startTime) * speed;
local fracJourney = distCovered / journeyLength;
ball.LocalPosition = startMarker.LocalPosition.Lerp(endMarker.LocalPosition, fracJourney);
end
ball.OnStart(onStartMethod);
ball.OnUpdate(moveBall);
```
##### Slerp[β](#slerp "Direct link to Slerp")
SVector **Slerp** (SVector other, float t)
*Spherically linear interpolates between this and other based on factor t (0-1)*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
slerpVector = currentVector.Slerp(targetVector, 0.5)
```
* Lua
```lua
-- Lua Translation of Unity C# Documentation
--[["Sunrise" and "Sunset" are game objects set up as endpoints.
These objects are attached to the script in the Object Reference section.
The name fields in that section should match these names for the example. --]]
local sunrise = Space.Host.GetReference("Sunrise");
local sunset = Space.Host.GetReference("Sunset");
local ball = Space.Host.ExecutingObject;
local startTime;
local journeyTime = 1.0;
ball.SubscribeToEvents();
local onStartMethod = function()
startTime = Space.Time;
end
-- This ball object will move from the start endpoint object to the end endpoint.
local moveBall = function()
local center = (sunrise.LocalPosition + sunset.LocalPosition) * 0.5;
center = center - Vector.Up;
local riseRelCenter = sunrise.LocalPosition - center;
local setRelCenter = sunset.LocalPosition - center;
local fracComplete = (Space.Time - startTime) / journeyTime;
ball.LocalPosition = riseRelCenter.Slerp(setRelCenter, fracComplete);
ball.LocalPosition = ball.LocalPosition + center;
end
ball.OnStart(onStartMethod);
ball.OnUpdate(moveBall);
```
##### MoveTowards[β](#movetowards "Direct link to MoveTowards")
SVector **MoveTowards** (SVector other, float maxDistance)
*Moves this vector closer to other by a maximum of maxDistance units*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
newVector = currentVector.MoveTowards(targetVector)
```
* Lua
```lua
-- Lua Translation of Unity C# Documentation
--[["Target" is a game object set up as a target position.
This object is attached to the script in the Object Reference section.
The name field in that section should match this name for the example. --]]
local target = Space.Host.GetReference("Target");
local ball = Space.Host.ExecutingObject;
local speed = 1.0;Vecto
local onStartMethod = function()
startTime = Space.Time;
end
-- This ball object will move towards the target. Negative values for
-- the maxDistance parameter will push the ball away from the target.
local moveBall = function()
local step = speed * Space.DeltaTime;
ball.LocalPosition = ball.LocalPosition.MoveTowards(target.LocalPosition, step);
end
ball.OnStart(onStartMethod);
ball.OnUpdate(moveBall);
-- NOTE: If you use MoveTowards, the movement will not overshoot the target.
```
##### Dot[β](#dot "Direct link to Dot")
float **Dot** (SVector other)
*Returns the dot product between this and other (note - normalise your vectors first!*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local vectorA = Vector.New(0, 1, 0);
local vectorOtherA = Vector.New(1, 0, 0);
Space.Log(vectorA.Dot(vectorOtherA));
-- prints 0
local vectorB = Vector.New(0, 1, 0);
local vectorOtherB = Vector.New(0, 1, 0);
Space.Log(vectorB.Dot(vectorOtherB));
-- prints 1
local vectorC = Vector.New(0, 1, 0);
local vectorOtherC = Vector.New(0, -1, 0);
Space.Log(vectorC.Dot(vectorOtherC));
-- prints -1
```
##### Equals[β](#equals "Direct link to Equals")
bool **Equals** (SVector other)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
isEqual = Vector.Up.Equals( Vector.New(0,1,0) )
```
##### ToString[β](#tostring "Direct link to ToString")
string **ToString** ()
*Function Description*
* Lua
```lua
stringVector = Vector.New(0,0,0).ToString()
```
##### New[β](#new "Direct link to New")
static SVector **New** (float x, float y, float z)
*Initialises vector from three floats*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
newVector = Vector.New(0, 1, 0)
```
##### operator+[β](#operator "Direct link to operator+")
static SVector **operator+** (SVector a, SVector b)
static SVector **operator+** (SVector a, float b)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
example 1
```
##### operator-[β](#operator- "Direct link to operator-")
static SVector **operator-** (SVector a, SVector b)
static SVector **operator-** (SVector a, float b)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
example 1
```
##### operator\*[β](#operator-1 "Direct link to operator*")
static SVector **operator**\* (SVector a, SVector b)
static SVector **operator**\* (SVector a, float b)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
example 1
```
##### operator/[β](#operator-2 "Direct link to operator/")
static SVector **operator/** (SVector a, SVector b)
static SVector **operator/** (SVector a, float b)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
example 1
```
#### Properties[β](#properties "Direct link to Properties")
##### X[β](#x "Direct link to X")
float **X** `get` `set`
*X axis (red axis)*
* Lua
```lua
newVect = Vector.New(0,0,0)
newVect.X = 5.0
```
* Lua
```lua
local obj = Space.Host.ExecutingObject;
local originalPos = obj.LocalPosition;
obj.SubscribeToEvents();
local onStartMethod = function()
Space.Log(originalPos.x);
-- prints the X axis position of this object as a float
originalPos.x = 100.0;
-- assigns 100.0 value to the X axis position of this object
obj.LocalPosition = originalPos;
-- sets the the new position
end
obj.OnStart(onStartMethod);
```
##### Y[β](#y "Direct link to Y")
float **Y** `get` `set`
*Y axis (green axis)*
* Lua
```lua
newVect = Vector.New(0,0,0)
newVect.Y = 5.0
```
* Lua
```lua
local obj = Space.Host.ExecutingObject;
local originalPos = obj.LocalPosition;
obj.SubscribeToEvents();
local onStartMethod = function()
Space.Log(originalPos.y);
-- prints the Y axis position of this object as a float
originalPos.y = 100.0;
-- assigns 100.0 value to the Y axis position of this object
obj.LocalPosition = originalPos;
-- sets the the new position
end
obj.OnStart(onStartMethod);
```
##### Z[β](#z "Direct link to Z")
float **Z** `get` `set`
*Z axis (blue axis)*
* Lua
```lua
newVect = Vector.New(0,0,0)
newVect.Z = 5.0
```
* Lua
```lua
local obj = Space.Host.ExecutingObject
local originalPos = obj.LocalPosition
local onStartMethod = function()
Space.Log(originalPos.z)
-- prints the Z axis position of this object as a float
originalPos.z = 100.0
-- assigns 100.0 value to the Z axis position of this object
obj.LocalPosition = originalPos
-- sets the the new position
end
obj.OnStart(onStartMethod)
```
##### Magnitude[β](#magnitude "Direct link to Magnitude")
float **Magnitude** `get`
*Returns the magnitude of this vector*
* Lua
```lua
vector = Vector.New(1.0, 5.0, 0.0)
vectorMagnitude = vector.Magnitude
```
##### Normalised[β](#normalised "Direct link to Normalised")
SVector **Normalised** `get`
*Returns the normalised version of this vector*
* Lua
```lua
vector = Vector.New(0.0, 10.0, 0.0)
vectorNormalised = vector.Normalised
```
##### Up[β](#up "Direct link to Up")
static SVector **Up** `get`
*Equivalent of new SVector(0,1,0)*
* Lua
```lua
up = Vector.Up
```
* Lua
```lua
--this script will make clicking this object move 2 units up on the world Y axis
thisObject = Space.Host.ExecutingObject
OnClick = function()
thisObject.WorldPosition = thisObject.WorldPosition + (Vector.Up * 2)
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClick)
```
##### Down[β](#down "Direct link to Down")
static SVector **Down** `get`
*Equivalent of new SVector(0,-1,0)*
* Lua
```lua
down = Vector.Down
```
* Lua
```lua
--this script will make clicking this object move 2 units down on the world Y axis
thisObject = Space.Host.ExecutingObject
OnClick = function()
thisObject.WorldPosition = thisObject.WorldPosition + (Vector.Down * 2)
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClick)
```
##### Left[β](#left "Direct link to Left")
static SVector **Left** `get`
*Equivalent of new SVector(-1,0,0)*
* Lua
```lua
left = Vector.Left
```
* Lua
```lua
--this script will make clicking this object move 2 units left on the world X axis
thisObject = Space.Host.ExecutingObject
OnClick = function()
thisObject.WorldPosition = thisObject.WorldPosition + (Vector.Left * 2)
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClick)
```
##### Right[β](#right "Direct link to Right")
static SVector **Right** `get`
*Equivalent of new SVector(1,0,0)*
* Lua
```lua
right = Vector.Right
```
* Lua
```lua
--this script will make clicking this object move 2 units right on the world X axis
thisObject = Space.Host.ExecutingObject
OnClick = function()
thisObject.WorldPosition = thisObject.WorldPosition + (Vector.Right * 2)
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClick)
```
##### Forward[β](#forward "Direct link to Forward")
static SVector **Forward** `get`
*Equivalent of new SVector(0,0,1)*
* Lua
```lua
forward = Vector.Forward
```
* Lua
```lua
--this script will make clicking this object move 2 units Forward on the world Z axis
thisObject = Space.Host.ExecutingObject
OnClick = function()
thisObject.WorldPosition = thisObject.WorldPosition + (Vector.Forward * 2)
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClick)
```
##### Back[β](#back "Direct link to Back")
static SVector **Back** `get`
*Equivalent of new SVector(0,0,-1)*
* Lua
```lua
back = Vector.Back
```
* Lua
```lua
--this script will make clicking this object move 2 units Back on the world Z axis
thisObject = Space.Host.ExecutingObject
OnClick = function()
thisObject.WorldPosition = thisObject.WorldPosition + (Vector.Back * 2)
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClick)
```
##### Zero[β](#zero "Direct link to Zero")
static SVector **Zero** `get`
*Equivalent of new SVector(0,0,0)*
* Lua
```lua
vectorZero = Vector.Zero
```
* Lua
```lua
--clicking this object move it to the center of the region <0,0,0>
thisObject = Space.Host.ExecutingObject
OnClick = function()
thisObject.WorldPosition = Vector.Zero
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClick)
```
##### One[β](#one "Direct link to One")
static SVector **One** `get`
*Equivalent of new SVector(1,1,1)*
* Lua
```lua
vectorOne = Vector.One
```
* Lua
```lua
--clicking this object move it to the <1,1,1> coordinates of the region.
thisObject = Space.Host.ExecutingObject
OnClick = function()
thisObject.WorldPosition = Vector.One
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClick)
```
##### MaxValue[β](#maxvalue "Direct link to MaxValue")
static SVector **MaxValue** `get`
*Contains the largest possible vector* \[3.402823E+38, 3.402823E+38, 3.402823E+38]
* Lua
```lua
vectorMaxValue = Vector.MaxValue
```
##### MinValue[β](#minvalue "Direct link to MinValue")
static SVector **MinValue** `get`
*Contains the largest possible negative vector*
* Lua
```lua
vectorMinValue = Vector.MinValue
```
---
### SWebResponse
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property Name |
| ----------------------------------------------------------------------------------------------------- |
| string [**Error**](/scripting/client-scripting-api-reference/types/swebresponse.md#propertyname) |
| string [**Response**](/scripting/client-scripting-api-reference/types/swebresponse.md#propertyname-1) |
#### Properties[β](#properties "Direct link to Properties")
##### Error[β](#error "Direct link to Error")
string **Error** `get`
*Any error, will be empty or null if the request was successful*
* Lua
```lua
function ResponseFunction(responseData)
stringError = responseData.Error
end
Space.WebServices.Get('aURL', ResponseFunction)
```
##### Response[β](#response "Direct link to Response")
string **Response** `get`
*The body text of the webpage response if error is empty or null*
* Lua
```lua
function ResponseFunction(responseData)
stringResponse = responseData.Response
end
Space.WebServices.Get('aURL', ResponseFunction)
```
---
### Guides
#### [ποΈPersistence](/scripting/guides/persistence.md)
[Guide on how to script persistence in Sinespace](/scripting/guides/persistence.md)
---
### Persistence
The Sinespace API has a range of API functions that enable us to create different types of persistence. As scripters, we have to choose the type which is more suitable for the task at hand, or even mix and match. In this guide we will go through all the the different classes and functions and explain how to use them.
#### Reference[β](#reference "Direct link to Reference")
These two tables briefly explains the difference between the different types of classes and members that have persistence functionality, and we will expand even more after that.
| Class | Member | Type of persistence |
| --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| [SNetwork](../client-scripting-api-reference/network/snetwork)
(client scripting) | [SetRegionProperty](../client-scripting-api-reference/network/snetwork#setregionproperty)
[GetRegionProperty](../client-scripting-api-reference/network/snetwork#getregionproperty)
[SetShardProperty](../client-scripting-api-reference/network/snetwork#setshardproperty)
[GetShardProperty](../client-scripting-api-reference/network/snetwork#getshardproperty)
[HasShardProperties](../client-scripting-api-reference/network/snetwork#hasshardproperties) | Semi-permanent Region
Semi-permanent Region
Semi-permanent Shard
Semi-permanent Shard
Semi-permanent Shard/Region |
| [SPersistence](../client-scripting-api-reference/region/spersistence)
(client scripting) | [UpdateInfo
](../client-scripting-api-reference/region/spersistence#updateinfo)[RetrieveValue](../client-scripting-api-reference/region/spersistence#retrievevalue)
[SetValue](../client-scripting-api-reference/region/spersistence#setvalue)
[UpdateRegionInfo](../client-scripting-api-reference/region/spersistence#updateregioninfo)
[RetrieveRegionValue](../client-scripting-api-reference/region/spersistence#retrieveregionvalue)
[SetRegionValue](../client-scripting-api-reference/region/spersistence#setregionvalue) | Permanent Player
Permanent Player
Permanent Player
Permanent Region
Permanent Region
Permanent Region |
| [SShared](../client-scripting-api-reference/client/sshared)
(client scripting) | [SetSuperGlobal](../client-scripting-api-reference/client/sshared#setsuperglobal)
[GetSuperGlobal](../client-scripting-api-reference/client/sshared#getsuperglobal) | Semi-permanent Viewer
Semi-permanent Viewer |
| [SDatabase](../server-scripting-api-reference/storage/sdatabase) (server scripting) | [GetPlayerValue](../server-scripting-api-reference/storage/sdatabase#getplayervalue)
[SetPlayerValue](../server-scripting-api-reference/storage/sdatabase#setplayervalue)
[GetRegionValue](../server-scripting-api-reference/storage/sdatabase#getregionvalue)
[SetRegionValue](../server-scripting-api-reference/storage/sdatabase#setregionvalue) | Permanent Player
Permanent Player
Permanent Region
Permanent Region |
| Types of persistence | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Semi-permanent Region | Persistence will last until Region is closed (after all players leave the Region).Persistence applied region-wide (including all shards, if any are active). |
| Semi-permanent Shard | Persistence will last until Shard is closed (after all players leave the Shard).Persistence applied only to a specific Shard. |
| Semi-permanent Viewer | Persistence will last until Viewer is closed.
Persistence applied to the Viewer. |
| Permanent Player | Persistence will last permanently.
Persistence applied to specific Player. |
| Permanent Region | Persistence will last permanently.
Persistence applied to Region. |
#### What is persistence?[β](#what-is-persistence "Direct link to What is persistence?")
Sending Network Messages is cool for one off events, for example: a player waving Hello, which is relevant for only a few seconds. However, sometimes we want to make changes that are relevant for more than just a few seconds, for example: a window being opened.
If we send a Network Message to broadcast to all players that Window A is now open, when a new player enters our region, they would have missed that Network Message, and Window A would still be closed for them in their viewer.
This is why we need the ability to make certain changes to the scene **Persist**, either permanently or at least until everyone's left the region.
#### SNetwork class[β](#snetwork-class "Direct link to SNetwork class")
The SNetwork class has a variety of networking functions but has 4 functions and 1 property which are related to persistence.
* SetRegionProperty/GetRegionProperty
* SetShardProperty/GetShardProperty
* HasShardProperties
##### Shard Vs Region[β](#shard-vs-region "Direct link to Shard Vs Region")
You'll notice some functions apply to **Shards** and some to **Regions**. What are "shards" anyways?
A Shard is a feature in Sinespace where **one** **Region** can have **multiple** **Shards** (instances), very much like parallel universes, where players on one Shard cannot see players on another Shard.
For the purpose of this beginner guide, we won't go into scripting multi-Shard experiences, but it's enough to understand the differences.
##### What are Shard/Region properties?[β](#what-are-shardregion-properties "Direct link to What are Shard/Region properties?")
For every Shard/Region that is open (there's players inside), there's a semi-permanent storage created on the server that holds **properties**. All scripts using these functions will access this same storage to read and write properties. This storage is a collection of **keys** and **values**. This storage will close after the Shard/Region is closed (after all players leave).
##### What "key" should you use?[β](#what-key-should-you-use "Direct link to What \"key\" should you use?")
You mostly want your **key** to be a private one, so other scripts cannot access it. You are also most likely to want your key to be specific to a GameObject.
We can achieve both of the above in this way:
```lua
thisGameObject = Space.Host.ExecutingObject
KEY = 'SomethingSecret' .. thisGameObject.ID
```
Now we've created a **key** which both **private** and **specific to a GameObject**. We will use it later to access the properties storage and read/write a specific value.
##### HasShardProperties[β](#hasshardproperties "Direct link to HasShardProperties")
When a player joins the region, scripts that want to immediately access the properties database might fire off during a very tiny period where we haven't yet connected to the properties storage. This is why use **HasShardProperties** to check if the storage database is connected and ready for read/write. (HasShardProperties is used for both Shard properties and Region properties)
Let's expand our previous code by adding a coroutine (run our code in a parallel thread) to take care of this:
```lua
thisGameObject = Space.Host.ExecutingObject
KEY = 'SomethingSecret' .. thisGameObject.ID
function TheCoroutineFunction()
while not Space.Network.HasShardProperties do --this while loop keeps looping until HasShardProperties returns true
coroutine.yield(0) --this ensures our loop runs once per frame, otherwise it will be crashed for running too long on a single frame
end
--At this point we have the confirmation we need to begin read/write
end
Space.Host.StartCoroutine(TheCoroutineFunction)
```
##### Setting and Getting properties[β](#setting-and-getting-properties "Direct link to Setting and Getting properties")
Shard properties and Region properties are executed in the exact same way. So for the purpose of this guide we will continue using Region properties only.
Note: The below to functions are usage limited to 10 calls per second. (20 calls per second on Breakroom)
To get a Region property: `value = Space.Network.GetRegionProperty(KEY)`
Note: Sometimes a Region property may have not been set before, so it might return **Nil**. We'll have to add a check for that.
To set a Region property: `Space.Network.SetRegionProperty(KEY, 'A Value')`
Note: Region property values are a string datatype, so you'll have to convert your numbers or tables to a string to store them.
```lua
thisGameObject = Space.Host.ExecutingObject
KEY = 'SomethingSecret' .. thisGameObject.ID
function TheCoroutineFunction()
while not Space.Network.HasShardProperties do --this while loop keeps looping until HasShardProperties returns true
coroutine.yield(0) --this ensures our loop runs once per frame, otherwise it will be crashed for running too long on a single frame
end
--below part only runs after weve got our confirmation
value = Space.Network.GetRegionProperty(KEY) --how to read
Space.Network.SetRegionProperty(KEY, 'A Value') --how to write
end
Space.Host.StartCoroutine(TheCoroutineFunction)
```
##### The window example[β](#the-window-example "Direct link to The window example")
Let's write a script for a window which when clicked opens/closes and updates it's Region property, and also keeps reading the Region property incase another player opens/closes the window.
We are going to add to our script two main parts. First part is constantly reading the Region property to monitor and react to changes. Second part reacts to clicks and updates the Region property which holds the state of the window (open/close).
###### The First Part[β](#the-first-part "Direct link to The First Part")
```lua
thisGameObject = Space.Host.ExecutingObject
KEY = 'SomethingSecret' .. thisGameObject.ID
refWindow = Space.Host.GetReference("window") -- this should be linked in the Scripting Runtime "references" section
function TheCoroutineForFirstPart()
while true do
local value = Space.Network.GetRegionProperty(KEY) --how to read
if value = nil then
--we're going to default the window to closed if Nil
refWindow.Active = true
elseif value == "Open" then
--if it's "Open" we're going to make the window disappear
refWindow.Active = false
elseif value == "Closed" then
--if it's "Closed" we're going to make the window appear
refWindow.Active = true
end
coroutine.yield(0.2) --We'll make this run every 0.2 seconds. That's should be quick enough and we also have a limit to mind.
end
end
function TheCoroutineFunction()
while not Space.Network.HasShardProperties do --this while loop keeps looping until HasShardProperties returns true
coroutine.yield(0) --this ensures our loop runs once per frame, otherwise it will be crashed for running too long on a single frame
end
--below part only runs after weve got our confirmation
Space.Host.StartCoroutine(TheCoroutineForFirstPart) -- we can no start our coroutine which consist of the first part
Space.Network.SetRegionProperty(KEY, 'A Value') --how to write
end
Space.Host.StartCoroutine(TheCoroutineFunction)
```
###### The Second Part (and final code)[β](#the-second-part-and-final-code "Direct link to The Second Part (and final code)")
```lua
thisGameObject = Space.Host.ExecutingObject
KEY = 'SomethingSecret' .. thisGameObject.ID
refWindow = Space.Host.GetReference("window") -- this should be linked in the Scripting Runtime "references" section
function TheCoroutineForFirstPart()
while true do
local value = Space.Network.GetRegionProperty(KEY) --how to read
if value = nil then
--we're going to default the window to closed if Nil
refWindow.Active = true
elseif value == "Open" then
--if it's "Open" we're going to make the window disappear
refWindow.Active = false
elseif value == "Closed" then
--if it's "Closed" we're going to make the window appear
refWindow.Active = true
end
coroutine.yield(0.2) --We'll make this run every 0.2 seconds. That's should be quick enough and we also have a limit to mind.
end
end
function TheOnClickFunctionForSecondPart() --Second Part code which will update region properties when object is clicked
local checkFirst = Space.Network.GetRegionProperty(KEY)
if checkFirst == nil then --if it's nil, this window was never used, so we update property to open
Space.Network.SetRegionProperty(KEY, "Open")
elseif checkFirst == "Open" --if its "Open" we update it to "Closed"
Space.Network.SetRegionProperty(KEY, "Closed")
elseif checkFirst == "Closed" --if its "Closed" we update it to "Open"
end
end
function TheCoroutineFunction()
while not Space.Network.HasShardProperties do --this while loop keeps looping until HasShardProperties returns true
coroutine.yield(0) --this ensures our loop runs once per frame, otherwise it will be crashed for running too long on a single frame
end
--below part only runs after weve got our confirmation
Space.Host.StartCoroutine(TheCoroutineForFirstPart) -- we can no start our coroutine which consist of the first part
Space.Network.SetRegionProperty(KEY, 'A Value') --how to write
end
thisGameObject.AddClickable() --we make this object a clickable
thisGameObject.Clickable.OnClick(TheOnClickFunctionForSecondPart) --we add our Second Part new code to be executed On cLick
Space.Host.StartCoroutine(TheCoroutineFunction)
```
#### SShared class[β](#sshared-class "Direct link to SShared class")
The SShared class (client scripting) has a variety of inter-script communication functions and local viewer storage functions but has 2 functions which are related to persistence.
* SetSuperGlobal
* GetSuperGlobal
##### What is a Super Global?[β](#what-is-a-super-global "Direct link to What is a Super Global?")
A "Global" in the SShared class is a storage within the local player's viewer accessible to all scripts.
A "Super Global" is the same storage but semi-permanent; it will keep existing even when changing regions, until the viewer is closed.
For this example, we will creator a clickable object that teleports us to a region, and on that region we will have a script that reacts depending where we came from.
##### What "namespace" and "key" should you use?[β](#what-namespace-and-key-should-you-use "Direct link to What \"namespace\" and \"key\" should you use?")
Unlike [our previous case](/scripting/guides/persistence.md#what-key-should-you-use), these functions are storing on a specific player's viewer, and they could be meant to be accessed by multiple scripts (could be our other scripts or other scripters' scripts too). It's inherently specific to a player, and likely to a specific project or operation/objective.
That's why it's accessed using a **namespace**, **key** and **value**, vs just **key** and **value**. The **namespace** could be a type of accessor which doesn't have to be private, while still having a **key** accessor that we can make private.
```lua
--SCRIPT A
NAMESPACE = 'space.sine.apidocs.persistenceguide' --this format is just a naming convention
KEY = 'Teleported From'
```
##### Setting and Getting Super Globals[β](#setting-and-getting-super-globals "Direct link to Setting and Getting Super Globals")
When Setting a Super Global, the value need not be a **string**. It accepts a value of type **DynValue**, which means it can be a **string**, **number** or **table** etc...
We set a Super Global like this:
`Space.Shared.SetSuperGlobal('namespace', 'key', AVariable)`
We get a Super Global like this:
`value = Space.Shared.GetSuperGlobal('namespace','key')`
##### The teleporter example[β](#the-teleporter-example "Direct link to The teleporter example")
We will create 2 scripts for this example. The first script will be the one teleporting us an Setting a Super Global, and the second one will be at the destination and will access our Super Global and react to where we teleported from.
We will start creating our first script by expanding on our code above by adding a clickable and make it Set a Super Global with the information we need to carry on to the second region. For the purpose of this guide we will pass our information in a Table rather than a single variable.
```lua
--Script A
NAMESPACE = 'space.sine.apidocs.persistenceguide' --this format is just a naming convention
KEY = 'Teleported From'
thisGameObject = Space.Host.ExecutingObject
function OnClickFunction()
local tableValue = {id = Space.Scene.RegionID, name = Space.Scene.Name} --we create a Table that holds both RegionID and Region Name
Space.Shared.SetSuperGlobal(NAMESPACE,KEY, tableValue) --we Set our Super Global
Space.Scene.PlayerAvatar.Teleport(0000000) -- We teleport. You'll have to replace the zeros with your region ID
end
thisGameObject.AddClickable() --we make the object clickable
thisGameObject.Clickable.OnClick(OnClickFunction) --we hook our OnClickFunction to the clickable's OnClick event
```
Now we have an object, that when clicked, Sets a Super Global and then teleports us. On the destination region we will now create the script that processes our carried over information (regiond name and ID).
```lua
--Script B
NAMESPACE = 'space.sine.apidocs.persistenceguide' --this format is just a naming convention
KEY = 'Teleported From'
getTableValue = Space.Shared.GetSuperGlobal(NAMESPACE, KEY)
Space.Log("You have arrived from region ID: ".. getTableValue.id .. " with Name: " .. getTableValue.name)
```
#### SPersistence Class[β](#spersistence-class "Direct link to SPersistence Class")
The SPersistence class has 6 functions that are all used for creating permanent persistence.
* UpdateInfo/UpdateRegionInfo
* RetrieveValue/RetrieveRegionValue
* SetValue/SetRegionValue
##### What are Region Values and Values?[β](#what-are-region-values-and-values "Direct link to What are Region Values and Values?")
Half the functions in this class create Permanent Region persistence, and the other half create Permanent Player persistence.
If the function has the word **region** in it, that means it creates Region persistence. If it does not, that means it creates Player persistence.
Region/Player values are values in a permanent storage. Region values are in a permanent storage which is linked to the region, and (Player) Values are in a permanent storage linked to the player running the script.
In terms of usage, Region Values are the equivalent to the permanent version of the[ SNetwork class](/scripting/guides/persistence.md#snetwork-class). Whereas Player values are the equivalent to the [SShared class](/scripting/guides/persistence.md#sshared-class).
##### What "key" should you use?[β](#what-key-should-you-use-1 "Direct link to What \"key\" should you use?")
In the case of Region values we will be creating keys in the same way as we did for the [SNetwork class](/scripting/guides/persistence.md#what-key-should-you-use).
In the case of (Player) values we will be creating keys in the same way as we did for the [SShared class](/scripting/guides/persistence.md#sshared-class).
##### Why do we need to "Update Region Info"?[β](#why-do-we-need-to-update-region-info "Direct link to Why do we need to \"Update Region Info\"?")
The unique feature of this class is that it is a client scripting class, but gives us the ability to create persistence without the use of a **server script.**
The storage used to achieve this is an external one, which means we have to start with using the **UpdateRegionInfo()** function to request the storage to send us a copy of it's most recent values (before trying to access these values).
We do it this way:
```lua
function WhatToDoWhenInfoIsReady()
--We access the data we need from inside here
end
Space.Persistence.UpdateRegionInfo() --or UpdateInfo() for Player version
```
Unlike semi-permanent region properties, this function call is not as instant. Because it accesses an external permanent storage, we need to hook a function which will be called once the info has arrived.
```lua
thisGameObject = Space.Host.ExecutingObject
KEY = "Secret" .. thisGameObject.GlobalID
function WhatToDoWhenInfoIsReady()
value = Space.Persistence.RetrieveRegionValue(KEY) --Getting a region value
Space.Log(value) --should print "Something"
end
Space.Persistence.SetRegionValue(KEY, "Something") --Setting a region value
Space.Persistence.UpdateRegionInfo()
```
The slower or variable response speed of this functionality means that it's not recommended to be called rapidly like we did with SNetwork region properties. Therefore we might have to mix and match our code with other types of persistence.
##### Smart Lights Example[β](#smart-lights-example "Direct link to Smart Lights Example")
[Visit our **Smart Lights** sample project page.](/scripting/sample-projects/smart-lights.md)
#### SDatabase Class[β](#sdatabase-class "Direct link to SDatabase Class")
The SDatabase class is the equivalent of the SPersistence class but the only difference being that it is accessed only through [**Server Scripts**](/scripting/guides/server-scripts.md)**.** Server scripts do not have access to the SPersistence class.
A server script is also inherently semi-persistent. That means if you do this `aVariable = 5` in a server script. This variable will be persistent until all players leave the region. This makes the usage of the SDatabase class much easier than the SPersistent class due to not having to mix and match persistent methods.
A downside to server scripts is that they can only be placed in furniture items and need to be loaded on a region to be used (unlike client scripts).
Since this class is almost an exact copy of the SPersistence class. We will only be outlining the differences below (to avoid being repetitive).
##### Differences between SDatabase and SPersistence[β](#differences-between-sdatabase-and-spersistence "Direct link to Differences between SDatabase and SPersistence")
The only two small differences between these to classes are:
1. Functions SetValue/GetValue in SPersistence, are SetPlayerValue/GetPlayerValue in SDatabase
2. GetRegionValue and GetPlayerValue have an extra **onSave** parameter which is a hook that lets us know when the value as been successfully set.
```lua
--Setting a region value using SPersistence in a client script
Space.Persistence.SetRegionValue(KEY, "Something")
--vs
--Setting a region value using SDatabase in a server script
function onSave()
--do something when set is succesful
end
Space.Database.SetRegionValue(KEY, "Something", onSave)
```
#### Thank You[β](#thank-you "Direct link to Thank You")
**Thanks for completing this guide. If you run into any issues or would like to recommend improvements,**[ **please do so on this page**](/scripting/support/report-an-issue.md)**.**
---
### Server Scripts
##### What are server scripts and why do we need them?[β](#what-are-server-scripts-and-why-do-we-need-them "Direct link to What are server scripts and why do we need them?")
The main difference between Server scripts and Client scripts is that they are running on the server.
For **Client scripts**, each player is **running their own local version of a script**, while for **Server scripts**, all players are **running the same version of a script**. Also, server scripts and client scripts **do not share the same API**.
Most of the time we should be able to achieve our task using Client scripts, specially with the availability of classes like the SNetwork or SPersistence classes, which allow scripts to communicate with each other and share data.
However, we may sometimes run into tasks that are more complex and require an independent script (a server script) to be a central hub for communication, data storage, processing information, syncing etc... A good example of an interactive object that would be done using a server script is a multiplayer board game.
##### Creating a Server script:[β](#creating-a-server-script "Direct link to Creating a Server script:")
* Create a GameObject.
* Add the server script component to the GameObject. (Add Component -> Server Script)
* Fill in the **Class ID** field with a unique identifier for your server script. (example: com.example.theserverscript)
* Drag your .lua file into the **Script** field.
* Add a Virtual Good component. (Add Component -> Virtual Good)
* Most important part in a Server Script's Virtual Good component is that the **Type** needs to be set to **Server Script.**
* Upload the GameObject .
##### Using a Server script:[β](#using-a-server-script "Direct link to Using a Server script:")
* Create a GameObject.
* Add a **Require Server Script** component.
* Set the **Virtual Good ID** field to the same virtual good ID of your above created server script.
* Set the **Class ID** field to the same class ID of your above created server script.
* Add a **Room Furniture** component (Add Component -> Room Furniture)
* Now this object will load the above created server script in the region it is placed in.
* You can also add a **Scripting Runtime** component to this GameObject. (Add Component -> Scripting Runtime).
#### Events[β](#events "Direct link to Events")
Unlike client scripting where you have to create hooks/bindings to events, Server scripts only need you to declare that function without creating any hooks/bindings.
For example:
```lua
function OnAvatarJoin(id)
Space.Log(id .. " joined the scene.")
end
```
You can find [Server script events here](/scripting/server-scripting-api-reference/region/sregionscript.md#events-index).
#### Sample Project[β](#sample-project "Direct link to Sample Project")
The **Trivia Box** sample project is a good demonstration of how to use server scripts.
[You can access it here and download it's open-source files.](/scripting/sample-projects/trivia-box.md)
#### Thank You[β](#thank-you "Direct link to Thank You")
**\[This guide is still in progress.**[ **Please report issues here**](/scripting/support/report-an-issue.md)**]**
---
### Sample Projects
#### [ποΈSmart Lights](/scripting/sample-projects/smart-lights.md)
[This sample project is a panel that has switches to turn off/on and change the colors of all lights connected to it. This project demonstrates how we](/scripting/sample-projects/smart-lights.md)
---
### Smart Lights
This sample project is a panel that has switches to turn off/on and change the colors of all lights connected to it. This project demonstrates how we can achieve permanent persistence, how a World Canvas can interface with a script and a bit of networking. Creators can access and download the project files (which are open-source) and do as they wish with it.
Note: Control of the panel is limited to Owner and Admin. This can be modified in the script.
You can demo this object live by going to the **Shop** -> **Furniture** -> Search for **Smart Lights** (it will be under **API Docs Sample Projects** as creator)**.**
###### How to use:[β](#how-to-use "Direct link to How to use:")
* Download the package using the link below
* Import into your Sinespace project (Editor Pack required)
* The project folder will be under **Sinespace Sample Projects -> Smart Lights**
* There's a demo scene in the Scenes folder
* To connect lights to the panel, make them children of the "**Lights**" object group
* In the **Virtual Goods component**, press **Clear ID** and modify the component fields with your own info
* Upload.
[Download PersistentSmartLights16July2022.unitypackage](/assets/files/PersistentSmartLights16July2022-956af536b0479562f583a94b380fc9a4.unitypackage)
Last Updated: 6/28/2022
---
### Trivia Box
This sample project is a box that when pressed will show a trivia question on screen and users will be able to attempt to answer the trivia question using local chat.
This project demonstrates how to create a server script and how client-server communications can be made to create an interactive multiplayer object. It also shows how we can access and interact with the local chat messages through scripting.
Creators can access and download the project (which is open-source) and do as they wish with it.
Note: Control of the box is limited to Owner and Admin. This can be modified in the script.
You can demo this object live by going to the **Shop** -> **Furniture** -> Search for **Trivia Box** (it will be under **API Docs Sample Projects** as creator)**.**
###### How to use:[β](#how-to-use "Direct link to How to use:")
* Download the package using the link below
* Import into your Sinespace project (Editor Pack required)
* The project folder will be under **Sinespace Sample Projects -> Trivia Box**
* There's a demo scene in the **Scenes** folder
* In the **Virtual Goods component**, press **Clear ID** and modify the component fields with your own info.
* In the **VG Trivia Box Server** object, edit the **Class ID** in the **Server Script** component.
* In the **VG Trivia Box object**, edit the **Virtual Good ID** and **Class ID** in the **Require Server Script** component.
* Modify the project and upload.
---
### Server Scripting API
#### [πLibrary](/scripting/server-scripting-api-reference/library.md)
[1 item](/scripting/server-scripting-api-reference/library.md)
---
### Library
Helper libraries available to server scripts, including math utilities.
---
### SMath
#### Index[β](#index "Direct link to Index")
##### Static Functions Index[β](#static-functions-index "Direct link to Static Functions Index")
| Function Name |
| --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| static float [**Random** ](/scripting/server-scripting-api-reference/library/smath.md#random)() |
| static float [**RandomRange** ](/scripting/server-scripting-api-reference/library/smath.md#randomrange)(float min, float max) |
| static int [**RandomInteger** ](/scripting/server-scripting-api-reference/library/smath.md#randominteger)(int min, int max) |
| static float [**Abs** ](smath#abs)(float v)
static int [**Abs** ](smath#abs)(int v) |
| static float [**Acos** ](/scripting/server-scripting-api-reference/library/smath.md#acos)(float v) |
| static bool [**Approximately** ](/scripting/server-scripting-api-reference/library/smath.md#approximately)(float a, float b) |
| static float [**Asin** ](/scripting/server-scripting-api-reference/library/smath.md#asin)(float v) |
| static float [**Atan** ](/scripting/server-scripting-api-reference/library/smath.md#atan)(float v) |
| static float [**Atan2** ](/scripting/server-scripting-api-reference/library/smath.md#atan2)(float y, float x) |
| static int [**Ceil** ](/scripting/server-scripting-api-reference/library/smath.md#ceil)(float v) |
| static float [**Clamp** ](/scripting/server-scripting-api-reference/library/smath.md#clamp)(float v, float min, float max) |
| static float [**Clamp01** ](/scripting/server-scripting-api-reference/library/smath.md#clamp01)(float v) |
| static int [**ClosestPowerOfTwo** ](/scripting/server-scripting-api-reference/library/smath.md#closestpoweroftwo)(int v) |
| static float [**Cos** ](/scripting/server-scripting-api-reference/library/smath.md#cos)(float v) |
| static float [**DeltaAngle** ](/scripting/server-scripting-api-reference/library/smath.md#deltaangle)(float current, float target) |
| static float [**Exp** ](/scripting/server-scripting-api-reference/library/smath.md#exp)(float v) |
| static int [**Floor** ](/scripting/server-scripting-api-reference/library/smath.md#floor)(float v) |
| static float [**GammaToLinearSpace** ](/scripting/server-scripting-api-reference/library/smath.md#gammatolinearspace)(float v) |
| static float [**InverseLerp** ](/scripting/server-scripting-api-reference/library/smath.md#inverselerp)(float a, float b, float value) |
| static bool [**IsPowerOfTwo** ](/scripting/server-scripting-api-reference/library/smath.md#ispoweroftwo)(int v) |
| static float [**Lerp** ](/scripting/server-scripting-api-reference/library/smath.md#lerp)(float a, float b, float v) |
| static float [**LerpAngle** ](/scripting/server-scripting-api-reference/library/smath.md#lerpangle)(float a, float b, float v) |
| static float [**LerpUnclamped** ](/scripting/server-scripting-api-reference/library/smath.md#lerpunclamped)(float a, float b, float v) |
| static float [**LinearToGammaSpace** ](/scripting/server-scripting-api-reference/library/smath.md#lineartogammaspace)(float v) |
| static float [**Log** ](smath#log)(float v)
static float [Log ](smath#log)(float v, float p) |
| static float [**Log10** ](/scripting/server-scripting-api-reference/library/smath.md#log10)(float v) |
| static float [**Max** ](/scripting/server-scripting-api-reference/library/smath.md#max)(float a, float b) |
| static float [**Min** ](/scripting/server-scripting-api-reference/library/smath.md#min)(float a, float b) |
| static float [**MoveTowards** ](/scripting/server-scripting-api-reference/library/smath.md#movetowards)(float value, float target, float delta) |
| static float [**MoveTowardsAngle** ](/scripting/server-scripting-api-reference/library/smath.md#movetowardsangle)(float value, float target, float delta) |
| static int [**NextPowerOfTwo** ](/scripting/server-scripting-api-reference/library/smath.md#nextpoweroftwo)(int v) |
| static float [**PerlinNoise** ](/scripting/server-scripting-api-reference/library/smath.md#perlinnoise)(float x, float y) |
| static float [**PingPong** ](/scripting/server-scripting-api-reference/library/smath.md#pingpong)(float t, float length) |
| static float [**Pow** ](/scripting/server-scripting-api-reference/library/smath.md#pow)(float value, float pow) |
| static float [**Repeat** ](/scripting/server-scripting-api-reference/library/smath.md#repeat)(float value, float length) |
| static int [**Round** ](/scripting/server-scripting-api-reference/library/smath.md#round)(float value) |
| static float [**Sign** ](/scripting/server-scripting-api-reference/library/smath.md#sign)(float value) |
| static float [**Sin** ](/scripting/server-scripting-api-reference/library/smath.md#sin)(float value) |
| static float [**SmoothStep** ](/scripting/server-scripting-api-reference/library/smath.md#smoothstep)(float from, float to, float t) |
| static float [**Sqrt** ](/scripting/server-scripting-api-reference/library/smath.md#sqrt)(float value) |
| static float [**Tan** ](/scripting/server-scripting-api-reference/library/smath.md#tan)(float value) |
##### Static Attributes Index[β](#static-attributes-index "Direct link to Static Attributes Index")
| Property Name |
| ----------------------------------------------------------------------------------------------------- |
| static readonly float [**Pi**](/scripting/server-scripting-api-reference/library/smath.md#pi)\*\*\*\* |
#### Static Functions[β](#static-functions "Direct link to Static Functions")
##### Random[β](#random "Direct link to Random")
static float **Random** ()
*Returns a random float between 0 and 1 (inclusive)*
* Lua
```lua
local randomNumber = Space.Math.Random();
Space.Log(randomNumber);
-- prints 0.689094245433807
```
##### RandomRange[β](#randomrange "Direct link to RandomRange")
static float **RandomRange** (float min, float max)
*Returns a random float between min and max (inclusive)*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local min = 100.0;
local max = 500.0;
local randomNumber = Space.Math.RandomRange(min, max );
Space.Log(randomNumber);
-- prints 0206.659149169922
```
##### RandomInteger[β](#randominteger "Direct link to RandomInteger")
static int **RandomInteger** (int min, int max)
*Returns a random float between min (inclusive) and max (exclusive)*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local min = 50;
local max = 75;
local randomInteger = Space.Math.RandomInteger(min, max);
Space.Log(randomInteger);
-- prints 52
```
##### Abs[β](#abs "Direct link to Abs")
static float **Abs** (float v)
static int **Abs** (int v)
*Returns the absolute value of 'val'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local value = -4.2
local absoluteNum = Space.Math.Abs(value);
Space.Log(absoluteNum);
-- prints 4 [BUG] should be 4.2
```
##### Acos[β](#acos "Direct link to Acos")
static float **Acos** (float v)
*Returns the arc cosine value of 'val'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local value = 0.5;
local arcCosine = Space.Math.Acos(value);
Space.Log(arcCosine);
-- prints 1.04719758033752 (radians) which is 60 degrees
```
##### Approximately[β](#approximately "Direct link to Approximately")
static bool **Approximately** (float a, float b)
*True if the difference between a and b is less than epsilon*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local a = 5.0;
local b = 5;
local approx1 = Space.Math.Approximately(a, b);
Space.Log(approx1);
-- prints true
local a = 5.01;
local b = 5.0;
local approx2 = Space.Math.Approximately(a, b);
Space.Log(approx2);
-- prints false
local a = 5.01;
local b = 5.0;
local approx3 = Space.Math.Approximately(a, b);
Space.Log(approx3);
-- prints false
```
##### Asin[β](#asin "Direct link to Asin")
static float **Asin** (float v)
*Returns the arc sine value of 'val'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local value = 0.5;
local arcSine = Space.Math.Asin(value);
Space.Log(arcSine);
-- prints 0.523598790168762 (radians) which is 30 degrees
```
##### Atan[β](#atan "Direct link to Atan")
static float **Atan** (float v)
*Returns the arc tangent value of 'val'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local value = 1.732050808;
local arcTangent = Space.Math.Atan(value);
Space.Log(arcTangent);
-- prints 1.04719758033752 (radians) which is 60 degrees
```
##### Atan2[β](#atan2 "Direct link to Atan2")
static float **Atan2** (float y, float x)
*Returns the arc tangent of y/x*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local x = 0.5;
local y = 0.5;
local arcTangent = Space.Math.Atan2(y, x);
Space.Log(arcTangent);
-- prints 0.785398185253143
```
##### Ceil[β](#ceil "Direct link to Ceil")
static int **Ceil** (float v)
*Returns the ceil value of 'val' as an integer*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.Ceil(4.0));
-- prints 4
Space.Log(Space.Math.Ceil(4.2));
-- prints 5
Space.Log(Space.Math.Ceil(-4.2));
-- prints -4
```
##### Clamp[β](#clamp "Direct link to Clamp")
static float **Clamp** (float v, float min, float max)
*Clamps val between min and max, and returns the result*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local value = 100.0;
local min = 20.0;
local max = 82.0;
local clampedValue = Space.Math.Clamp(value, min, max);
Space.Log(clampedValue);
-- prints 82
```
##### Clamp01[β](#clamp01 "Direct link to Clamp01")
static float **Clamp01** (float v)
*Clamps val between 0 and 1, and returns the result*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local value = -1.0;
local clampedValue = Space.Math.Clamp01(value);
Space.Log(clampedValue);
-- prints 0
```
##### ClosestPowerOfTwo[β](#closestpoweroftwo "Direct link to ClosestPowerOfTwo")
static int **ClosestPowerOfTwo** (int v)
*Returns the closest power of two to val*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local value = 33;
local powerOfTwo = Space.Math.ClosestPowerOfTwo(value);
Space.Log(powerOfTwo);
-- prints 32
```
##### Cos[β](#cos "Direct link to Cos")
static float **Cos** (float v)
*Returns the cosine of val*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local angle = 1.04719758033752; -- converts to 60 degrees
local cosine = Space.Math.Cos(angle);
Space.Log(cosine);
-- prints 0.499999970197678
local angle2 = Space.Math.Pi/3; -- converts to 60 degrees
local cosine2 = Space.Math.Cos(angle2);
Space.Log(cosine2);
-- prints 0.499999970197678
```
##### DeltaAngle[β](#deltaangle "Direct link to DeltaAngle")
static float **DeltaAngle** (float current, float target)
\_Returns the difference in degrees between two values (e.g. 350' and 17' returns 27') \_
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.DeltaAngle(350.0, 17.0));
-- prints 27
```
##### Exp[β](#exp "Direct link to Exp")
static float **Exp** (float v)
*Returns e raised to val power.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.Exp(3.0));
-- prints 20.0855369567871
```
##### Floor[β](#floor "Direct link to Floor")
static int **Floor** (float v)
*Returns floor of val, converted to an int*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.Floor(4.0));
-- prints 4
Space.Log(Space.Math.Floor(4.2));
-- prints 4
Space.Log(Space.Math.Floor(-4.2));
-- prints -5
```
##### GammaToLinearSpace[β](#gammatolinearspace "Direct link to GammaToLinearSpace")
static float **GammaToLinearSpace** (float v)
*Converts a colour value from Gamma to Linear Space (Pow 2.2)*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.GammaToLinearSpace(0.5));
-- prints 0.214041143655777
```
##### InverseLerp[β](#inverselerp "Direct link to InverseLerp")
static float **InverseLerp** (float a, float b, float value)
*Returns the percentage between a and b that 'val' is on a line (opposite of Lerp)*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local sliderStart = 0.0;
local sliderStop = 100.0;
local currentSliderPos = 75.0;
local percentage = Space.Math.InverseLerp(sliderStart, sliderStop, currentSliderPos);
Space.Log(percentage);
-- prints 0.75
```
##### IsPowerOfTwo[β](#ispoweroftwo "Direct link to IsPowerOfTwo")
static bool **IsPowerOfTwo** (int v)
*Returns true if val is a power of two*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.IsPowerOfTwo(55));
-- prints False
Space.Log(Space.Math.IsPowerOfTwo(32));
-- prints True
```
##### Lerp[β](#lerp "Direct link to Lerp")
static float **Lerp** (float a, float b, float v)
*Interpolates between 'a' and 'b' based on 'val', assuming 'val' is between 0 and 1*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local sliderStart = 0.0;
local sliderStop = 100.0;
local percentage = 0.75;
local currentSliderPos = Space.Math.Lerp(sliderStart, sliderStop, percentage);
Space.Log(currentSliderPos);
-- prints 75
```
##### LerpAngle[β](#lerpangle "Direct link to LerpAngle")
static float **LerpAngle** (float a, float b, float v)
*Interpolates between angles 'a' and 'b' based on 'val', assuming 'val' is between 0 and 1*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local sliderStartAngle = 0.0;
local sliderStopAngle = Space.Math.Pi;-- 180 degrees
local percentage = 0.50;
local currentSliderPos = Space.Math.LerpAngle(sliderStartAngle, sliderStopAngle, percentage);
Space.Log(currentSliderPos);
-- prints 1.57079637050629 (90 degrees)
```
##### LerpUnclamped[β](#lerpunclamped "Direct link to LerpUnclamped")
static float **LerpUnclamped** (float a, float b, float v)
*Interpolates between 'a' and 'b' based on 'val', assuming 'val' is between 0 and 1, but unbounded (allowing higher/lower values)*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local sliderStart = 0.0;
local sliderStop = 100.0;
local percentage = 2.0;
local currentSliderPos = Space.Math.LerpUnclamped(sliderStart, sliderStop, percentage);
Space.Log(currentSliderPos);
-- prints 200
```
##### LinearToGammaSpace[β](#lineartogammaspace "Direct link to LinearToGammaSpace")
static float **LinearToGammaSpace** (float v)
*Converts a colour value from Linear to Gamma Space (Pow 1/2.2)*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.LinearToGammaSpace(0.214041143655777));
-- prints 0.5
```
##### Log[β](#log "Direct link to Log")
static float **Log** (float v)
static float **Log** (float v, float p)
*Returns the natural logarithm for 'val'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.Log(30.0));
-- prints 3.40119743347168
Space.Log(Space.Math.Log(4.0, 2.0));
-- prints 2
```
##### Log10[β](#log10 "Direct link to Log10")
static float **Log10** (float v)
*Returns the Log10 value for 'val'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.Log10(100.0));
-- prints 2
```
##### Max[β](#max "Direct link to Max")
static float **Max** (float a, float b)
*Returns higher of 'a' or 'b'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.Max(20.0, 100.0));
-- prints 100
```
##### Min[β](#min "Direct link to Min")
static float **Min** (float a, float b)
*Returns lower of 'a' or 'b'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.Min(20.0, 100.0));
-- prints 20
```
##### MoveTowards[β](#movetowards "Direct link to MoveTowards")
static float **MoveTowards** (float value, float target, float delta)
*Move value to target, but by no more than delta*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local sliderStart = 5.0;
local sliderStop = 10.0;
local deltaChange = 1.0;
local currentSliderPos = Space.Math.MoveTowards(sliderStart, sliderStop, deltaChange);
Space.Log(currentSliderPos);
-- prints 6 (moves forward 1)
local sliderStart = 5.0;
local sliderStop = 10.0;
local deltaChange = 7.0;
local currentSliderPos = Space.Math.MoveTowards(sliderStart, sliderStop, deltaChange);
Space.Log(currentSliderPos); -- prints 10 (caps out at at the target value)
-- NOTE: Use negative delta to move away from target.
```
##### MoveTowardsAngle[β](#movetowardsangle "Direct link to MoveTowardsAngle")
static float **MoveTowardsAngle** (float value, float target, float delta)
*Move angle value to target, but by no more than delta*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local sliderStartAngle = Space.Math.Pi/2; -- 90 degrees
local sliderStopAngle = Space.Math.Pi; -- 180 degrees
local deltaChange = Space.Math.Pi/6; -- 30 degrees
local currentSliderPos = Space.Math.MoveTowardsAngle(sliderStartAngle, sliderStopAngle, deltaChange);
Space.Log(currentSliderPos);
-- prints 2.09439516067505 (moves forward 30 degrees to 120 degrees)
-- NOTE: Add 180 degrees (Space.Math.Pi) to move away from target.
```
##### NextPowerOfTwo[β](#nextpoweroftwo "Direct link to NextPowerOfTwo")
static int **NextPowerOfTwo** (int v)
*Return the next power of two larger or equal to val*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.NextPowerOfTwo(16));
-- prints 16
Space.Log(Space.Math.NextPowerOfTwo(17));
-- prints 32
```
##### PerlinNoise[β](#perlinnoise "Direct link to PerlinNoise")
static float **PerlinNoise** (float x, float y)
*Return 2D Perlin noise for coordinates x and y*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
-- Lua Translation of Unity C# Documentation
local ball = Space.Host.ExecutingObject;
ball.SubscribeToEvents();
-- animates this object to move upwards on the y axis with slight random movement
local animateBall = function()
local heightScale = 0.1; -- controls speed of movement
local xScale = 1.0; -- shifts x position on perlin noise plane
local height = heightScale * Space.Math.PerlinNoise(Space.Time * xScale, 0.0);
local pos = ball.LocalPosition;
pos.y = pos.y + height;
ball.LocalPosition = pos;
Space.Log(pos.y);
end
ball.OnUpdate(animateBall);
-- NOTE: If you need a guaranteed range of [0,1], make sure to clamp the value with Space.Math.Clamp01.
```
##### PingPong[β](#pingpong "Direct link to PingPong")
static float **PingPong** (float t, float length)
*Return a value between 0 and length that oscillates upwards and back based on the position of 'val'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
--[[ In this example, if you traced the output of Space.Math.PingPong(value, length),
the return values would cycle forward through the range [0,5] then cycle backwards through the range [5,0] in order. --]]
local ball = Space.Host.ExecutingObject;
local originalPos = ball.LocalPosition;
ball.SubscribeToEvents();
-- The ball object oscillates back and forth on the x-axis.
local animateBall = function()
local value = Space.Time;
local length = 5.0;
local newPos = Vector.New(Space.Math.PingPong(value, length) + originalPos.x, originalPos.y, originalPos.z);
ball.LocalPosition = newPos;
end
ball.OnUpdate(animateBall);
```
##### Pow[β](#pow "Direct link to Pow")
static float **Pow** (float value, float pow)
*Return x raised to y power*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.Pow(2, 4));
-- prints 16
```
##### Repeat[β](#repeat "Direct link to Repeat")
static float **Repeat** (float value, float length)
*Return a value between 0 and length that returns to 0 after exceeding length based on 'val'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
--[[ In this example, if you traced the output of Space.Math.Repeat(value, length),
the return values would cycle forward through the range [0,5]. The cycle is repeated again from 0.--]]
local ball = Space.Host.ExecutingObject;
local originalPos = ball.LocalPosition;
ball.SubscribeToEvents();
-- The ball object moves forward on the x-axis.
-- Then, it repeats the same motion again from the beginning.
local animateBall = function()
local value = Space.Time;
local length = 5.0;
local newPos = Vector.New(Space.Math.Repeat(value, length) + originalPos.x, originalPos.y, originalPos.z);
ball.LocalPosition = newPos;
end
ball.OnUpdate(animateBall);
```
##### Round[β](#round "Direct link to Round")
static int **Round** (float value)
*Returns the nearest integer value to val*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.Round(4.0));
-- prints 4
Space.Log(Space.Math.Round(4.2));
-- prints 4
Space.Log(Space.Math.Round(4.5));
-- prints 4
Space.Log(Space.Math.Round(4.55));
-- prints 5
Space.Log(Space.Math.Round(4.8));
-- prints 5
Space.Log(Space.Math.Round(-4.2));
-- prints -4
Space.Log(Space.Math.Round(-4.8));
-- prints -5
```
##### Sign[β](#sign "Direct link to Sign")
static float **Sign** (float value)
*Returns either 1 or -1 based on the sign of 'val'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.Sign(4.2));
-- prints 1
Space.Log(Space.Math.Sign(-4.2));
-- prints -1
```
##### Sin[β](#sin "Direct link to Sin")
static float **Sin** (float value)
*Returns the sine of val*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local angle = 1.04719758033752; -- converts to 60 degrees
local sine = Space.Math.Sin(angle);
Space.Log(sine);
-- prints 0.866025447845459
local angle2 = Space.Math.Pi/3; -- converts to 60 degrees
local sine2 = Space.Math.Sin(angle2);
Space.Log(sine2);
-- prints 0.866025447845459
```
##### SmoothStep[β](#smoothstep "Direct link to SmoothStep")
static float **SmoothStep** (float from, float to, float t)
*Similar to Lerp but moves slowly closer to the edges ('Spherical Lerp')*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
-- Lua Translation of Unity C# Documentation
--[[ In this example, Space.Math.SmoothStep(min, max, time) returns values in the range [1,10] in order.
As values approach 10, the interpolation slows down. --]]
local ball = Space.Host.ExecutingObject;
local originalPos = ball.LocalPosition;
local min = 1.0;
local max = 10.0;
local duration = 5.0; --lower value to speed up; raise to slow down
local startTime;
ball.SubscribeToEvents();
local initStartTime = function()
startTime = Space.Time;
end
-- The ball jumps to min + originalPos, then it moves towards
-- max + originalPos while slowing down at the end.
local animateBall = function()
local time = (Space.Time - startTime) / duration;
local newPos = Vector.New(Space.Math.SmoothStep(min, max, time)
+ originalPos.x, originalPos.y, originalPos.z);
ball.LocalPosition = newPos;
end
ball.OnStart(initStartTime);
ball.OnUpdate(animateBall);
```
##### Sqrt[β](#sqrt "Direct link to Sqrt")
static float **Sqrt** (float value)
*Returns the square root of val*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log(Space.Math.Sqrt(16));
-- prints 4
Space.Log(Space.Math.Sqrt(-16));
-- prints NaN
```
##### Tan[β](#tan "Direct link to Tan")
static float **Tan** (float value)
*Returns the tangent value of 'val'*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local angle = 1.04719758033752; -- converts to 60 degrees
local tangent = Space.Math.Tan(angle);
Space.Log(tangent);
-- prints 1.73205089569092
local angle2 = Space.Math.Pi/3; -- converts to 60 degrees
local tangent2 = Space.Math.Tan(angle2);
Space.Log(tangent2);
-- prints 1.73205089569092
```
#### Static Attributes[β](#static-attributes "Direct link to Static Attributes")
##### Pi[β](#pi "Direct link to Pi")
static readonly float **Pi** = 3.14159265358979f
*Returns the constant value of Ξ .*
* Lua
```lua
Space.Log(Space.Math.Pi);
-- prints 3.14159274101257
```
---
### Network
Networking APIs for server scripts, covering shared data and outbound web requests.
---
### SShared
#### Index[β](#index "Direct link to Index")
##### Functions Index[β](#functions-index "Direct link to Functions Index")
| Function |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| void [**SetGlobal** ](/scripting/server-scripting-api-reference/network/sshared.md#setglobal)(string ns, string key, DynValue value) |
| DynValue [**GetGlobal** ](/scripting/server-scripting-api-reference/network/sshared.md#getglobal)(string ns, string key) |
| void [**RegisterFunction** ](/scripting/server-scripting-api-reference/network/sshared.md#registerfunction)(string ns, string func, Closure reference) |
| void [**RegisterBroadcastFunction** ](/scripting/server-scripting-api-reference/network/sshared.md#registerbroadcastfunction)(string ns, string func, Closure reference) |
| void [**UnregisterBroadcastFunction** ](sshared#unregisterbroadcastfunction)(string ns, string func, Closure reference)
void **UnregisterBroadcastFunction** (string ns, string func) |
| void [**CallFunction** ](/scripting/server-scripting-api-reference/network/sshared.md#callfunction)(string ns, string func, IEnumerable< DynValue > args) |
| int [**CallBroadcastFunction** ](/scripting/server-scripting-api-reference/network/sshared.md#callbroadcastfunction)(string ns, string func, IEnumerable< DynValue > args) |
#### Functions[β](#functions "Direct link to Functions")
##### SetGlobal[β](#setglobal "Direct link to SetGlobal")
void **SetGlobal** (string ns, string key, DynValue value)
*Sets a global key to a value. The value can be any object type.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Shared.SetGlobal("com.someNameHere.world", "version", "1.02");
```
##### GetGlobal[β](#getglobal "Direct link to GetGlobal")
DynValue **GetGlobal** (string ns, string key)
*Retrieves a previously set global variable, or returns nil.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
local versionValue = Space.Shared.GetGlobal("com.someNameHere.world", "version")
```
##### RegisterFunction[β](#registerfunction "Direct link to RegisterFunction")
void **RegisterFunction** (string ns, string func, Closure reference)
*Makes func into a global function that can be accessed anywhere.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
function someFunction(name)
Space.Log("Hello " .. name);
end
Space.Shared.RegisterFunction("com.someNameHere.world", "func", someFunction);
```
##### RegisterBroadcastFunction[β](#registerbroadcastfunction "Direct link to RegisterBroadcastFunction")
void **RegisterBroadcastFunction** (string ns, string func, Closure reference)
*Makes func into a global function that can be accessed anywhere.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
function someFunction(name)
Space.Log("Hello " .. name);
end
Space.Shared.RegisterBroadcastFunction("com.someNameHere.world", "func", someFunction);
```
##### UnregisterBroadcastFunction[β](#unregisterbroadcastfunction "Direct link to UnregisterBroadcastFunction")
void **UnregisterBroadcastFunction** (string ns, string func, Closure reference)
void **UnregisterBroadcastFunction** (string ns, string func)
*Unregister Broadcast Function.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
example 1
```
##### CallFunction[β](#callfunction "Direct link to CallFunction")
void **CallFunction** (string ns, string func, IEnumerable< DynValue > args)
*Calls the registered function with the specified arguments.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Shared.CallFunction("com.someNameHere.world", "func",{"Smith"});
```
##### CallBroadcastFunction[β](#callbroadcastfunction "Direct link to CallBroadcastFunction")
int **CallBroadcastFunction** (string ns, string func, IEnumerable< DynValue > args)
*Calls every registered broadcast function with the specified arguments, and returns the number of calls queued.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
example 1
```
---
### SWebservice
#### Index[β](#index "Direct link to Index")
##### Functions Index[β](#functions-index "Direct link to Functions Index")
| Function |
| -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| void [**Get** ](/scripting/server-scripting-api-reference/network/swebservice.md#get)(string url, Closure onComplete, Table headers=null) |
| void [**Post** ](/scripting/server-scripting-api-reference/network/swebservice.md#post)(string url, string data, Closure onComplete, Table headers=null) |
#### Functions[β](#functions "Direct link to Functions")
##### Get[β](#get "Direct link to Get")
void **Get** (string url, Closure onComplete, Table headers=null)
*Performs an HTTP\[S] GET. The callback receives two parameters: `success` (bool) and `response` (string).*
| Parameter | Type | Description |
| ---------- | ---------------- | --------------------------------------------------------------------------------------------------------- |
| url | string | The absolute URL to request. |
| onComplete | Closure | Callback `(bool success, string response)` invoked on completion. |
| headers | Table (optional) | Supported keys: `Bearer` (maps to `Authorization: Bearer
`), `Content-Type` (rarely used for GET). |
* Lua
```lua
-- Simple GET
local url = "https://httpbin.org/get"
Space.WebServices.Get(url, function(success, response)
if success then
Space.Log("OK: " .. response)
else
Space.Log("Request failed: " .. response)
end
end)
```
* Lua
```lua
-- GET with Bearer auth
local url = "https://api.example.com/me"
local headers = { ["Bearer"] = "YOUR_ACCESS_TOKEN" }
Space.WebServices.Get(url, function(success, response)
if success then
Space.Log(response)
else
Space.Log("Error: " .. response)
end
end, headers)
```
##### Post[β](#post "Direct link to Post")
void **Post** (string url, string data, Closure onComplete, Table headers=null)
*Performs an HTTP\[S] POST. The callback receives two parameters: `success` (bool) and `response` (string).*
| Parameter | Type | Description |
| ---------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| url | string | The absolute URL to POST to. |
| data | string | Request body string. For JSON, send a JSON string and set `Content-Type`. |
| onComplete | Closure | Callback `(bool success, string response)` invoked on completion. |
| headers | Table (optional) | Supported keys: `Content-Type` (defaults to `application/x-www-form-urlencoded`), `Bearer` (maps to `Authorization: Bearer `). |
* Lua
```lua
-- Form POST
local url = "https://httpbin.org/post"
local body = "x=1&y=2"
Space.WebServices.Post(url, body, function(success, response)
if success then
Space.Log("OK: " .. response)
else
Space.Log("Error: " .. response)
end
end)
```
* Lua
```lua
-- JSON POST with Bearer auth
local url = "https://api.example.com/widgets"
local body = '{"name":"Server Created Widget"}'
local headers = { ["Content-Type"] = "application/json", ["Bearer"] = "YOUR_ACCESS_TOKEN" }
Space.WebServices.Post(url, body, function(success, response)
if success then
Space.Log("Created: " .. response)
else
Space.Log("Error: " .. response)
end
end, headers)
```
Note:
* Server requests automatically include: `X-Sinespace-Region-ID`, `X-Sinespace-Instance-ID`, `X-Sinespace-Script-ID`, `X-Sinespace-Runtime-Type`, and `X-Sinespace-In-Editor`.
* There is no `timeout` parameter on server web requests.
---
### Scene
APIs for the region from the server's perspective β scenes, parcels, cells, objects, and the avatars present within them.
---
### SAvatar
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ----------------------------------------------------------------------------------------------------- |
| int [**ID**](/scripting/server-scripting-api-reference/region/savatar.md#id) `get` |
| Vector3 [**Position** ](/scripting/server-scripting-api-reference/region/savatar.md#position)`get` |
| Vector3 [**Velocity** ](/scripting/server-scripting-api-reference/region/savatar.md#velocity)`get` |
| Quaternion [**Rotation** ](/scripting/server-scripting-api-reference/region/savatar.md#rotation)`get` |
| string [**Username** ](/scripting/server-scripting-api-reference/region/savatar.md#username)`get` |
| string [**Title** ](/scripting/server-scripting-api-reference/region/savatar.md#title)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### ID[β](#id "Direct link to ID")
int **ID** `get`
*Avatar's ID*
* Lua
```lua
ID = Space.Scene.Avatars[1].ID
```
* Lua
```lua
--server script that prints a list of IDs of players online whenever someone joins
function OnAvatarJoin(id)
local numOfAvatars = Space.Scene.ConnectedAvatars
for num =1 , numOfAvatars, 1 do
Space.Log(Space.Scene.Avatars[num].ID)
end
end
```
##### Position[β](#position "Direct link to Position")
Vector3 **Position** `get`
*Avatar's position*
* Lua
```lua
ID = Space.Scene.Avatars[1].Position
```
* Lua
```lua
--server script that prints a list of Positions of players online whenever someone joins
function OnAvatarJoin(id)
local numOfAvatars = Space.Scene.ConnectedAvatars
for num =1 , numOfAvatars, 1 do
Space.Log(Space.Scene.Avatars[num].Position)
end
end
```
##### Velocity[β](#velocity "Direct link to Velocity")
Vector3 **Velocity** `get`
*Avatar's Velocity*
* Lua
```lua
ID = Space.Scene.Avatars[1].Velocity
```
* Lua
```lua
--server script that prints a list of Velocitys of players online whenever someone joins
function OnAvatarJoin(id)
local numOfAvatars = Space.Scene.ConnectedAvatars
for num =1 , numOfAvatars, 1 do
Space.Log(Space.Scene.Avatars[num].Velocity)
end
end
```
##### Rotation[β](#rotation "Direct link to Rotation")
Quaternion **Rotation** `get`
*Avatar's Rotation*
* Lua
```lua
ID = Space.Scene.Avatars[1].Quaternion
```
* Lua
```lua
--server script that prints a list of Rotations of players online whenever someone joins
function OnAvatarJoin(id)
local numOfAvatars = Space.Scene.ConnectedAvatars
for num =1 , numOfAvatars, 1 do
Space.Log(Space.Scene.Avatars[num].Rotation)
end
end
```
##### Username[β](#username "Direct link to Username")
string **Username** `get`
*Avatar's Username*
* Lua
```lua
ID = Space.Scene.Avatars[1].Username
```
* Lua
```lua
--server script that prints a list of Usernames of players online whenever someone joins
function OnAvatarJoin(id)
local numOfAvatars = Space.Scene.ConnectedAvatars
for num =1 , numOfAvatars, 1 do
Space.Log(Space.Scene.Avatars[num].Username)
end
end
```
##### Title[β](#title "Direct link to Title")
string **Title** `get`
*Avatar's Title*
* Lua
```lua
ID = Space.Scene.Avatars[1].Title
```
* Lua
```lua
--server script that prints a list of Titles of players online whenever someone joins
function OnAvatarJoin(id)
local numOfAvatars = Space.Scene.ConnectedAvatars
for num =1 , numOfAvatars, 1 do
Space.Log(Space.Scene.Avatars[num].Title)
end
end
```
---
### SCell
#### Index[β](#index "Direct link to Index")
##### Functions Index[β](#functions-index "Direct link to Functions Index")
| Function |
| -------------------------------------------------------------------------------------------------------- |
| SObject [**GetObject** ](/scripting/server-scripting-api-reference/region/scell.md#getobject)(string id) |
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| -------------------------------------------------------------------------------------------- |
| Table [**Objects** ](/scripting/server-scripting-api-reference/region/scell.md#objects)`get` |
#### Functions[β](#functions "Direct link to Functions")
##### GetObject[β](#getobject "Direct link to GetObject")
[SObject](/scripting/server-scripting-api-reference/region/sobject.md) **GetObject** (string id)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
#### Properties[β](#properties "Direct link to Properties")
##### Objects[β](#objects "Direct link to Objects")
Table **Objects** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
---
### SObject
#### Index[β](#index "Direct link to Index")
##### Functions Index[β](#functions-index "Direct link to Functions Index")
| Function |
| ------------------------------------------------------------------------------------------------------------------------------- |
| string [**GetProperty** ](/scripting/server-scripting-api-reference/region/sobject.md#getproperty)(string property) |
| void [**SetProperty** ](/scripting/server-scripting-api-reference/region/sobject.md#setproperty)(string property, string value) |
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ----------------------------------------------------------------------------------------------------------- |
| SCell [**Cell** ](/scripting/server-scripting-api-reference/region/sobject.md#cell)`get` |
| string [**ID**](/scripting/server-scripting-api-reference/region/sobject.md#id) `get` |
| string [**Floor** ](/scripting/server-scripting-api-reference/region/sobject.md#floor)`get` |
| Vector3 [**Position** ](/scripting/server-scripting-api-reference/region/sobject.md#position)`get` `set` |
| Quaternion [**Rotation** ](/scripting/server-scripting-api-reference/region/sobject.md#rotation)`get` `set` |
| Vector3 [**Scale** ](/scripting/server-scripting-api-reference/region/sobject.md#scale)`get` `set` |
| int [**Player** ](/scripting/server-scripting-api-reference/region/sobject.md#player)`get` |
| int [**InventoryID** ](/scripting/server-scripting-api-reference/region/sobject.md#inventoryid)`get` |
| int [**ItemID** ](/scripting/server-scripting-api-reference/region/sobject.md#itemid)`get` |
| Bounds [**Bounds** ](/scripting/server-scripting-api-reference/region/sobject.md#bounds)`get` |
#### Functions[β](#functions "Direct link to Functions")
##### GetProperty[β](#getproperty "Direct link to GetProperty")
string **GetProperty** (string property)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### SetProperty[β](#setproperty "Direct link to SetProperty")
void **SetProperty** (string property, string value)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
#### Properties[β](#properties "Direct link to Properties")
##### Cell[β](#cell "Direct link to Cell")
SCell **Cell** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### ID[β](#id "Direct link to ID")
string **ID** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Floor[β](#floor "Direct link to Floor")
string **Floor** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Position[β](#position "Direct link to Position")
Vector3 **Position** `get` `set`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Rotation[β](#rotation "Direct link to Rotation")
Quaternion **Rotation** `get` `set`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Scale[β](#scale "Direct link to Scale")
Vector3 **Scale** `get` `set`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Player[β](#player "Direct link to Player")
int **Player** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### InventoryID[β](#inventoryid "Direct link to InventoryID")
int **InventoryID** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### ItemID[β](#itemid "Direct link to ItemID")
int **ItemID** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Bounds[β](#bounds "Direct link to Bounds")
Bounds **Bounds** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
---
### SParcel
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ---------------------------------------------------------------------------------------------------------------- |
| string [**ID**](/scripting/server-scripting-api-reference/region/sparcel.md#id) `get` |
| string [**Name** ](/scripting/server-scripting-api-reference/region/sparcel.md#name)`get` |
| string [**DescriptionName** ](/scripting/server-scripting-api-reference/region/sparcel.md#descriptionname)`get` |
| bool [**ForSale** ](/scripting/server-scripting-api-reference/region/sparcel.md#forsale)`get` |
| int [**GoldSalePrice** ](/scripting/server-scripting-api-reference/region/sparcel.md#goldsaleprice)`get` |
| int [**SilverSalePrice** ](/scripting/server-scripting-api-reference/region/sparcel.md#silversaleprice)`get` |
| int [**GoldRentalPrice** ](/scripting/server-scripting-api-reference/region/sparcel.md#goldrentalprice)`get` |
| int [**SilverRentalPrice** ](/scripting/server-scripting-api-reference/region/sparcel.md#silverrentalprice)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### ID[β](#id "Direct link to ID")
string **ID** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### Name[β](#name "Direct link to Name")
string **Name** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### DescriptionName[β](#descriptionname "Direct link to DescriptionName")
string **DescriptionName** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### ForSale[β](#forsale "Direct link to ForSale")
bool **ForSale** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### GoldSalePrice[β](#goldsaleprice "Direct link to GoldSalePrice")
int **GoldSalePrice** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### SilverSalePrice[β](#silversaleprice "Direct link to SilverSalePrice")
int **SilverSalePrice** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### GoldRentalPrice[β](#goldrentalprice "Direct link to GoldRentalPrice")
int **GoldRentalPrice** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
##### SilverRentalPrice[β](#silverrentalprice "Direct link to SilverRentalPrice")
int **SilverRentalPrice** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
---
### SParcelManager
#### Index[β](#index "Direct link to Index")
##### Functions Index[β](#functions-index "Direct link to Functions Index")
| Function |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [SParcel](/scripting/server-scripting-api-reference/region/sparcel.md) [**GetParcel** ](/scripting/server-scripting-api-reference/region/sparcelmanager.md#getparcel)(string id) |
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ----------------------------------------------------------------------------------------------------------- |
| Table [**AllParcels** ](/scripting/server-scripting-api-reference/region/sparcelmanager.md#allparcels)`get` |
#### Functions[β](#functions "Direct link to Functions")
##### GetParcel[β](#getparcel "Direct link to GetParcel")
SParcel **GetParcel** (string id)
*Function Description*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
#### Properties[β](#properties "Direct link to Properties")
##### AllParcels[β](#allparcels "Direct link to AllParcels")
Table **AllParcels** `get`
*Property Description*
* Lua
```lua
example 1
```
* Lua
```lua
example 2
```
---
### SRegionScript
#### Index[β](#index "Direct link to Index")
##### Functions Index[β](#functions-index "Direct link to Functions Index")
| Function |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| void [**Log** ](/scripting/server-scripting-api-reference/region/sregionscript.md#log)(string message) |
| void [**SubscribeToNetwork** ](/scripting/server-scripting-api-reference/region/sregionscript.md#subscribetonetwork)(string key) |
| void [**UnsubscribeFromNetwork** ](/scripting/server-scripting-api-reference/region/sregionscript.md#unsubscribefromnetwork)(string key) |
| void [**SendMessageToAllClientScripts** ](/scripting/server-scripting-api-reference/region/sregionscript.md#sendmessagetoallclientscripts)(string messageName, Table message) |
| void [**SendMessageToClientScripts** ](/scripting/server-scripting-api-reference/region/sregionscript.md#sendmessagetoclientscripts)(ulong playerID, string messageName, Table message) |
| void [**StartCoroutine** ](sregionscript#startcoroutine)(DynValue coroutine, DynValue parameter=default(DynValue))
void [**StartCoroutine** ](sregionscript#startcoroutine)(string name, DynValue parameter=default(DynValue)) |
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ------------------------------------------------------------------------------------------------------------------ |
| string [**ScriptID** ](/scripting/server-scripting-api-reference/region/sregionscript.md#scriptid)`get` |
| uint [**InstanceID** ](/scripting/server-scripting-api-reference/region/sregionscript.md#instanceid)`get` |
| ulong [**RegionID** ](/scripting/server-scripting-api-reference/region/sregionscript.md#regionid)`get` |
| SScene [**Scene** ](/scripting/server-scripting-api-reference/region/sregionscript.md#scene)`get` |
| SDatabase [**Database** ](/scripting/server-scripting-api-reference/region/sregionscript.md#database)`get` |
| SMath [**Math** ](/scripting/server-scripting-api-reference/region/sregionscript.md#math)`get` |
| SShared [**Shared** ](/scripting/server-scripting-api-reference/region/sregionscript.md#shared)`get` |
| SWebservice [**WebServices** ](/scripting/server-scripting-api-reference/region/sregionscript.md#webservices)`get` |
| string [**RuntimeType** ](/scripting/server-scripting-api-reference/region/sregionscript.md#runtimetype)`get` |
| bool [**InEditor** ](/scripting/server-scripting-api-reference/region/sregionscript.md#ineditor)`get` |
| float [**TimeSinceAwake** ](/scripting/server-scripting-api-reference/region/sregionscript.md#timesinceawake)`get` |
| string [**DateTimeUTC** ](/scripting/server-scripting-api-reference/region/sregionscript.md#datetimeutc)`get` |
| int [**LocalTimeUnix** ](/scripting/server-scripting-api-reference/region/sregionscript.md#localtimeunix)`get` |
| int [**ServerTimeUnix** ](/scripting/server-scripting-api-reference/region/sregionscript.md#servertimeunix)`get` |
##### Events Index[β](#events-index "Direct link to Events Index")
| Event |
| -------------------------------------------------------------------------------------------------------------------------------------------- |
| Action< int > [**OnAvatarJoin**](/scripting/server-scripting-api-reference/region/sregionscript.md#onavatarjoin) |
| Action< int > [**OnAvatarLeave**](/scripting/server-scripting-api-reference/region/sregionscript.md#onavatarleave) |
| Action< string, Table > [**OnScriptServerMessage**](/scripting/server-scripting-api-reference/region/sregionscript.md#onscriptservermessage) |
#### Functions[β](#functions "Direct link to Functions")
##### Log[β](#log "Direct link to Log")
void **Log** (string message)
*Log a message to console. (only works on preview grid)*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.Log("Log")
```
* Lua
```lua
--Clicking the object will make the server script log "Test Message" on all clients
--server script
function OnScriptServerMessage(key, table)
if key == "testKey" then
Space.Log("Message:" .. table[1])
end
end
--client script
thisObject = Space.Host.ExecutingObject
OnClickFunction = function()
Space.Network.SendNetworkMessage("testKey",{"Test Message"})
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
##### SubscribeToNetwork[β](#subscribetonetwork "Direct link to SubscribeToNetwork")
void **SubscribeToNetwork** (string key)
*Subscribe to network messages on "key".*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.SubscribeToNetwork("thekey")
```
##### UnsubscribeFromNetwork[β](#unsubscribefromnetwork "Direct link to UnsubscribeFromNetwork")
void **UnsubscribeFromNetwork** (string key)
*Unsubscribe from network messages on "key".*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.UnsubscribeFromNetwork("thekey")
```
##### SendMessageToAllClientScripts[β](#sendmessagetoallclientscripts "Direct link to SendMessageToAllClientScripts")
void **SendMessageToAllClientScripts** (string messageName, Table message)
*Sends a network message to all client scripts.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.SendMessageToAllClientScripts("thekey",{"themessage"})
```
* Lua
```lua
--Clicking the object by a single client will send a message to the server which triggers a message response to all clients
--server script--
function OnScriptServerMessage(key, table)
if key == "testKey" then
Space.SendMessageToAllClientScripts("ServerResponse",{"message response to all client scripts in region that are subscribed to this key"})
end
end
--client script--
thisObject = Space.Host.ExecutingObject
OnClickFunction = function()
Space.Network.SendNetworkMessage("testKey",{"Test Message"})
end
OnReceiveFunction = function(SNetworkMessage)
Space.Log(SNetworkMessage.Key)
Space.Log(SNetworkMessage.Message[1])
end
Space.Network.SubscribeToNetwork("ServerResponse", OnReceiveFunction)
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
##### SendMessageToClientScripts[β](#sendmessagetoclientscripts "Direct link to SendMessageToClientScripts")
void **SendMessageToClientScripts** (ulong playerID, string messageName, Table message)
*Sends a network message to a client script belonging to a specific player*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.SendMessageToClientScripts(playerID,"thekey",{"themessage"})
```
* Lua
```lua
--Clicking the object by a single client will send a message to the server which triggers...
--a message response only to that specific client
--server script--
function OnScriptServerMessage(key, table)
if key == "testKey" then
local sender = table[2]
Space.SendMessageToClientScripts(sender,"ServerResponse",{"a message response to the clicker's client script in region that is subscribed to this key"})
end
end
--client script--
thisObject = Space.Host.ExecutingObject
OnClickFunction = function()
id = Space.Scene.PlayerAvatar.ID
Space.Network.SendNetworkMessage("testKey",{"Test Message", id})
end
OnReceiveFunction = function(SNetworkMessage)
Space.Log(SNetworkMessage.Key)
Space.Log(SNetworkMessage.Message[1])
end
Space.Network.SubscribeToNetwork("ServerResponse", OnReceiveFunction)
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
##### StartCoroutine[β](#startcoroutine "Direct link to StartCoroutine")
void **StartCoroutine** (DynValue coroutine, DynValue parameter=default(DynValue))
void **StartCoroutine** (string name, DynValue parameter=default(DynValue))
*Runs the given function as a coroutine. A parameter is optional.*
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| | | |
* Lua
```lua
Space.StartCoroutine(AFunctionName)
```
* Lua
```lua
--Clicking the object on client will trigger a 3 second countdown on server script using coroutine
--server script--
function OnScriptServerMessage(key, table)
if key == "testKey" and table[1] == "Timer" then
Space.StartCoroutine(TimerCoroutine)
end
end
function TimerCoroutine()
local time = 0
while time < 3 do
Space.Log(3-time)
time = time + 1
coroutine.yield(1)
end
end
--client script--
thisObject = Space.Host.ExecutingObject
function OnClickFunction()
Space.Network.SendNetworkMessage("testKey",{"Timer"})
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
#### Properties[β](#properties "Direct link to Properties")
##### ScriptID[β](#scriptid "Direct link to ScriptID")
string **ScriptID** `get`
*Returns a unique identifier of this script runtime. (can be found in "/list\_scripts" window on preview.)*
* Lua
```lua
scriptID = Space.ScriptID
```
* Lua
```lua
--Clicking the object on client will make the server script log it's ScriptID
--server script--
function OnScriptServerMessage(key, table)
if key == "testKey" and table[1] == "ScriptID" then
Space.Log(Space.ScriptID)
end
end
--client script--
thisObject = Space.Host.ExecutingObject
function OnClickFunction()
Space.Network.SendNetworkMessage("testKey",{"ScriptID"})
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
##### InstanceID[β](#instanceid "Direct link to InstanceID")
uint **InstanceID** `get`
*Returns a unique identifier for the instance of the region. Useful in the case of multiple shards/instances being used. InstanceID does not necessarily equal to the RegionID, even if there's only one instance running.*
* Lua
```lua
instance = Space.InstanceID
```
* Lua
```lua
--Clicking the object on client will make the server script log only...
--if it's instanceID matches with client's instanceID
--server script--
function OnScriptServerMessage(key, table)
local instanceID = Space.InstanceID
if key == "testKey" and table[1] == "ScriptID" and table[2] == instanceID then
Space.Log(instanceID)
end
end
--client script--
thisObject = Space.Host.ExecutingObject
function OnClickFunction()
local instanceID = Space.Scene.InstanceID
Space.Network.SendNetworkMessage("testKey",{"ScriptID", instanceID})
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
##### RegionID[β](#regionid "Direct link to RegionID")
ulong **RegionID** `get`
*Returns a unique identifier for the region. (Same ID seen in curator)*
* Lua
```lua
region = Space.RegionID
```
* Lua
```lua
--Clicking the object on client will make the server script log only...
--if it's RegionID matches with client's RegionID
--server script--
function OnScriptServerMessage(key, table)
local RegionID = Space.RegionID
if key == "testKey" and table[1] == "ScriptID" and table[2] == RegionID then
Space.Log(RegionID)
end
end
--client script--
thisObject = Space.Host.ExecutingObject
function OnClickFunction()
local RegionID = Space.Scene.RegionID
Space.Network.SendNetworkMessage("testKey",{"ScriptID", RegionID})
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
##### Scene[β](#scene "Direct link to Scene")
[SScene](/scripting/server-scripting-api-reference/region/sscene.md) **Scene** `get`
*Access to the SScene class methods and properties.*
* Lua
```lua
Space.Scene
```
##### Database[β](#database "Direct link to Database")
[SDatabase](/scripting/server-scripting-api-reference/storage/sdatabase.md) **Database** `get`
*Access to the SDatabase class methods and properties.*
* Lua
```lua
Space.Database
```
##### Math[β](#math "Direct link to Math")
[SMath](/scripting/server-scripting-api-reference/library/smath.md) **Math** `get`
*Access to the SMath class methods and properties.*
* Lua
```lua
Space.Math
```
##### Shared[β](#shared "Direct link to Shared")
[SShared](/scripting/server-scripting-api-reference/network/sshared.md) **Shared** `get`
*Access to the SShared class methods and properties.*
* Lua
```lua
Space.Shared
```
##### WebServices[β](#webservices "Direct link to WebServices")
[SWebservice](/scripting/server-scripting-api-reference/network/swebservice.md) **WebServices** `get`
*Access to the SWebservice class methods and properties.*
* Lua
```lua
Space.WebServices
```
##### RuntimeType[β](#runtimetype "Direct link to RuntimeType")
string **RuntimeType** `get`
*Returns "Server" if this script is a Server script*
* Lua
```lua
type = Space.RuntimeType
```
##### InEditor[β](#ineditor "Direct link to InEditor")
bool **InEditor** `get`
*Returns true if in Editor. (this will return false on server scripts)*
* Lua
```lua
IsInEditor = Space.InEditor
```
##### TimeSinceAwake[β](#timesinceawake "Direct link to TimeSinceAwake")
float **TimeSinceAwake** `get`
*Time, in seconds, since this script runtime has been awake.*
* Lua
```lua
SecondsAwake = Space.TimeSinceAwake
```
* Lua
```lua
--Clicking the object will make the server script log it's TimeSinceAwake on all clients
--server script
function OnScriptServerMessage(key, table)
if key == "testKey" and table[1] == "TimeSinceAwake" then
Space.Log(Space.TimeSinceAwake)
end
end
--client script
thisObject = Space.Host.ExecutingObject
OnClickFunction = function()
Space.Network.SendNetworkMessage("testKey",{"TimeSinceAwake"})
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
##### DateTimeUTC[β](#datetimeutc "Direct link to DateTimeUTC")
string **DateTimeUTC** `get`
*Returns a string of the current Date/Time in UTC*
* Lua
```lua
DateAndTime = Space.DateTimeUTC
```
* Lua
```lua
--Clicking the object will make the server script log it's DateTimeUTC on all clients
--server script
function OnScriptServerMessage(key, table)
if key == "testKey" and table[1] == "DateTimeUTC" then
Space.Log(Space.DateTimeUTC)
end
end
--client script
thisObject = Space.Host.ExecutingObject
OnClickFunction = function()
Space.Network.SendNetworkMessage("testKey",{"DateTimeUTC"})
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
##### LocalTimeUnix[β](#localtimeunix "Direct link to LocalTimeUnix")
int **LocalTimeUnix** `get`
*Returns the current Unix time (in seconds) (same as ServerTimeUnix)*
* Lua
```lua
unixtime = Space.LocalTimeUnix
```
* Lua
```lua
--Clicking the object will make the server script log it's LocalTimeUnix on all clients
--server script
function OnScriptServerMessage(key, table)
if key == "testKey" and table[1] == "LocalTimeUnix" then
Space.Log(Space.LocalTimeUnix)
end
end
--client script
thisObject = Space.Host.ExecutingObject
OnClickFunction = function()
Space.Network.SendNetworkMessage("testKey",{"LocalTimeUnix"})
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
##### ServerTimeUnix[β](#servertimeunix "Direct link to ServerTimeUnix")
int **ServerTimeUnix** `get`
*Returns the current Unix time (in seconds) (same as LocalTimeUnix)*
* Lua
```lua
unixtime = Space.ServerTimeUnix
```
* Lua
```lua
--Clicking the object will make the server script log it's ServerTimeUnix on all clients
--server script
function OnScriptServerMessage(key, table)
if key == "testKey" and table[1] == "ServerTimeUnix" then
Space.Log(Space.ServerTimeUnix)
end
end
--client script
thisObject = Space.Host.ExecutingObject
OnClickFunction = function()
Space.Network.SendNetworkMessage("testKey",{"ServerTimeUnix"})
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
#### Events[β](#events "Direct link to Events")
##### OnAvatarJoin[β](#onavatarjoin "Direct link to OnAvatarJoin")
Action< int > **OnAvatarJoin**
*An event function which will be called whenever an Avatar joins and will also contain the Avatar's ID as a parameter.*
* Lua
```lua
function OnAvatarJoin(playerID)
end
```
* Lua
```lua
function OnAvatarJoin(id)
local numOfAvatars = Space.Scene.ConnectedAvatars
Space.Log("Avatar with ID " .. id .. "has joined")
Space.Log("Number of avatars connected: " .. numOfAvatars)
end
```
##### OnAvatarLeave[β](#onavatarleave "Direct link to OnAvatarLeave")
Action< int > **OnAvatarLeave**
*An event function which will be called whenever an Avatar leaves and will also contain the Avatar's ID as a parameter.*
* Lua
```lua
function OnAvatarLeave(playerID)
end
```
* Lua
```lua
function OnAvatarLeave(id)
local numOfAvatars = Space.Scene.ConnectedAvatars
Space.Log("Avatar with ID " .. id .. "has left")
Space.Log("Number of avatars connected: " .. numOfAvatars)
end
```
##### OnScriptServerMessage[β](#onscriptservermessage "Direct link to OnScriptServerMessage")
Action< string, Table > **OnScriptServerMessage**
*An event function which will be called whenever the server script receives a Network Message, and will contain the network message key String and message Table as a parameter.*
* Lua
```lua
function OnScriptServerMessage(key, table)
theKeyString = key
theSNetworkMessageTable = table
end
```
* Lua
```lua
--Clicking the object will make the server script log "Test Message" on all clients
--server script
function OnScriptServerMessage(key, table)
if key == "testKey" then
Space.Log("Message:" .. table[1])
end
end
--client script
thisObject = Space.Host.ExecutingObject
OnClickFunction = function()
Space.Network.SendNetworkMessage("testKey",{"Test Message"})
end
thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClickFunction)
```
---
### SScene
#### Index[β](#index "Direct link to Index")
##### Properties Index[β](#properties-index "Direct link to Properties Index")
| Property |
| ------------------------------------------------------------------------------------------------------------- |
| int [**ConnectedAvatars** ](/scripting/server-scripting-api-reference/region/sscene.md#connectedavatars)`get` |
| Table [**Avatars** ](/scripting/server-scripting-api-reference/region/sscene.md#avatars)`get` |
| Table [**Cells** ](/scripting/server-scripting-api-reference/region/sscene.md#cells)`get` |
| SParcelManager [**Parcels** ](/scripting/server-scripting-api-reference/region/sscene.md#parcels)`get` |
#### Properties[β](#properties "Direct link to Properties")
##### ConnectedAvatars[β](#connectedavatars "Direct link to ConnectedAvatars")
int **ConnectedAvatars** `get`
*Returns the number of Avatars connected to the region.*
* Lua
```lua
numOfAvatars = Space.Scene.ConnectedAvatars
```
* Lua
```lua
function OnAvatarJoin(id)
local numOfAvatars = Space.Scene.ConnectedAvatars
Space.Log("Avatar with ID " .. id .. "has joined")
Space.Log("Number of avatars connected: " .. numOfAvatars)
end
```
##### Avatars[β](#avatars "Direct link to Avatars")
Table **Avatars** `get`
*Returns a table of SAvatar objects currently in the region*
* Lua
```lua
currentAvatars = Space.Scene.Avatars
```
##### Cells[β](#cells "Direct link to Cells")
Table **Cells** `get`
*Returns a table of SCell objects. (Not all cells are available at all times, a client on this server must be within 384m of a cell in order for it to exist.)*
* Lua
```lua
cellsTable = Space.Scene.Cells
```
##### Parcels[β](#parcels "Direct link to Parcels")
[SParcelManager](/scripting/server-scripting-api-reference/region/sparcelmanager.md) **Parcels** `get`
*Access to the SParcelManager class.*
* Lua
```lua
Space.Scene.Parcels
```
---
### Storage
Persistent server-side storage for your region, including the database API for saving and querying data.
---
### SDatabase
#### Index[β](#index "Direct link to Index")
##### Functions Index[β](#functions-index "Direct link to Functions Index")
| Function |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| void [**GetRegionValue** ](/scripting/server-scripting-api-reference/storage/sdatabase.md#getregionvalue)(string key, Closure onResult) |
| void [**SetRegionValue** ](/scripting/server-scripting-api-reference/storage/sdatabase.md#setregionvalue)(string key, string value, Closure onSave) |
| void [**GetPlayerValue** ](/scripting/server-scripting-api-reference/storage/sdatabase.md#getplayervalue)(int player, string key, Closure onResult) |
| void [**SetPlayerValue** ](/scripting/server-scripting-api-reference/storage/sdatabase.md#setplayervalue)(int player, string key, string value, Closure onSave) |
#### Functions[β](#functions "Direct link to Functions")
##### GetRegionValue[β](#getregionvalue "Direct link to GetRegionValue")
void **GetRegionValue** (string key, Closure onResult)
*Get a value stored in the region database. (this does not access the same database as the SPersistence class)*
| Parameter | Type | Description |
| --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| key | string | The "key" to access the record from the region database. |
| onResult | Closure | The name of the function which will be called once the results are ready.
This function will be called with a string parameter containing the requested value. onResult(value) |
* Lua
```lua
function onResult(value)
yourValue = value
end
Space.Database.GetRegionValue("testKey", onResult)
```
##### SetRegionValue[β](#setregionvalue "Direct link to SetRegionValue")
void **SetRegionValue** (string key, string value, Closure onSave)
*Store a "value" in the region database. (this does not access the same database as the SPersistence class)*
| Parameter | Type | Description |
| --------- | ------- | ------------------------------------------------------------------------------------------------------ |
| key | string | The "key" to access the record from the region database. |
| value | string | The "value" that will be stored in the region database. |
| onSave | Closure | The name of the function which will be called when the "value" has been stored in the region database. |
* Lua
```lua
function onSave()
--
end
Space.Database.SetRegionValue("testKey", "testValue", onSave)
```
##### GetPlayerValue[β](#getplayervalue "Direct link to GetPlayerValue")
void **GetPlayerValue** (int player, string key, Closure onResult)
*Get a value stored in a player database. (this does not access the same database as the SPersistence class)*
| Parameter | Type | Description |
| --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| player | int | The ID of the player's database in whose record we will access. |
| key | string | The "key" to access the record from the region database. |
| onResult | Closure | The name of the function which will be called once the results are ready.
This function will be called with a string parameter containing the requested value. onResult(value) |
* Lua
```lua
function onResult(value)
yourValue = value
end
Space.Database.GetPlayerValue(aPlayerID,"testKey",onResult)
```
##### SetPlayerValue[β](#setplayervalue "Direct link to SetPlayerValue")
void **SetPlayerValue** (int player, string key, string value, Closure onSave)
*Store a "value" in a player database. (this does not access the same database as the SPersistence class). (this does not access the same database as the SPersistence class)*
| Parameter | Type | Description |
| --------- | ------- | ------------------------------------------------------------------------------------------------------ |
| player | int | The ID of the player's database in whose record we will access. |
| key | string | The "key" to access the record from the region database. |
| onSave | Closure | The name of the function which will be called when the "value" has been stored in the player database. |
* Lua
```lua
function onSave()
--
end
Space.Database.SetPlayerValue(aPlayerID,"testKey", "testValue",onSave)
```
---
### Support
#### [ποΈReport An Issue](/scripting/support/report-an-issue.md)
[How to report issues within the Sinespace Scripting Documentation](/scripting/support/report-an-issue.md)
---
### Report An Issue
##### How to report an issue with this documentation[β](#how-to-report-an-issue-with-this-documentation "Direct link to How to report an issue with this documentation")
If you would like to report any issues with this documentation such as corrections, lack of documentation, or improvements in the quality, please use [this form ](https://form.asana.com/?k=foybfPQQIK5JpFVRRcPyJg\&d=634886966090241)and select **Scripting** as the type of documentation.
---
## Sinespace Api
### Sinespace API
#### [ποΈRegistration & Grid API](/sinespace-api/gridapi.md)
[This API requires specific access to be granted to your account. If you have purchased your own Grid, this will be automatically enabled on the primary user account.](/sinespace-api/gridapi.md)
---
### Registration & Grid API
#### Overview[β](#overview "Direct link to Overview")
This API requires specific access to be granted to your account. If you have purchased your own Grid, this will be automatically enabled on the primary user account.
info
You may send parameters as either POST form\_data, or as Query parameters on the URL.
tip
**All APIs require you send three additional POST parameters** - `adminname, adminpwd,`and `gridid`, these should be the username, and password of an account on the Grid with administrator rights, along with the grid you wish to interface with. We recommend creating a new user for this role specifically.
#### User Management APIs[β](#user-management-apis "Direct link to User Management APIs")
#### Register User[β](#register-user "Direct link to Register User")
*`POST`* `https://sine.space/worldapi/externalapi/add_user`
This endpoint allows you to register new users automatically.
###### Query Parameters[β](#query-parameters "Direct link to Query Parameters")
| Name | Type | Description |
| -------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| gridid | integer | The unique grid ID to register the user on. |
| password | string | The users initial password |
| email | string | The users email address. We will not send any messages to this address unless requested by the user (e.g. password reset) |
| username | string | The desired username for the user |
| playeroutfitid | integer | The "Outfit ID" the user should be wearing when they first log in. As this creates 'free' copies of items that may be paid items in our marketplace, the creator of the items must be an administrator of the grid in question. |
* 200 User account has been created
* 400 Bad or invalid input, or similar.
```text
2099396
```
```text
0A user account with that name already exists.
```
#### Delete User[β](#delete-user "Direct link to Delete User")
*`POST`* `https://sine.space/worldapi/externalapi/delete_user`
Deletes or disables a user account
###### Path Parameters[β](#path-parameters "Direct link to Path Parameters")
| Name | Type | Description |
| ------ | ------- | -------------------------------------- |
| userid | integer | The user ID associated with this user. |
* 200
```text
1
```
#### Update User[β](#update-user "Direct link to Update User")
*`POST`* `https://sine.space/worldapi/externalapi/update_user`
Changes information about a user account
###### Query Parameters[β](#query-parameters-1 "Direct link to Query Parameters")
| Name | Type | Description |
| -------- | ------- | -------------------------------------- |
| userid | integer | The user ID associated with this user. |
| email | string | Updates the users email address |
| password | string | Updates the users password |
* 200
```text
1
```
#### Get Users[β](#get-users "Direct link to Get Users")
*`POST`* `https://sine.space/worldapi/externalapi/get_users`
Returns a bulk list of users associated with the Grid
###### Query Parameters[β](#query-parameters-2 "Direct link to Query Parameters")
| Name | Type | Description |
| ------- | ------- | -------------------------------------------------------------------------------------------------------------- |
| userids | string | A comma separated list of user IDs you are interested in information about. |
| offset | integer | The query will return a maximum of 100 records, if more are available, use 'offset' to return past this point. |
* 200
```text
2099560usernameusername@test1.comM2099559username2username2@test1.comF
```
#### Get User By Email[β](#get-user-by-email "Direct link to Get User By Email")
*`POST`* `https://sine.space/worldapi/externalapi/get_user_by_email`
Retrieves information about an individual user via their email address
###### Query Parameters[β](#query-parameters-3 "Direct link to Query Parameters")
| Name | Type | Description |
| ----- | ------ | --------------------------------------------- |
| email | string | The email address associated with the account |
* 200
```text
2099560usernameusername@test1.comM
```
#### Update Login Region[β](#update-login-region "Direct link to Update Login Region")
*`POST`* `https://sine.space/worldapi/externalapi/update_login_region`
Updates the user, sets their login scene to the specified ID.
###### Query Parameters[β](#query-parameters-4 "Direct link to Query Parameters")
| Name | Type | Description |
| -------- | ------- | ------------------------------------------------------------------------------ |
| userid | integer | The user to updates user ID |
| regionid | integer | The scene to make as their login scene. Set to zero to return to grid default. |
* 200
```text
1
```
#### Region APIs[β](#region-apis "Direct link to Region APIs")
#### Create Region[β](#create-region "Direct link to Create Region")
*`POST`* `https://sine.space/worldapi/externalapi/create_region`
Creates a new region on the grid
###### Query Parameters[β](#query-parameters-5 "Direct link to Query Parameters")
| Name | Type | Description |
| ----------- | ------- | --------------------------------------------------------------------------------------------------------------------- |
| owner | integer | The user ID to be marked as owner of the region |
| templateid | integer | The item ID for the region template to use |
| accesslevel | integer | Either "0" for no access, "1" for free-for-all access, "2" for friends-only access, and "3" for approved only access. |
| regionname | string | The name of the region you wish to create |
* 200 Region was created successfully
* 400 An error was found in the inputs
```text
152860
```
```text
0Room template not available, please try another.
```
#### Set Region Role[β](#set-region-role "Direct link to Set Region Role")
*`POST`* `https://sine.space/worldapi/externalapi/set_region_role`
###### Query Parameters[β](#query-parameters-6 "Direct link to Query Parameters")
| Name | Type | Description |
| -------- | ------- | --------------------------------------- |
| regionid | integer | The ID of the region |
| userid | integer | The ID of the user in question |
| role | string | Either "Normal", "Admin", or "Blocked". |
* 200
* 400
```text
1
```
```text
0The data provided is incorrect: role = abc
```
#### Get Regions[β](#get-regions "Direct link to Get Regions")
*`POST`* `https://sine.space/worldapi/externalapi/get_regions`
Requests a list of regions on the Grid
###### Query Parameters[β](#query-parameters-7 "Direct link to Query Parameters")
| Name | Type | Description |
| --------- | ------- | --------------------------------------------------------------------- |
| offset | integer | Offsets the results if there is too many to return in a single query. |
| owner | integer | Return regions owned by this account |
| regionids | string | A CSV separated list of region IDs to return information about. |
* 200
```text
50000040regionname209956411350000039regionname22099563111
```
#### Update Region[β](#update-region "Direct link to Update Region")
*`POST`* `https://sine.space/worldapi/externalapi/update_region`
Updates information about a particular region
###### Query Parameters[β](#query-parameters-8 "Direct link to Query Parameters")
| Name | Type | Description |
| ----------- | ------- | ------------------------------------------------------------------------------------------------- |
| regionid | integer | The region ID to update information about |
| regionname | string | If present, changes the name of the region |
| templateid | integer | If present, changes the template of the region to the specified template ID |
| accesslevel | integer | Either "0" - no access, "1" - free access, "2" friends-only access, and "3" approved only access. |
* 200
```text
1
```
---
## Sinespace Sdk
### Sinespace SDK
#### [πAnimation](/sinespace-sdk/animation/animation-production-workflow.md)
[1 item](/sinespace-sdk/animation/animation-production-workflow.md)
---
### Animation Production Workflow
#### Overview[β](#overview "Direct link to Overview")
A zero-cost animation production workflow.
A zero-cost animation production workflow. This is FAIRLY EXPERIMENTAL, please do update if possible!
Animation production for Sine Space has been a bit of a neglected topic. Here is a fresh end-to-end process and toolchain for getting animations/poses together for your furniture, vehicles, and etc.
###### The Toolchain and Process[β](#the-toolchain-and-process "Direct link to The Toolchain and Process")
1\. QAvimator ([\[1\]](http://qavimator.org/))
This older opensource application does one thing and one thing only, and does it fairly well. It allows you to pose an avatar model for keyframes on a timeline, and output the resulting humanoid animation as both a proprietary file and as a mocap motion file (BVH). Version 0.1.1.426 on Windows 10 is being used in this workflow.
We wont get into how to use QAvimator; it is simple, and if you've ever made a paper flipbook and used a computer, you should not have a problem working out how to use QAvimator. One note though regarding storage: It'll try and save to the directory in 'Programs (x86)' where the executable lives. That's bad. That way lies madness. Make a data directory somewhere and use it.
2\. Blender ([\[2\]](http://blender.org/))
Blender is exactly the opposite of QAvimator in scope; it does \*everything\*. Including provide for the production of animations. However, blender is a highly complex tool with a steep learning curve and a user interface made by aliens from alpha centauri, so we will use it only for converting from BVH to FBX. Blender version 2.78 is being used in this workflow. Doing so is fairly straightforward: Click 'File->Import->Motion Capture(.BVH)'. You should not need to tweak any settings here; just import it according to the defaults. Next, export it as FBX (File->Export->FBX(.fbx)).
If you've never used blender, pay careful attention to the file saving dialog, it's a bit different. I'd recommend fiddling with it a bit and gathering some confidence that my files were being saved.
3\. Unity/Space
Finally, we're getting the animation into Space. This is where the important tweaks come into play. The process is not unlike that of importing any other FBX, excpet for a few notable ddifferences.
First, you'll want to click 'Assets->Import Asset...'. This will take you into the file selector dialog; browse to your data directory (you did make one and use it, yes?) and select the FBX version of your animation saved from blender in the previous step.
Your FBX is imported now, but there are various tweaks that need be applied to get it into a proper working state for Space. First, click the 'Rig' tab on the import properties pane. Set the anim type as 'Humanoid'. Click apply. On the 'Model' tab, untick 'Use File Scale'. Click the Apply button. You should be set; there will be a folder generated in your unity project's assets named after the file you imported. Within that will be the clip(s) (animations). These should be ready to use in your vehicle furniture sits or animation controllers in Space.
Good luck and happy animating! ANIMATE ALL THE THINGS!!
---
### Animation Tools
#### Overview[β](#overview "Direct link to Overview")
A brief survey of various tools with humanoid avatar animation capability There are a variety of solutions available for producing humanoid animations, both paid and free.
A brief survey of various tools with humanoid avatar animation capability
There are a variety of solutions available for producing humanoid animations, both paid and free. We'll accumulate a list here, and hopefully everyone with the knowledge can pitch in with instructions, pointers and tips.
###### The Tools[β](#the-tools "Direct link to The Tools")
1\. QAvimator ([\[1\]](http://qavimator.org/))
This older opensource application does one thing and one thing only, and does it fairly well. It allows you to pose an avatar model for keyframes on a timeline, and output the resulting humanoid animation as both a proprietary file and as a mocap motion file (BVH). Version 0.1.1.426 is what has been used successfully with Unity/Space so far.
QAvimator has a fairly intuitive interface developed on Troll-Tech's Qt interface library. It's quite well utilised, resulting in a highly interactive tool with a small executable footprint. Because it was developed on relatively old computers, it isn't very thread heavy and will cheerfully run several copies at once.
The interface loves to get clicked. Click and drag on the background in the scene to move the camera; click on body parts to select them for positioning. Drag the sliders around to change the position and orientation of whatever bodypart is selected.
When you start an animation, never use the first frame. The animator uses that for stuff. Otherwise, clicking to the right of a bodypart listed on the timeline graph will also select that bodypart, at that point on the graph. Any bodypart, once selected, can have it's current position and orientation changed via the sliders.
On the lower right, beneath the sliders, are various parameters pertaining to the actual animation clip, e.g., number of frames and frames per second. Adjust these according to your needs.
There is support for a range of props and prop workflows in this version, but these came a bit after my time and so I will leave it to you all or perhaps another time to describe that set of tools and techniques.
2\. Blender ([\[2\]](http://blender.org/))
3\. Poser
4\. DAZ Studio
5\. 3DS/MAX
6\. Maya
7\. AVASTAR
8\. Photoshop
9\. Mechanim
---
### Clothing
#### Overview[β](#overview "Direct link to Overview")
Welcome to the Clothing Portal! Sinespace has some powerful tools when it comes to creating clothing.

#### Welcome to the Clothing Portal\
Sinespace has some powerful tools when it comes to creating clothing. You can create anything from bikinis, to skin tight jeans, to dresses, to trench coats. Check out the pages below and get creative!
#### Newbie Area[β](#newbie-area "Direct link to Newbie Area")
* [Getting Started](/quickstart-sinespace-viewer/get-started-sdk/sdk-setup.md)
#### How Do I?[β](#how-do-i "Direct link to How Do I?")
* [Importing and Uploading Clothing](/sinespace-sdk/avatars/clothing/importing-and-uploading-clothing.md)
#### Clothing Resource Files[β](#clothing-resource-files "Direct link to Clothing Resource Files")
* [Male Clothing Resource Files](/sinespace-sdk/avatars/clothing/male-clothing-resource-files.md)
* [Male Hair Resource Files](/sinespace-sdk/avatars/clothing/male-hair-resource-files.md)
* [Female Clothing Resource Files](/sinespace-sdk/avatars/clothing/female-clothing-resource-files.md)
* [Female Hair Resource Files](/sinespace-sdk/avatars/clothing/female-hair-resource-files.md)
#### Reference[β](#reference "Direct link to Reference")
* [Clothing Item Setting](/sinespace-sdk/avatars/clothing/clothing-item-settings.md)
* [Virtual Good Component](/sinespace-sdk/components/virtual-goods.md)
* [End-User License Agreement](/policies/end-user-license-agreement.md)
#### Clothing Video Tutorials[β](#clothing-video-tutorials "Direct link to Clothing Video Tutorials")
* [Basic Clothes](/sinespace-sdk/avatars/clothing/basic-clothes.md)
* [Clothing/Variations](/sinespace-sdk/avatars/clothing/clothing-variations.md)
* [Avatar Skins](/sinespace-sdk/avatars/skins.md)
#### Advanced Topics[β](#advanced-topics "Direct link to Advanced Topics")
* [Attachments versus Skinned Clothing](/sinespace-sdk/avatars/clothing/advanced-topics/attachments-vs-skinned-clothing.md)
* [Heel Adjustments](/sinespace-sdk/avatars/clothing/advanced-topics/boots-and-heels.md)
* [Full Body Replacement Costumes](/sinespace-sdk/avatars/clothing/advanced-topics/how-to-upload-avatars/full-body-replacement-costumes-with-custom-animations.md)
* [Cloth Physics](/sinespace-sdk/avatars/clothing/advanced-topics/cloth-physics.md)
---
### Attachments Vs Skinned Clothing
#### Overview[β](#overview "Direct link to Overview")
space has both options of attachments and skinned clothing which you can use for uploading items and clothing to space.
space has both options of attachments and skinned clothing which you can use for uploading items and clothing to space.
There is a few differences between the two, and here are the details of the differences for you!
##### Attachments[β](#attachments "Direct link to Attachments")
Attachments are just that- Attachments.
They attach to your avatar on a specific bone, for example, to the neck bone if you have created a necklace. You cannot attach the attachments to multiple bones.
Attachments also don't support deletion zones or advanced clothing features.
Attachments are much faster than skinned clothing performance wise, and they are much easier to upload and create as there are no rigging steps.
##### Skinned Clothing[β](#skinned-clothing "Direct link to Skinned Clothing")
Skinned clothing are the normal full clothing items with rigging/weighting, and also with the addition of settings such as skin deletion and skin preservation.
Skin deletion is good to use if you have items of clothing which have areas cut out, such as trousers with lace up sides, or a dress with cut out side panels as you can select certain areas of the skin you want to delete.
Skin preservation works in a parallel way to the skin deletion - the areas of skin you select will be preserved.
This is good to use if you are also adding cloth physics to your clothing items as you can choose to preserve areas that might be shown when the cloth is moving around - e.g, you can choose to preserve the legs from the knee up if the cloth item is a skirt with physics, as you don't want the avatar's legs to disappear when the skirt is moving.
---
### Boots And Heels
#### Overview[β](#overview "Direct link to Overview")
Boots and shoes with heels require a little more work to set up properly in space.
Boots and shoes with heels require a little more work to set up properly in space. Fortunately, it's easy to do and you should be able to get great results in no time.
First things first. If you have not already familiarized yourself with the basics, check out the Clothing Basics tutorial video below.
***
Now that you're familiar with the basics, try your hand at a pair of high heels or boots with heels. After loading the Space avatar into the scene, add your boots. You should see something that looks like this:
*It's okay, this is perfectly normal!*
Notice in the picture that the boots are lined up so the heel of the foot is aligned with where the heel would go in the boot? That's important - your boots should be at an x/y/z position of 0, 0, 0 and be similarly aligned.
##### Morph Targets[β](#morph-targets "Direct link to Morph Targets")
If you are making boots or shoes that have an exposed foot or open toe design, then you need to adjust a couple settings in order to make the Space avatar's feet fit. If your boots/shoes are an enclosed design, you can skip ahead to the Clothing Item Settings section below.
The first thing you're going to want to do is inspect the Space avatar in your Hierarchy panel. Open up the 2017 Female *(or 2017 Male)* object, and then open the Geo\_grp sections by clicking on the triangle to the left. Now select the femalebody *(or malebody)* object.
Next, in your Inspector panel, click on the triangle to the left of Skinned Mesh Renderer and then click on the triangle next to BlendShapes to expose an avalanche of settings. These let you control various aspects of avatar positioning and shaping, and you are going to scroll to nearly the bottom of that long list to find three specific sets of controls, two of which are important for setting up your footwear:
Slider.high\_heel accepts a value of 0 - 100 and affects the shape of the foot in the heel. A value of zero means no lift, and a value of 100 is an extremely high heel. Play with a setting here to find a number that works best with the shape of your boots or heels.
Slider.archoffeet also accepts a velue of 0-100 and affects the offset *(or crunch)* of the arch. A value of zero means no effect, and a value of 100 is severely crunched.
Make a note of the numbers that work best, and then you can change both values back to zero so that your Space avatar base is at its default values. Next, move on to the Clothing Item Settings below.
##### Clothing Item Settings[β](#clothing-item-settings "Direct link to Clothing Item Settings")
Now go to your boots/shoes object, and look in the Clothing Items Settings script. Click open the triangle for Extra Settings, and then click on the triangle to the word Heel to expose the Extended Heel Settings.
Make sure to tick the box that says Use Heel Settings.
If you have Morph Target settings from the section above, enter your Slider.high\_heel settings under Heel Amount, and Slider.archoffeet under Arch Offset.
For Avatar Center of Mass, enter a number to represent how high the avatar should be raised above the ground. A value of zero is no lift at all, and may result in the bottom of the shoes or boots going beneath the floor or ground terrain. A value of .01 equals 1 centimeter, and a value of 1 equals 1 meter.
Once you've entered those settings that are specific to boots & heels, you can fill out the rest of the info in your Clothing Items Settings and Virtual Goods scripts as you normally would, and everything should look great in-world!
---
### Cloth Physics
#### Overview[β](#overview "Direct link to Overview")
Creating Cloth Physics Cloth Physics needs a skinned mesh, follow the steps in Importing\_and\_Uploading\_Clothing until "convert to skinned".
##### Creating Cloth Physics[β](#creating-cloth-physics "Direct link to Creating Cloth Physics")
Cloth Physics needs a skinned mesh, follow the steps in [Importing\_and\_Uploading\_Clothing](/sinespace-sdk/avatars/clothing/importing-and-uploading-clothing.md) until "convert to skinned". See [Clothing/Clothing\_Item\_Setting](/sinespace-sdk/avatars/clothing/clothing-item-settings.md) for more detail on how to add clothing item setting component and to convert to skinned.
Attaching Cloth component
Once you have the skinned mesh attach the cloth component to the skinned mesh. To do so click on add component and search cloth and select it.
##### Cloth physics properties[β](#cloth-physics-properties "Direct link to Cloth physics properties")
The Cloth component provides a physics-based solution for the simulation of fabrics. Following are the various settings you can adjust.
Stretching Stiffness: Changes the stretching stiffness of the cloth.
Bending Stiffness: Bending stiffness of the cloth.
Use Tethers: Apply constraints that help to prevent the moving cloth particles from going too far away from the fixed ones. This helps to reduce excess stretchiness.
Use Gravity: Should gravitational acceleration be applied to the cloth?
Damping: Motion damping coefficient.
External Acceleration: A constant, external acceleration applied to the cloth.
Random Acceleration: A random, external acceleration applied to the cloth.
World Velocity Scale: How much world-space movement of the character will affect cloth vertices.
World Acceleration Scale: How much world-space acceleration of the character will affect cloth vertices.
Friction: The friction of the cloth when colliding with the character.
Collision Mass Scale: How much to increase mass of colliding particles.
Use Continuous Collision: Enable continuous collision to improve collision stability.
Use Virtual Particles: Add one virtual particle per triangle to improve collision stability.
Solver Frequency: Number of solver iterations per second.
Sleep Threshold: Clothβs sleep threshold.
Capsule Colliders: An array of CapsuleColliders which this Cloth instance should collide with. Sine Space avatars already have capsule and sphere colliders. You do not need to attach any more.
##### Edit Constraints Tool[β](#edit-constraints-tool "Direct link to Edit Constraints Tool")
Selecting Edit Constraints will enter the editor into a mode to edit the constraints applied to each of the vertices in the cloth mesh. All vertices will be coloured based on the current Visualization mode to display the difference between their respective values.
Max Distance: is the distance a vertex is allowed to travel from the skinned mesh vertex position. The SkinnedCloth component ensures that the cloth vertices stay within maxDistance from the skinned mesh vertex positions. If maxDistance is zero, the vertex is not simulated but set to the skinned mesh vertex position. This behavior is useful for fixing the cloth vertex to the skin of an animated character - you will want to do that for any vertices which should not be skinned, or for parts which are somehow fixed to the characterβs body (such as the waist of trousers, fixed by a belt). You can either select or paint constraints and set max distance. For example in a dress you don't want the top to move at all. The bottom below waist to move slightly and the near the legs to move most. You can select the distance for each part as shown below.
##### Preparing and adding Deletion Zones[β](#preparing-and-adding-deletion-zones "Direct link to Preparing and adding Deletion Zones")
##### Add virtual goods script[β](#add-virtual-goods-script "Direct link to Add virtual goods script")
Attach the virtual goods script and complete the submission process.
See [Virtual Goods](/sinespace-sdk/components/virtual-goods.md) for more details on the virtual goods script.
---
### Full Body Replacement Costumes (no custom animations)
#### Overview[β](#overview "Direct link to Overview")
You can upload your own avatars to sinespace to wear as a full body costume.
You can upload your own avatars to sinespace to wear as a full body costume. This tutorial is only for uploading your avatar to Sinespace without custom animations .
1\. Import your avatar into Unity. At the top of Unity, click on 'Assets' then 'Import new asset' and import your avatar. Make sure you have saved your avatar from the 3D software you use to model as a FBX file type.
When you click on this, you will see an Import Menu. Click on the Import button at the bottom.
2\. Click on the avatar FBX in the Project window. Under the Inspector window on the right, make sure that the 'Rig' settings are as shown here:
* Set the Animation Type to Humanoid.
* Set Avatar definition to Create from this model.
If you are uploading anything other than a humanoid, please see the page linked at the top of this tutorial.
3\. Drag your FBX into the hierarchy and click on it. In the Inspector window, you should see this:
Make sure that Root Motion is unchecked .
4\. Drag the FBX back into the project window to make a prefab.
5\. Once you have the prefab in the project window, click on it. In the Inspector window, add the 'Clothing Item Settings' component.
* Pick the skeleton you want the costume to fit to.
* Under clothing, change the clothing type to Rigged clothing. The fitting slots layer should be set to underwear, and Chest and Pelvis should be checked under the fitting slots.
* Under Materials and Patterns, check the 'Keep Materials always' box.
* Check the Costume settings by clicking on the circle on the left of the Costume name.
* Under the Costume settings, there is a setting called Referenced Prefab. Drag the prefab of your avatar into the Root Template box here.
* If you have LOD variants of your avatar, you can add them here.
6\. Hit the Prepare button. If it is successful, the prepare button will say Re-prepare after a second.
7\. Add the virtual good component underneath the clothing item settings.
8\. Under Basic, set the information to this:
9\. Fill in the rest of the virtual good component as you normally would to upload items and hit auto submit to start the upload process. If you are not familiar with the virtual good component, you can see our [Virtual Good](/sinespace-sdk/components/virtual-goods.md) page for more information.
You can check on the upload progress at [curator.sine.space](https://curator.sine.space/).
---
### Full Body Replacement Costumes (with custom animations)
#### Overview[β](#overview "Direct link to Overview")
Since Editor Pack 7, all space users now have the ability to create a full body replacement costume.
Since Editor Pack 7, all space users now have the ability to create a full body replacement costume. The costume allows you to replace the space avatar base mesh with any object you want, such as another human avatar, an animal or an object; You can even use particle systems as your avatar!
There are two parts to getting a costume working in space. You will need to first create or import your replacement costume, and then you will need to build an animator for this replacement costume. For the animations, you will need to create your own custom animations if you wish to use an object or creature as your replacement costume, but if you are using a humanoid as a replacement, you can use the default space animations, but more in detail on this later on in this guide.
##### Creating Your Costume[β](#creating-your-costume "Direct link to Creating Your Costume")
You can create whatever you want to be your replacement costume, whether it be a unicorn, a wrestler or even a fire particle, anything is possible! You can create your own costume in your chosen 3D software and import it into Unity.
###### Exporting From 3D Software[β](#exporting-from-3d-software "Direct link to Exporting From 3D Software")
If you have made your own costume, you will need to export the costume from your chosen 3D software as an FBX file and save it somewhere for importing into Unity later.
###### Importing From Unity Asset Store[β](#importing-from-unity-asset-store "Direct link to Importing From Unity Asset Store")
If you have decided to download an object/model to use as your costume from the Unity Asset Store, then you probably wonβt have to change the format of the model as most models on the asset store are already in FBX format.
Once the asset has downloaded, it will ask you to import the model into Unity. I am using a warrior princess model for this guide.
Make sure you have selected all of the assets by clicking on βAllβ then click on βImportβ. This will make a new folder in your Assets folder with all of the items needed for your costume.
Note: Please make sure you have the rights to use the model from Unity Asset Store.
###### Importing From 3D Software[β](#importing-from-3d-software "Direct link to Importing From 3D Software")
After the above step of exporting from the 3D software as an FBX file, you can import this into Unity by clicking on βAssetsβ and choosing βImport New Assetβ at the top of the Unity screen. Then choose your FBX file. This will place the FBX file into your Assets folder.
##### Setting Up Your Costume For Upload[β](#setting-up-your-costume-for-upload "Direct link to Setting Up Your Costume For Upload")
###### Setting Up A Humanoid Costume[β](#setting-up-a-humanoid-costume "Direct link to Setting Up A Humanoid Costume")
If your costume is a humanoid model, and you want to use it with the default space animations, you need to set it up to work with the animations.
Uncheck the βApply Root Motionβ box. You can do this by clicking on the FBX in your hierarchy and finding the βApply Root Motionβ box in the inspector window. If Apply Root Motion is greyed out, drag the FBX into your scene, then back to the project window to create a prefab.
Click on the FBX file you have imported in the project window, and under the Inspector window, choose βRigβ, and set the animation type to βHumanoidβ. This will enable you to be able to use the default space animations for the replacement costume.
###### Setting up a Non Humanoid Costume with Animator[β](#setting-up-a-non-humanoid-costume-with-animator "Direct link to Setting up a Non Humanoid Costume with Animator")
If you have chosen to use an object or animal as your replacement costume, or you want to create your own animations for a humanoid, you will need to create an animator.
Animators allow you to upload completely custom animations with the replacement costume.
**Making A Controller for the Animator**
Animators need a controller to work, so you need to create a controller. To create a controller, right click in your project window, and choose βCreateβ then βAnimator Controllerβ and begin laying it out.
This is a complex step, but you can use the space editor pack controller as a template for laying out the animators; Just search for βPlayer Controllerβ in the project window.
An animator controller transitions animations based on input variables - we let you insert a few variables in here (we may add more over time). Your animator needs to have all these variables listed - even if it does not use them.
These variables are:
* Magnitude: runs from 0.0 to 1.0 - 0.0 is standing still, 0.5 is walking, 1.0 is running (approximately. These values may deviate from these general bounds.)
* Angle: Runs from -1.0 to 1.0, 0.0 is not turning. -1.0 is turning left, 1.0 is turning right.
* Vertical: The users key input - moving forward/back shifts this value from -1.0 to 1.0
* Horizontal: As per above, except for the left/right keys.
* Fly Vertical: 0.0 is not moving up/down in flight, -1 is descending, 1.0 is ascending.
* Floor Angle: The normal angle of the floor - used for angling feet to match angled surfaces. Currently disabled.
* Is Falling: On/Off - is the user in a falling state
* Is Jump: On/Off - is the user currently jumping
* Is Flying: On/Off - is the user currently flying
See example:
##### Uploading Humanoid Costumes (No Custom Animations)[β](#uploading-humanoid-costumes-no-custom-animations "Direct link to Uploading Humanoid Costumes (No Custom Animations)")
After setting the rig type to humanoid, you can go ahead and upload your costume. To upload it, first create a new empty gameobject in your scene. Click on the gameobject in the hierarchy, and click on βAdd Componentβ in the Inspector window. Search for βClothing Item Settingsβ and click βAddβ. This will bring up the clothing item settings. Make sure to expand the βCostumesβ segment for the next step.
Costumes
For costume uploads. make sure the Costume setting is ticked under Clothing Item Settings. You do not need to use the "Clothing" setting as this will automatically be set.
Costume Settings
Under the Costume settings, there will be a setting called Referenced Prefab. Drag the prefab of the costume into this box to use this as the root template.
There is also LOD Variants listed here. You can put in a High Detail template and a Low Detail Template here. The default is Medium.
Finalise
Before preparing, you may need to rename this empty gameobject to something else, otherwise it wonβt prepare. You can rename it by scrolling to the top of the Inspector window and clicking in the box right at the top. I renamed mine to βWarrior Princessβ.
After renaming, click on βPrepareβ. If it is successful, it will say βRe-Prepareβ after a couple of seconds. Save this as a prefab by dragging the gameobject into your project window.
Uploading
Now you are ready to get the costume uploaded to space. Click on the prefab of your costume in the project window. In the Inspector window, click on βAdd Componentβ and search for βVirtual Goodβ and add it.
Set the content type to βClothingβ and fill in the rest of the information as you see fit. You can pick any category of clothing for the costume, it doesnβt matter which category it is under.
After itβs all filled out, you can click on βAutomatic Submissionβ to get it uploading to space.
##### Uploading Humanoid and Other Costumes with Animator[β](#uploading-humanoid-and-other-costumes-with-animator "Direct link to Uploading Humanoid and Other Costumes with Animator")
To upload a costume with custom animators, follow the upload steps as above, but check βAnimatorβ under the βSlotsβ segment.
Scroll down to custom animations, and drag the animator controller you made into the βControllerβ slot.
You need to insert the names you used for the variables under the Parameters section into the various fields. These are case and syntax sensitive, so copy them exactly as they are.
Note: If you want to create new transitions in the controller, remember to uncheck the "Has ExitTime" in each transition. It is picked by default.
After doing this, follow the steps above to make your costume a virtual good with the virtual goods script, and your costume will get uploading to space.
For more information and tutorials on animations, see below:
* [Humanoid Animation](https://unity3d.com/learn/tutorials/modules/intermediate/live-training-archive/setting-up-a-humanoid-avatar)
* [Animation](https://unity3d.com/learn/tutorials/topics/animation)
* [Unity Learn](https://unity3d.com/learn)
---
### Basic Clothes
#### Overview[β](#overview "Direct link to Overview")
Basic Clothes documentation for Sinespace.
[YouTube video player](https://www.youtube.com/embed/D54FJiKbMaE)
---
### Clothing Extra Pattern
#### Overview[β](#overview "Direct link to Overview")
.png>) Usage When you click the Prepare button you will see the materials removed.
![]()
#### Usage[β](#usage "Direct link to Usage")
When you click the Prepare button you will see the materials removed.
To submit a range of items based on a single clothing mesh but with varied materials and textures, follow the steps on the [Importing and Uploading Clothing](/sinespace-sdk/avatars/clothing/importing-and-uploading-clothing.md); BUT leave "Keep Material Always" unticked.
---
### Clothing Item Settings
#### Overview[β](#overview "Direct link to Overview")
The clothing item setting component is split into different subcategories.
The clothing item setting component is split into different subcategories. Each sub-category has different settings for the clothing and the uploading of the item.
When you have imported your clothing item into Unity, make sure it is selected, go to the Inspector window, click on βAdd Componentβ and search for Clothing to add the Clothing Item Settings component to your clothing item.

As you can see in the above image, there are four main categories: Item, Customisation, Submission and Review; Under each of these main categories are sub-categories.
#### Item[β](#item "Direct link to Item")
Item is where you can change the skeleton of the avatar to match the clothing you are uploading, and you will also see a list of categories to choose from. The list of categories is:
* Clothing
* Costumes
* Skin Material
* Tattoos and Makeup
* Shapes
* Animations and Controllers
Underneath is an explanation for all of these categories and their sub-categories.
#### Clothing[β](#clothing "Direct link to Clothing")
There are six sub-categories of clothing settings under the clothing category. These categories are:
* Fitting and Slots
* Skin and Cloth Deletion
* Materials and Patterns
* Level of Detail
* Automatic Skin Weighting
* Feet Settings
At the top of the clothing settings, you can change the type of clothing you are uploading. The types are Rigged Clothing and Attachments.

#### **Clothing Type**[β](#clothing-type "Direct link to clothing-type")
This is where you choose if your clothing item is a Rigged Clothing or an Attachment.
* Rigged clothing -[ Automatic Skin Wieghting](/sinespace-sdk/avatars/clothing/clothing-item-settings.md#automatic-skin-weighting)
* Attachment - Tick if your item is an attachement. Then select the appropriate bone from "Attach to this bone."
#### **Fitting and Slots**[β](#fitting-and-slots "Direct link to fitting-and-slots")

Fitting and slots is where you will find all the settings for the fit of the clothing and the clothing slots.

* Layer - This is where you can choose the layer of your clothing. For example, underwear would be under the Underwear layer, and a coat would be under the Baggy and Outerwear layer. If you set your clothing as an Underwear layer, it means other clothing can go over them. If you set your item as baggy and outerwear, it means that other items of clothing can be worn under it. For a guide on layers, please see this [layers](/sinespace-sdk/avatars/clothing/layers-guide.md) page.
* Fitting Slots - The avatar slots are where the skeleton will be deleted under the clothing. If you have a t-shirt, for example, and donβt want it worn with other items, you will have to check the upper chest, chest and back slots.
#### **Skin and Clothing Deletion**[β](#skin-and-clothing-deletion "Direct link to skin-and-clothing-deletion")

This is where you can add deletion zones, and preservation zones, recalculate bounds and also change the settings for deletion and tucking, fitting and obscuration tuning.
* Deletion Zone Settings - The deletion zones are used for selecting an area of the avatar which you want to be deleted under clothing. This can be used for certain types of clothing which need a little extra deletion underneath.
* Preservation Zone Settings - Preservation zones are used for selecting an area of the avatar which you want to keep under clothing. This is useful if you have clothing with holes in, e.g. a dress with a slit or a corset with a lace-up back.
* Skip deletion - Tick to avoid all skin deletion being applied.
* Obscuration distance - Compresses the skin under clothing items at hemlines. This allows tight-fitting clothes to squash the avatar slightly where skin emerges from under the cloth.
The default distance is 1 cm. The affected vertices are highlighted in yellow when the item has been prepared.
* 
* Red squares indicate skin that will be deleted. Blue indicates skin that will be deleted if more than two adjacent vertices are red. Yellow indicates skin that will be squeezed in line with the Obscuration distance.

info
These tools are helpful if the automatic skin deletion is not perfect. For instance, with open-topped shoes, the preservation zone can ensure the automatic skin deletion does not remove parts of the foot where it should be visible.
#### **Materials and Patterns**[β](#materials-and-patterns "Direct link to materials-and-patterns")

Materials is where you can set to keep the material always of the clothing or attachment. If you plan to use the pattern system which allows for color and texture variations, leave the βKeep Materials Alwaysβ unticked.
#### **Level of Detail**[β](#level-of-detail "Direct link to level-of-detail")

This is where you can add in the high, medium and low LOD objects of the clothing. If you do not add any, we will set it to medium by default.
#### **Automatic Skin Weighting**[β](#automatic-skin-weighting "Direct link to automatic-skin-weighting")

This is where you will find the settings needed for auto-weighting the clothing.
* Automatic Skin Weighting - This will automatically do the skin weighting for you without you having to do anything manually when you press the button. You can also add in a Custom Template here. This custom template is used if you have manually rigged and weighted clothes to a model in 3D software. You will need to drag the model into the Custom Template box.
* Advanced Weighting Settings - You can change settings for weighting here for better outcomes manually under the advanced weighting settings.
info
This works well for close-fitting items but is less effective with loose items, which will usually be much better if skinned manually.
#### **Feet Settings**[β](#feet-settings "Direct link to feet-settings")

When the 'Use Heel Settings' is ticked, you can alter the heel and avatar placement. You can check the blend shapes on the character archetypes to precisely line up shoes.
Morph Targets is where you enter the data for the Heel Amount, Arch Offset, and Height Offset.
Here is more information on how to set up shoes with [heels](/sinespace-sdk/avatars/clothing/advanced-topics/boots-and-heels.md).
#### Finialise[β](#finialise "Direct link to Finialise")
* Prepare/Re-Prepare - Once clicked, this will show the results of the skin deletion and weighting.
#### Costume[β](#costume "Direct link to Costume")

This is where you can add the options for a full body replacement costume.
* Referenced Prefab - This is where the root template of your costume will be. You will need to drag the costume into the Root Template box. For example, if you have a self-made avatar you want to use in sinespace, you will need to drag this avatar game object into this box.
* LOD Variants - This is where you can drag the low and high poly variants of your costume/avatar.
#### Skin Material[β](#skin-material "Direct link to Skin Material")

This section should only be used if you are adjusting the skin shader with a custom material. If you are just making a skin, we recommend using the tattoo and makeup system.
#### Tattoos and Makeup[β](#tattoos-and-makeup "Direct link to Tattoos and Makeup")

This is where you can add tattoos, make up e.t.c as layers.
* Enabled - Check this box to enable the layers.
* Type - Here you can choose from different types of layers. Overlay will be an overlay layer, Tattoo will be for a tattoo, Make up is for make up, Skin is for a skin overlay layer, and Base Skin layer will replace the original avatar skin.
* Blend - You can choose from a range of blend options here such as darken or soft light, they work a bit like layer masks.
* Default Tint - This is the default tint of the layer. If you want a black tattoo for example, you can set the default tint to black.
* Mask Mode - You have two options here, you can choose Use Albedo Alpha, or Use Albedo Alpha ignoring Albedo.
* Albedo - This is where you drag the texture for the albedo.
* Metal Smoothness - This is where you drag the texture for the metal smoothness.
* Normal - This is where you drag the texture for the normal map
#### Shapes[β](#shapes "Direct link to Shapes")

This is where you can paste the shape data from the client to add a shape preset to your clothing.
#### Animation[β](#animation "Direct link to Animation")

This is where you add the information from your animation controller.
* Animation Overrides - This is where you will state the number of animation overrides, then add the element slot and humanoid animation clip.
* Controller - This is where you drag in your animation controller.
#### Customisation[β](#customisation "Direct link to Customisation")

warning
This field has been replaced by the new βCustomisationβ field on the Virtual Good component.
It is recommended to use that customisation field, but this method will also work.
* Restrict Customisation - If this is ticked, it will restrict customisation of the clothing from other users/creators.
#### Submission[β](#submission "Direct link to Submission")

This is where the final settings for uploading the clothing item are.
* Finalise - You can either click on βPrepareβ to finalise the settings on the clothing, or you can click on βRecalculate Occlusionβ to recalculate the occlusion.
#### Review[β](#review "Direct link to Review")

This is where you can see the performance score, which is a quick estimate of the GPU and CPU power required to render the item. You can also change the Type Override to see an estimate of GPU and CPU power for similar items such as shorts, dresses or jackets.
Once all of these settings have been set, you need to add the Virtual Good component to the clothing item to upload to Sinespace.
---
### Template
#### Overview[β](#overview "Direct link to Overview")
Included in the Editor Pack are several template avatar models that can be used when making new content.
Included in the Editor Pack are several template avatar models that can be used when making new content. These can be found in Assets/SpacePack/Artist Project/Avatar Art/Templates. It is recommended to make a copy of the model to import into your program of choice in order to avoid accidentally saving over it.
Until further notice, the 2015 or 2017 templates should be used, as the 2019 avatar models are unfinished.
---
### Clothing Variations
#### Overview[β](#overview "Direct link to Overview")
To submit a range of items based on a single clothing mesh but with varied materials and textures, follow the steps on the Importing and Uploading Clothing; BUT leave "Keep Material Always" unticked.
To submit a range of items based on a single clothing mesh but with varied materials and textures, follow the steps on the [Importing and Uploading Clothing](/sinespace-sdk/avatars/clothing/importing-and-uploading-clothing.md); BUT leave "Keep Material Always" unticked.
When you click the Prepare button you will see the materials removed.
Submit the item and you will see an ID is assigned to the item;
##### Clothing Extra Pattern Component[β](#clothing-extra-pattern-component "Direct link to Clothing Extra Pattern Component")
Create an empty game object in your project.
This component applies to any furniture item also.
Attach the Clothing Extra Pattern component to it.
Enter the ID of the mesh object submitted above to the Item ID field.
The default settings allow for one material per item. If you need more than one material per item change the materials index from 0 to how many additional ones you need for that item.
Select or drag in the materials for the base item. For example, if all your different versions make use of the same normal or height maps, you do not need to put them into the Extra Pattern component, they will get that information from the master pattern. If a map does change from one version to the next *(a leather boot versus a metallic one, for example)*, then select or drag in the materials that are specific to that version in the element material slot/s.
Shader path - *(do not touch this setting)*
##### Virtual Good Component[β](#virtual-good-component "Direct link to Virtual Good Component")
It is worth mentioning that clothing variations will inherit the Product Name, Description, and Price from the Parent Clothing Item.
Add the virtual good script and submit.
See here for more on the [Virtual Goods](/sinespace-sdk/components/virtual-goods.md) script.
For multiple variations you can duplicate and modify this object in the project folder (ctrl + d), though do make sure to clear out the Resume ID if the item you are duplicating has already been uploaded to the server.
Please note that if you duplicate a virtual good that has already been submitted and has an ID, you need to wipe the ID in the Virtual Good script and change the product name before resubmitting as a new item.
---
### Creating Clothing Patterns
#### Overview[β](#overview "Direct link to Overview")
You can have a set of different colors or patterns for clothing in space.
You can have a set of different colors or patterns for clothing in space.
#### Uploading a Base Clothing Mesh[β](#uploading-a-base-clothing-mesh "Direct link to Uploading a Base Clothing Mesh")
To set your clothing item up to have different patterns, first choose a main clothing mesh which you wish to recolor.
When you have chosen the clothing you want, you need to add the 'Clothing Item Settings' component. Do this by clicking on 'Add Component' in the Inspector window and search for clothing item settings.
Once this is done, you can then select all the slots needed for your item. I am using a vest top, so I have selected the chest and upper chest slots. Remember, if you want other items to be used with your clothing, don't select the slots for these items, such as back for wings, wrists/arms for bracelet e.t.c.

Make sure you leave 'keep material always' unchecked for making extra patterns as you just want the base mesh to upload.
follow [Importing and Uploading Clothing](/sinespace-sdk/avatars/clothing/importing-and-uploading-clothing.md) from 'Steps of Uploading' to upload your clothing item to space.
When it has finished processing and it's in space, make a note of the curator ID in Unity for your clothing item. You can find the curator ID at the bottom of the virtual good component, or you can click on 'Space' at the top of Unity and choose 'Items and Status' to see the ID.

#### Creating the Extra Patterns[β](#creating-the-extra-patterns "Direct link to Creating the Extra Patterns")
To create the extra patterns, you need to first create an empty game object in your scene by right clicking in the hierarchy and choosing 'Create Empty'. You can rename this to the clothing item and color you are going to use. For example, if you have a dress and you want one of the patterns to be a plain blue, you can rename the empty object as 'Dress - Blue'. This will help you differentiate between other patterns of the same clothing item.
***Note*** You will need to use the UV map of the clothing item to make color variations in Photoshop or similar software for the patterns.
Make sure your empty game object is selected and in the Inspector window, click on 'Add Component' and search for 'Clothing extra pattern'. This will bring up the component in the Inspector window.
**Parent Clothing Item**
This is where you put the Item ID of the clothing item, for example as shown above, mine is 2107941, so put the ID number generated for your item here.
**Textures**
* Diffuse - This is where you will but the diffuse map for your clothing. This contains the color you want to use.
* Specular or metallic - This is for a specular or metallic map.
* Normal Map - This is where to put the normal map/bump map.
* Height Map - This is for a height map.
* Occlusion - This is for an Occlusion map.
* Emission - This will be for the emission map.
* Detail Mask - This is for the detail mask map.
* Customisations Slots - This is for choosing to make the item customisable with the choice of no slots or three slots.
You will need to drag diffuse map into the diffuse box, and then repeat the step for any other maps you are using.
#### Uploading the Extra Pattern[β](#uploading-the-extra-pattern "Direct link to Uploading the Extra Pattern")
Click on 'Add Component' under the extra pattern component in the Inspector window and search for 'virtual good' and add this to your empty object.
Once this is done you can add in the details for this pattern. For example, I named my item Vest top - Blue, and then filled in all the other details. Drag the item from the hierarchy into the project window to make it a prefab before clicking on auto submit.
Don't add any ID to this item, as it will be generated when you auto submit this item to space.
You can duplicate the prefab to make it easier for you to make multiple recolors; Just right click on the recolor in the heirarchy and choose duplicate. Remember to rename the copies to the color they will be to avoid confusion, and also remember to drag these new recolors into your project window to make a prefab before uploading to space.
Watch a visual guide to these steps:
[YouTube video player](https://www.youtube.com/embed/o5ETgeNAeEc)
---
### Designing Detailed Clothing
#### Overview[β](#overview "Direct link to Overview")
This guide covers best practices for clothing and outfit creation, using the Vlad outfit as an example. The workflow focuses on current game-character modelling practices: low-poly runtime meshes, high-detail source meshes for normal maps, PBR textures, tessellation where it helps, and careful weighting for avatar movement.
The outfit showcases these areas:
* Model creation
* Tessellation
* PBR textures
* Sinespace custom clothing shaders
* Weighting and skinning
* Pattern variations
#### Model Creation[β](#model-creation "Direct link to Model Creation")
We recommend following current game-character modelling practices: use PBR texturing tools and low-poly models with a high-detail normal map.
The Vlad outfit was created with high-detail models totalling roughly 1 million polygons to create normal and tangent maps, and low-detail models totalling roughly 12,000 polygons for upload to Sinespace.
Useful tutorials:
* [Designing a Base Mesh](https://www.youtube.com/watch?v=oXEPHVEm5wM)
* [Customizing a 3D Body in ZBrush and Blender](https://www.youtube.com/watch?v=eCAbA94vaJU)
* [Modeling 3D Clothes in ZBrush and Blender](https://www.youtube.com/watch?v=XGCIuVb8kxA)
* [Texturing the Clothes in Substance Painter](https://www.youtube.com/watch?v=P8WBaubooX4)
* [Designing Detailed Clothing](https://www.youtube.com/watch?v=OYyK4y_6lZw)
#### Tessellation[β](#tessellation "Direct link to Tessellation")
Tessellation shaders let you create multi-million-poly details across a model with very little performance impact. They are useful for ultra-smooth surfaces that can be viewed closely.
The usual workflow is to upload a low-poly, high-performance model, then use the Sinespace tessellation shader to make it appear as a high-detail, smooth asset in-world.
Tessellation shaders create dynamic detail controlled by camera distance. They use Phong tessellation to help hard edges become rounded during tessellation.
##### Phong Smoothing[β](#phong-smoothing "Direct link to Phong Smoothing")
The Phong strength setting ranges from `0.1` to `1.0`: `0.1` is minimal smoothing, and `1.0` is maximum smoothing. We recommend setting Phong strength between `0.1` and `0.3` for the best results. Higher values may introduce artefacts, especially when the model animates.
Make sure your renderer is set to **Skinned** when adjusting these settings. Otherwise, the values you set may look different in-world.
#### Avoiding Tessellation Seams[β](#avoiding-tessellation-seams "Direct link to Avoiding Tessellation Seams")
Paint red on all vertices that run along UV seams.
Phong tessellation can fail on UV seams where the vertices are not connected. This creates gaps in the mesh around the UV seams.
The Sinespace tessellation shader supports excluded zones. To exclude a vertex from tessellation, paint the vertex colour pure red (`255,0,0`) in your 3D modelling tool. The shader will avoid separating the mesh in that area.
#### Tessellation or Geometry?[β](#tessellation-or-geometry "Direct link to Tessellation or Geometry?")
Tessellation height maps can introduce complex patterns that would otherwise require extreme polygon counts, such as fabric ruffles, distressed surfaces, or wrinkles. They work best with organic patterns that do not contain hard edges, unless those edges are slightly rounded.
As a guide, set **Tessellation Edge** between `5` and `15`. Higher values are much better for performance; `15` is significantly cheaper than `5`. Unless you are using a height map, there is usually no reason to go below `15`, because the result should already appear smooth.
Avoid setting **Tessellation Edge** to `1`.
Hard-edged non-organic shapes should use basic geometry rather than tessellation. Bitmapped height maps can introduce unwanted noise on hard-edged shapes.
Basic tessellation with smoothing is excellent for rounding very smooth surfaces, such as shoes or other elements that need softened corners.
#### Sinespace Custom Clothing Shader[β](#sinespace-custom-clothing-shader "Direct link to Sinespace Custom Clothing Shader")
Sinespace supplies a custom shader for clothing tessellation in the editor pack. Search for **Unified Clothing and Skin (Metal and Tessellate)** and add that shader to your clothing material.
For more detail, see [Unified Clothing and Skin (Metal and Tessellate)](/sinespace-sdk/avatars/unified-clothing-and-skin-metal-and-tessellate.md).
[]()
#### Weighting and Rigging[β](#weighting-and-rigging "Direct link to Weighting and Rigging")
Use skin weight transfer if you have non-skin-tight clothing, such as dresses or baggy items. Then reweight by hand as appropriate.
You can use the automated skinning system built into the clothing component if your clothing item is skin-tight.
#### Physically Based Rendering (PBR)[β](#physically-based-rendering-pbr "Direct link to Physically Based Rendering (PBR)")
##### Background[β](#background "Direct link to Background")
PBR lets you accurately simulate a wide range of materials. It carries through energy conservation, so avatars look better across different lighting environments and maintain a more realistic look.
Sinespace PBR maps follow a Metalness/Smoothness workflow based on the Unity 5 Standard Shader. Specular/Smoothness workflows can also work well.
Useful PBR references:
* [Physically based shading in Unity 5](https://blogs.unity3d.com/2014/10/29/physically-based-shading-in-unity-5-a-primer/)
* [Working with PBR in Unity](https://unity3d.com/learn/tutorials/modules/intermediate/graphics/substance/01-02-working-with-pbr-in-unity)
* [Basic theory of physically based rendering](https://www.marmoset.co/posts/basic-theory-of-physically-based-rendering/)
* [Working with physically based shading - A practical approach](https://blogs.unity3d.com/2015/02/18/working-with-physically-based-shading-a-practical-approach/)
##### Creating PBR Textures[β](#creating-pbr-textures "Direct link to Creating PBR Textures")
Recommended tools for creating PBR textures:
* [Quixel Suite](http://quixel.se/)
* [Substance Painter](https://www.allegorithmic.com/products/substance-painter)
* [Marmoset](https://www.marmoset.co/)
You can also use Photoshop. Photoshop cannot preview the final PBR result directly, but you can edit textures there and preview the results on your model in the Unity editor. Marmoset can be used to preview PBR textures while editing in Photoshop.
#### Patterns[β](#patterns "Direct link to Patterns")
For adding additional patterns to your clothing, see [Creating Clothing Patterns](/sinespace-sdk/avatars/clothing/creating-clothing-patterns.md).
---
### Female Clothing Resource Files
#### Overview[β](#overview "Direct link to Overview")
Here you can find the clothing resource files for female avatars.
Here you can find the clothing resource files for female avatars. All of the below resource file zips include an FBX of the item, TGA files for height map, normal map and occlusion and .PNG files for the patterns/textures. All of these clothing files are owned by Sinespace. We will be adding to the list when more Sinespace clothing is released.
These resource files can be used to make different pattern variations of the clothing.
| 50s silk neck tie | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/50s%20Silk%20Neck%20Tie.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/50s%20Silk%20Necktie.spp) |  |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Air hostess outfit | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Air%20hostess%20outfit.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Air%20Hostess%20Outfit.spp) |  |
| Beach skirt | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Beach%20Skirt.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Beach%20Skirt.spp) |  |
| Beach top | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Beach%20Top.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Beach%20Top.spp) |  |
| Bikini Shorts | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Bikini%20Shorts.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Bikini%20Shorts.spp) |  |
| Bikini Top | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Bikini%20Top.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Bikini%20Top.spp) |  |
| Bikini with sarong top | [Source Files](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Bikini%20with%20Sarong%20Top.spp) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Bikini%20Top.spp) |  |
| Bikini with sarong | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Bikini%20with%20sarong.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Bikini%20ith%20Sarong.spp) |  |
| Cardigan with top | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Cardigan%20with%20Top.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Cardigan%20with%20Top.spp) |  |
| Fitted shirt | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Fitted%20Shirt.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Fitted%20Shirt.spp) |  |
| Flip flops | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Flip%20Flops.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Flip%20Flops2.spp) |  |
| Flippers | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Flippers.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Flippers2.spp) |  |
| Full swimsuit | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Full%20Swimsuit.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Full%20Swimsuit.spp) |  |
| Leather pants | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Leather%20Pants.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Leather%20Pants.spp) |  |
| Mary Janes | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Mary%20Janes.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Mary%20Janes.spp) |  |
| Pant suit jacket | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Pant%20Suit%20Jacket.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Pant%20Suit%20Jacket.spp) |  |
| Pant suit Open Jacket | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Pant%20Suit%20Open%20Jacket.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Pant%20Suit%20Open%20Jacket.spp) |  |
| Pant suit open pants | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Pant%20Suit%20Open%20Pant.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Pant%20Suit%20Open%20Pants.spp) |  |
| Pant suit Pants | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Pant%20Suit%20Pants.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Pant%20Suit%20Pants.spp) |  |
| Patent court shoes | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Patent%20Court%20Shoes.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Patent%20Court%20Shoes.spp) |  |
| Patterned pants | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Patterned%20Pants.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Patterned%20Pants.spp) |  |
| Sexy Outfit | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Sexy.zip) | [Hat](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Sexy%20Hat.spp) [Jacket](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Sexy%20Jacket.spp) [Lian](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Sexy%20Lian.spp) [Pants](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Sexy%20Pants.spp) [Shoes](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Sexy%20Shoes.spp) |  |
| Silk scarf front knot | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Silk%20Scarf%20Front%20Knot.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Silk%20Scarf%20Front%20Knot.spp) |  |
| Silk scarf one tassle | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Silk%20Scarf%20One%20Tassle.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Silk%20Scarf%20One%20Tassle.spp) |  |
| Skirt suit jacket | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Skirt%20Suit%20jacket.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Skirt%20Suit%20Jacket.spp) |  |
| Skirt suit skirt | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Skirt%20Suit%20Skirt.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Skirt%20Suit%20Skirt.spp) |  |
| Snorkel | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Snorkel.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Snorkel%20F.spp) |  |
| sequined pants top and bottom | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/squinted%20pants%20top%20and%20bottom.zip) | [Shorts](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Squinted%20Shorts.spp) [Top](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Squinted%20Top.spp) |  |
| street female | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/street%20female.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Street%20Female.spp) |  |
| Studded leather vest | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Studded%20Leather%20Vest.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Studded%20Leather%20Vest.spp) |  |
| Suede ballet flats | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Suede%20Ballet%20Flats.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Suede%20Ballet%20Flats.spp) |  |
| Thick heeled shoes | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Thick%20Heeled%20Shoes.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Thick%20Heeled%20Shoes.spp) |  |
| Tied jacket with vest | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Tied%20Jacket%20with%20Vest.zip) | [Original](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Tied%20Jacket%20with%20Vest.spp) [Revised](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Tied%20Jacket%20With%20Vest%20Revised.spp) |  |
| womens camo capris | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Womens%20Camo%20Capris.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Womens%20Camo%20Capris.spp) |  |
| womens emo vest | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Womens%20Emo%20Vest.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Womens%20Emo%20Vest.spp) |  |
| womens polo hoodie | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Womens%20Polo%20Hoodie.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Womens%20Polo%20Hoodie.spp) |  |
| womens shorts with cat belt | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Womens%20Shorts%20With%20Cat%20Belt.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Womens%20Shorts%20with%20Cat%20Belt.spp) |  |
| yoga pants | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Yoga%20Pants.zip) | [Substance Painter Project](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Yoga%20Pants.spp) |  |
| Vlad Outfit | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Female%20Clothing%20Resources/Vlad%20Outfit%20Resource.zip) | [Glasses](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Vlad%20Glasses.spp) [Gloves](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Vlad%20Gloves.spp) [Hat](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Vlad%20Hat.spp) [Jacket](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Vlad%20Jacket.spp) [Necklace](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Vlad%20Necklace.spp) [Pants](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Vlad%20Pants.spp) [Shoes](http://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Vlad%20Shoes.spp) |  |
---
### Female Hair Resource Files
#### Overview[β](#overview "Direct link to Overview")
This page lists source files for female avatar hair resources. The resource ZIP files include pattern or texture PNG files, a Unity package, and an FBX. These hair files are owned by Sinespace.
#### Resource Files[β](#resource-files "Direct link to Resource Files")
| Hair | Source files | Preview |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Blunt Fringe Bob | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Womens%20Blunt%20Fringed%20Bob.zip) |  |
| Bob | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Womens%20Bob.zip) | Preview unavailable |
| Emo Bob | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Womens%20Emo%20Bob.zip) |  |
| Womens' Emo Hair | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Womens%20Emo%20Hair.zip) |  |
| Rave Dancer | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Womens%20Rave%20Dancer%20Hair.zip) |  |
| Striped Hair with Bow | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Womens%20Striped%20Hair.zip) |  |
| Womens' Ponytail | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Womens%20Ponytail.zip) |  |
| Wavy Bob | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Womens%20Wavy%20Bob.zip) |  |
---
### Importing and Uploading Clothing
#### Overview[β](#overview "Direct link to Overview")
Importing and Uploading Clothing This is in the middle of an update.
#### Importing and Uploading Clothing[β](#importing-and-uploading-clothing "Direct link to Importing and Uploading Clothing")
This is in the middle of an update. Please ask for any help needed. Discord fashion and clothing.
You can make clothing for your avatars in Sinespace by using any 3D software of your choice. You can use the avatars from the editor pack as a reference for your clothing; Just import it into your software and start making your clothing! Once your clothing is made, you can export the clothing as obj or fbx files, save it anywhere you want, and from there, you can setup your scene ready for importing your clothing item for upload.
##### Setting Up Your Unity Scene For Uploading[β](#setting-up-your-unity-scene-for-uploading "Direct link to Setting Up Your Unity Scene For Uploading")
Make sure you put the same reference avatar (male or female) you used to make clothing into your scene, just in case you need it for resizing your item or any other changes.
##### Importing Your Clothing Item[β](#importing-your-clothing-item "Direct link to Importing Your Clothing Item")
You will need to import your clothing item into the scene as well. First, go to Assets at the top of Unity, and then on the dropdown menu, choose Import Asset. This will open up your Explorer, and you can find your clothing item which you saved as an obj/fbx file. Once found, you can click on Import, and the item will be dropped into the main Assets folder. You can create a new folder and name it for organisation of your items.

###### Manually Rigged Clothing[β](#manually-rigged-clothing "Direct link to Manually Rigged Clothing")
If you are importing manually rigged clothing, make sure your mesh is exported with a Location of <0.0,0.0,0.0> and Scale of <1.0, 1.0, 1.0> and Rotation of <-90,0,0>, and to tick "Experimental" and press apply transform in Export Settings.
 
##### Steps of Uploading[β](#steps-of-uploading "Direct link to Steps of Uploading")
Open the folder you put your item in in Unity, and find the obj/fbx file. Drag this file into the Unity hierarchy. The Space avatar should be listed there too.

This should automatically fit your clothing to the avatar, but if it doesnβt, you might have to change the scale of the item under its Import Settings to 0.01. You can access the Import Settings by clicking the item in its Unity folder. If you used Blender to make the clothing, then the clothing should be the right scale already.

2\. Click on the clothing item in the hierarchy, and under the Inspector window on the right hand side of the screen, click on Add Component and search for Clothing Item Settings and add it.

This will add Clothing Items Settings under the Inspector window. Please see the [Clothing Item Setting](/sinespace-sdk/avatars/clothing/clothing-item-settings.md) page to see what each part of the clothing settings does.

Skeleton Selection
The skeleton selection needs to be set to the same skeleton you used for making the clothing, so if you chose the female Space avatar, you will need to set this to Base Female, and if you used the male avatar, you will need to set this to Base Male.
Fitting and slots
You can choose the layer of your clothing here and also set the slots for the item. If you set the layer to 'Underwear' for example, this means other clothing with different layers can go over the top of your clothing. If you set the layer to 'Outwear', other clothing can go underneath it. For items like jeans and t-shirts, 'Close Fitting' is a good layer to set it to.
You will need to check the slots of the item. The avatar slots are where the skeleton will be deleted under the clothing. If you have a t-shirt for example, and donβt want it to be worn with other items, you will have to check the upper chest, chest and back slots
Skin and Cloth Deletion
This is where you can add deletion zones, preservation zones, recalculate bounds and also change the settings for deletion and tucking, fitting and obscuration tuning.
* Deletion Zone Settings - The deletion zones are used for selecting an area of the avatar which you want to be deleted under clothing. This can be used for certain types of clothing which need a little extra deletion underneath.
* Preservation Zone Settings - Preservation zones are used for selecting an area of the avatar which you want to keep under clothing. This is useful if you have clothing with holes in, e.g, a dress with a slit or a corset with a lace-up back.
Materials and patterns
You will need to check this option so the material on your clothing will be visible when you upload your item. Please leave this unchecked if you plan on adding pattern variations.
Level of Detail

This setting is optional. If you want to include high, medium and low detail you can do so here by dragging in the game object containing the SkinnedMeshRender component. If you do not want to include these, the default LOD for your clothing item will be medium.
Automatic Skin Weighting

When you have hit 'Prepare' on your clothing item, you can come back to this setting and re-weight the item or change the advanced weighting settings.
Feet Settings

You only need to use this setting if you are uploading high heels and need to adjust the heel height and avatar placement.
Clothing Settings - Customisation tab

Here you can restrict other users from customizing your items.
##### Preparing the Clothing[β](#preparing-the-clothing "Direct link to Preparing the Clothing")
To prepare the clothing, all you need to do is click the big blue prepare button to get the clothing ready to upload. This will add all of the weighting settings and all of your other settings.

##### Making the Prefab[β](#making-the-prefab "Direct link to Making the Prefab")
A prefab of your item is needed for uploading. To make a prefab, simply drag your item from the hierarchy into the project folder.

##### Setting up the Prefab for Upload[β](#setting-up-the-prefab-for-upload "Direct link to Setting up the Prefab for Upload")
The prefab will be selected already from dragging and dropping into the project window. With it selected, you will see it has all the same information under the Inspector window as the original obj/fbx file. Underneath the clothing item setting component, you will see another Add Component button. Click on it, and search for Virtual Good and add it. Adding the Virtual Good will allow you to set your clothing item as a salable good in Sinespace.
##### Virtual Good Settings[β](#virtual-good-settings "Direct link to Virtual Good Settings")
Once you have added the virtual good component, you can go to our [Virtual Goods](/sinespace-sdk/components/virtual-goods.md) page to see how this component works. This is used to upload your item to Sinespace.
For clothing, under the Basic tab of the virtual good component, set the Type to Clothing, then choose the appropriate category. The rest of the virtual good component you can fill out how you want to.

To check on your items' upload progress, go to our [curator site](https://curator.sine.space/).
#### Video/Basic Clothes[β](#videobasic-clothes "Direct link to Video/Basic Clothes")
This tutorial shows you how to set up clothing and import clothing into Space.
[YouTube video player](https://www.youtube.com/embed/D54FJiKbMaE)
---
### Layers Guide
#### Overview[β](#overview "Direct link to Overview")
When preparing a clothing item for upload, you need to make some choices in where the item will go and how the item will fit on the avatar.
When preparing a clothing item for upload, you need to make some choices in where the item will go and how the item will fit on the avatar. This allows users to easily change clothes as well as mix and match outfits from different creators to create their own unique looks.
Space allows users to wear one item per clothing layer in each slot, on their avatar's skeleton. You set this up in the Clothing Item Settings component on the Item -> Clothing -> Fitting tab *(see the pc below)*. When creating an item to be worn, you start with the skeleton, leave the second drop-down menu at the default of Rigged Clothing when creating clothing items, and then choose the clothing layer and which slot *(or slots)* to use.
Note: The Chest(include Upper Chest) and Pelvis slots are a little special, they control whether the avatar will be masked if the necessary slot is empty, i.e., male character need at least wear a pants and female need pants and top wear, or the avatar will be blue masked. So if you're creating some clothing items not covering the sensitive parts of human body, you shouldn't pick the chest, upper chest and pelvis slot, or it will cause the item against the Review Policies. Actually, you can leave those slots blank if you have no idea where to put your items on, especially for the attachment-type clothing items.

Skeleton Selection
Choose the relevant skeleton for your clothing item. Please note Space supports multiple third-party skeletons as well as its own native male and female models. Your item will only appear in the store or the wardrobe for a user wearing that particular skeleton.
Clothing Layer
Set the clothing item to one of five sorting layers.
Mesh deletion and tucking of clothing items is applied dynamically in accordance with this layer.
So if a user wears a pair of boots set to "Close Fitting" worn with a pair of pants set to "Skintight," the pants mesh will be deleted inside the boots.
If the user then changes to a different pair of pants set to "Loose Fitting" the same pair of boots will then be deleted inside the pants.
![]()
Slots
Tick the slots your clothing item should occupy. When a user puts on an item, it will automatically remove other clothing items that occupy the same slot. Be careful not to select slots unnecessarily; for instance, a normal jacket would cover chest and uppper chest. But selecting back as well would prevent users from wearing the jacket with a backpack or wings.
#### Layers & Slots Guide[β](#layers--slots-guide "Direct link to Layers & Slots Guide")
Below is a list of some of the clothing items that are typically worn on each clothing layer.
###### Underwear[β](#underwear "Direct link to Underwear")
* Stockings, Socks
* Panties
* Layering Lace Tops
* Glitch Pants
* Tattoos
###### Skintight[β](#skintight "Direct link to Skintight")
* Collar Shirt *(tucked in)*
* Bodice
* Bikini
* Boots & Shoes *(worn under pants)*
###### Close Fitting[β](#close-fitting "Direct link to Close Fitting")
* Pants
* Skirt
* Shorts
###### Loose Fitting[β](#loose-fitting "Direct link to Loose Fitting")
* Corset
* Waistcoat/Vest
* Shirts *(untucked)*
###### Baggy And Outerwear[β](#baggy-and-outerwear "Direct link to Baggy And Outerwear")
* Coats
* Boots *(worn over pants)*
* Belts
* Jackets
Below is a list of what slots some of the SineSpace creators are standardizing for different types of clothing. Following this guide can not only take away some of the guesswork, but also make it easier for your customers and friends to wear your creations with other parts of their wardrobe. This list will grow over time, as more designers discover what works best for them.
* Neck - cravat, scarf, neckwear
* Chest - shirt, waistcoat/vest, corset, jacket/coat
* Back - backpacks, wings
* pelvis - stocking, skirts, pants
* right/left hand - gloves & mittens
* right/left foot - shoes, boots
---
### Male Clothing Resource Files
#### Overview[β](#overview "Direct link to Overview")
Here you can find the clothing resource files for male avatars.
Here you can find the clothing resource files for male avatars. All of the below resource file zips include an FBX of the item, TGA files for height map, normal map and occlusion and .PNG files for the patterns/textures. All of these clothing files are owned by Sinespace. We will be adding to the list when more Sinespace clothing is released.
##### Zip Files[β](#zip-files "Direct link to Zip Files")
| Beige Suit Jacket | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Beige%20Suit%20jacket.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Beige%20Suit%20Jacket.spp) |  |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| Beige Suit Pant | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Beige%20Suit%20pant.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Beige%20Suit%20Pants.spp) |  |
| Black Brogue Shoes | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Black%20Brogue%20Shoes.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Black%20Brogue%20Shoes.spp) |  |
| Black Dress Shoes with Buckle | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Black%20Dress%20Shoes%20With%20Buckle.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Black%20Dress%20Shoes%20with%20Buckle.spp) |  |
| Black Suit Jacket | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Black%20Suit%20jacket.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Black%20Suit%20Jacket.spp) |  |
| Black Suit Pant | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Black%20Suit%20pant.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Black%20Suit%20Pants.spp) |  |
| Boardshorts | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Boardshorts.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Mens%20Board%20Shorts.spp) |  |
| Brown Slip on Dress Shoes | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Brown%20Slip%20on%20Dress%20Shoes.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Brown%20Slip%20on%20Dress%20Shoes.spp) |  |
| Checkered Suit Jacket | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Checkered%20Suit%20jacket.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Checkered%20Suit%20Jacket.spp) |  |
| Checkered Suit Pant | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Checkered%20Suit%20pant.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Checkered%20Suit%20Pants.spp) |  |
| Flippers | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Flippers.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Flippers.spp) |  |
| Hooded Jacket | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Hooded%20Jacket.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Hooded%20Jacket.spp) |  |
| Longer Boardshorts | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Longer%20Boardshorts.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Longer%20Board%20Shorts.spp) |  |
| Mens Baggy Cutoffs | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Mens%20Baggy%20Cutoffs.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Mens%20Baggy%20Cutoffs.spp) |  |
| Mens Bomber Vest with Shirt | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Mens%20Bomber%20Vest%20With%20Shirt.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Mens%20Bomber%20Vest%20with%20Shirt.spp) |  |
| Mens Emo Drainpipe Trousers | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Mens%20Emo%20Drainpipe%20Trousers.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Mens%20Emo%20Drainpipe%20Trousers.spp) |  |
| Mens Emo Spiked Vest | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Mens%20Emo%20Spiked%20Vest.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Mens%20Emo%20Spiked%20Vest.spp) |  |
| Office Pants | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Office%20Pants.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Office%20Pants.spp) |  |
| Open Collar Suit | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Open%20Collar%20Suit.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Open%20Collar%20Suit.spp) |  |
| Scifi Male | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Scifi%20Male.zip) | Substance Files: [Hat](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Sci%20Fi%20Male%20Hat.spp) [Jacket](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Sci%20Fi%20Male%20Jacket.spp) [Pants](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Sci%20Fi%20Male%20Pants.spp) |  |
| Shirt with Woolen Vest | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Shirt%20with%20Woolen%20Vest.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Shirt%20and%20Tie%20with%20Woolen%20Vest.spp) |  |
| Snorkel | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Snorkel.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Snorkel.spp) |  |
| Street male | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/street%20male.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Street%20Male.spp) |  |
| Track Pants | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Clothing%20Resources/Track%20Pants.zip) | [Substance Painter Project](https://space-files.s3.amazonaws.com/sample-art/substance-templates/clothing/Track%20Pants.spp) |  |
---
### Male Hair Resource Files
#### Overview[β](#overview "Direct link to Overview")
This page lists source files for male avatar hair resources. The resource ZIP files include pattern or texture PNG files, a Unity package, and an FBX. These hair files are owned by Sinespace.
#### Resource Files[β](#resource-files "Direct link to Resource Files")
| Hair | Source files | Preview |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ |
| Mens' Combed Back | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Combed%20Back.zip) |  |
| Mens' Ponytail | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Mens%20Ponytail.zip) |  |
| Mens' Side Fringe | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Mens%20Emo%20Side%20Fringe.zip) |  |
| Let Hair Rule | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Hair01Male.zip) |  |
| Treat Me | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Hair03Male.zip) |  |
| Mens' Bandana | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Mens%20Hair%20with%20Bandana.zip) |  |
| Mens' Emo Hair | [Source Files](https://space-files.s3.amazonaws.com/wiki%20resources/Male%20Hair%20Resources/Mens%20Emo%20Hair.zip) |  |
---
### Gestures
#### Overview[β](#overview "Direct link to Overview")
The gesture system in Space allows you to create, publish and sell a range of animations and choreographed multi-user interactions.
The gesture system in Space allows you to create, publish and sell a range of animations and choreographed multi-user interactions.
##### Key Articles[β](#key-articles "Direct link to Key Articles")
* **Gestures Home**
* [Setting Up](/sinespace-sdk/avatars/gestures/set-up.md)
* [Single Person](/sinespace-sdk/avatars/gestures/single-person-animation.md)
* [Multi Person](/sinespace-sdk/avatars/gestures/multi-person-animations.md)
* [Animated Cameras](/sinespace-sdk/avatars/gestures/animated-cameras.md)
* [Props](/sinespace-sdk/avatars/gestures/props.md)
* [Special FX](/sinespace-sdk/avatars/gestures/visual-fx.md)
---
### Animated Cameras
#### Overview[β](#overview "Direct link to Overview")
You can animate the camera in concert with the character animations in your gesture.
You can animate the camera in concert with the character animations in your gesture.
There are two options;
* Avatar Effect Camera Script - create an animated path from a start and end point in Unity
* Avatar Effect Camera Movement Script - import an animation for the camera from another application.
##### Option 1 - Avatar Effect Camera Script[β](#option-1---avatar-effect-camera-script "Direct link to Option 1 - Avatar Effect Camera Script")
This component is accessed via the Unity Component menu, then select Avatar Effects and then "Camera Follow Character".

Start position and Duration
You can set a start position and duration for the camera here.
Rails Type
Linear will move the camera straight from start point to end point. Rotation will move around the avatar.
Interpolation
Choose either Linear or Smooth.
Offsets
The offsets allow you to place the camera in relation to the avatar. Y+ is up. Z+ is forward.
So; X0, Y1, Z2 will put the camera 1 meter above ground, 2 meters in front of the avatar.
Tracking Options
The tracking options will animate the camera in line with the selected bone (Tracking target).
Tracking Target
Start / End Avatar - For two person gestures you can move the camera target from one avatar to the other.
Start - End Target - You can move the camera's focus from one bone to another over the duration of the gesture.
##### Option 2 - Avatar Effect Camera Movement Script[β](#option-2---avatar-effect-camera-movement-script "Direct link to Option 2 - Avatar Effect Camera Movement Script")
This component is accessed via the Unity Component menu, then select Avatar Effects and then "Camera Follow Path".
You can apply animation from an fbx file to the camera using the Avatar Effect Camera Movement Script.

Legacy Animation Clip
Drag the fbx file containing your animation into the Legact Animation Clip field. See below for FBX settings.
Child name
The name of the camera in your FBX file
Focus name
The name of the camera target in your FBX file
Tweak Axis
Unity's orientation is;
Y+ = Up
Z+ = Forward
If your files export from your animation editor with a different orientation you can align to achieve your desired orientation using the Tweak Axis fields.
Offset / Ignore rotation
Use these if you want to make universal adjustments to the animation in the editor.
Start time / End time
Set the end time to the same as your animation file.
##### FBX settings[β](#fbx-settings "Direct link to FBX settings")
Add keyframes at start and end
Before you import your fbx file it needs to contain two animated objects; a Camera and Camera Interest.
Please ensure that for both objects there is a keyframe at the start and end of the track;
###### A screenshot from Motion Builder[β](#a-screenshot-from-motion-builder "Direct link to A screenshot from Motion Builder")

Copy Field of View data to Camera Scale X
Before you import your fbx file please copy the field of view information into the Camera object's X scale track.
The Legacy Animation rig that sinespace uses to apply the animation to the user's camera inworld, does not pick the data directly from the Field of View track in your animation editor.
###### A screenshot from Motion Builder[β](#a-screenshot-from-motion-builder-1 "Direct link to A screenshot from Motion Builder")

###### Import settings[β](#import-settings "Direct link to Import settings")
When you import your FBX file, open the Rig tab in the Inspector.
Set the Animation Type to Legacy Animation Clip.
Set Generation to Store in Root (new)

---
### Gestures/Snapshot Tools
#### Overview[β](#overview "Direct link to Overview")
Introduction The snapshot tools allow users to create camera positions, filters, poses & overlays that can be used for taking awesome pictures in Sinespace using the snapshot system.
##### Introduction[β](#introduction "Direct link to Introduction")
The snapshot tools allow users to create camera positions, filters, poses & overlays that can be used for taking awesome pictures in Sinespace using the snapshot system. In the tutorials below we will cover how to make and upload your own snapshot tools that you can sell in the shop or share with other users.
#### Setting Up The Scene (Beginner)[β](#setting-up-the-scene-beginner "Direct link to Setting Up The Scene (Beginner)")
In the drop down menu select About Sinespace and create a new region by clicking the Create region button in the box that appears.
In the hierarchy select the landmark and disable it, we wont be needing it for this tutorial.
We want to be able to preview what we are doing so at the top of the main window grab the game tab and drag it down and to the right to make a split screen as show above.
In the hierarchy right click to add a camera to the scene.
In the search bar above the project window search for 2017 male or female avatar, drag the model into the hierarchy.
In your scene window use your mouse & scroll wheel to position yourself on the avatar, in hierarchy select the main camera and press cntrl-shift-f to focus the camera on the avatar.
#### Creating Snapshot Filters[β](#creating-snapshot-filters "Direct link to Creating Snapshot Filters")
Snapshot filters are used to change the post processing effects while using the snapshot tool, we use Unity's post processing tools to create an effect to upload to Sinespace.
In order to see the changes we make to the post processing effects we need to add a post processing layer to the main camera. Select the camera in the hierarchy and click the add component button in the inspector, add the post processing layer component.
In your project window right click and select create/post processing profile, name it custom profile (you can name this whatever you like).
In the hierarchy select the Post Processing Settings and make sure Is Global is checked, set a high priority number 99999999 and then drag your custom profile from the project window into the profile section of the post processing volume component. **Important :** make sure that the layer at the top of the inspector is set to transparentFX.
Click on the custom profile in the project window then in the inspector click add effect, for this tutorial we will only be using the color grading tools but you can add any effects you like.
At this point we can check to see if the post processing effects are working by changing the post-exposure in the inspector window to an extreme value. You should now see an over exposed effect in our "preview window".
If the post processing is not visible in the preview window click on the camera in the hierarchy and looking in the post processing layer component, ensure that the layer field is set to everything, also check that the layer is set to transparentFX when clicking on the post processing settings in the hierarchy (this setting can be found at the top of the inspector window).

Next we will create our filter effect, click on the custom post profile in the project window and reset the exposure back to 0, check the color filter checkbox and click in the color box to the right for this tutorial I have set the color to hex code #DF83FF.
Next we will change some channel mixers settings, select the red filter tab and check the red/green/blue check boxes to enable them, set the values red -7, green - 57, blue 59.
Select the blue channel tab and again set the red/green/blue check boxes to enable them, set the values red 12, green -12, blue 27.
Now we will setup the blue channel, click the blue channel tab and enable the red/green/blue channel check boxes, set the values red 41, green 93, blue 172.
Finally to finish off the effect we will set some of the other settings in the custom profile, set the following value : mode ACES, temperature 20.1, post-exposure 2.33, saturation -38.3, contrast -5.9.
We are now ready to upload our effect to Sinespace, right click in the hierarchy and create an empty game object (name it as required), in the inspector click on the add component button and add the screenshot filter component, drag our custom profile from the project window into the post processing v2 field in the screenshot filter component.

While still having our empty game object selected click on the add component button in the inspector and add a virtual goods component, in the type field set Custom, custom type is **InventoryCameraFilter** and category is effects/snapshot/filter. Fill in the rest of the virtual goods as required.
Finally drag our empty game object from the hierarchy into the project window to prefab it, right click on the prefab and select upload to Sinespace (this can now be viewed on the preview server once processing is complete).
#### Creating Snapshot Poses[β](#creating-snapshot-poses "Direct link to Creating Snapshot Poses")
Snapshot poses allow us to be able to upload custom poses/animations that we can use in the snapshot tool in Sinespace. For this tutorial we will need to have created a pose or animation using an animation program or you can down load animations from a site such as .
Drag your chosen animation into the project window and click on it, in the inspector under the rig tab make sure the animation type is set to humanoid and click apply.
We need our animation to be looped so selected the animation tab in the inspector and check the loop time checkbox.
If you have downloaded an animation from Mixamo we will need to change the animation so it is not read only, this is so that we can edit it later in the tutorial, click the arrow next to your animations prefab (blue box) click on the animation as arrowed above and click cntrl-D to duplicate it. You can now delete the original animation prefab as this is no longer required.
We now need to be able to preview the animation inside of the editor so we can work with it, right click in the project window and select create/Animator Controller and name it Custom Controller.
Select the 2017 avatar in the hierarchy and click on the add component button in the inspector, add an animator controller component and drag our custom controller into the controller field. Make sure the avatar has the correct 2015 profile for the avatar we are using either male/female.
While still having the 2017 avatar selected click on the animator tab above the main scene window, if you don't have this tab your can right click on the scene tab and click add new tab/animator. Drag our animation into the animator window from the project window.
Now select the animation tab above the project window, if you don't have this tab you can add it by right clicking the project tab and select add tab/animation. Now if you grab the white time line in the animator window while holding the left mouse button you can scrub through the time line, the animation will be shown on our avatar in the preview window.
You can upload full animations to Sinespace for use in the snapshot system, for this tutorial I am going to create a static pose. Scrub through the time line and find a pose that you like then work through the time line and delete the key frames that are no longer needed until you have only that key frame left as pictured above.
Our avatar looks a little miserable for a picture so lets give her a smile, in the animation window click the record button then in the hierarchy open up 2017 avatar and click on either the femalebody or malebody found under Geo\_GRP. In the inspector under the skinned mesh renderer open up the blend shapes menu by clicking the arrow next to blend shapes.
We will change some of the mouth settings to make our avatar smile, for the tutorial i will set the mouth\_anim.mouth\_ah to 50 and the moth\_anim.mouth\_eee to 25, you can change other settings to suit. \*\*Warning : \*\* do not change anything that has slider in the name, this will break things in world. Our blend shape changes will now have been saved to the animation so we can click on the record button in the animation window to stop recording.
---
### Gestures - VFX
#### Overview[β](#overview "Direct link to Overview")
You can add colour treatments to your gesture using the Avatar Effect LUT script.
You can add colour treatments to your gesture using the Avatar Effect LUT script.
For more information on creating LUTs, see Unity's documentation here; \[]
---
### Multi-Person Animations
#### Overview[β](#overview "Direct link to Overview")
The process for setting up a multi-person gesture is the same as that for Gestures - Single Person Animation, BUT; Trigger Enable the trigger in the Avatar Effect Script.
The process for setting up a multi-person gesture is the same as that for [Gestures - Single Person Animation](/sinespace-sdk/avatars/gestures/single-person-animation.md), BUT;
##### Trigger[β](#trigger "Direct link to Trigger")
Enable the trigger in the Avatar Effect Script. Set the trigger radius to 4.
\\
Users can initiate a two person gesture inworld with a visible circle around them.
Please note that no animation or other prop, audio file or VFX, will be launched on any individual's desktop until all the components of the gesture have arrived and can be launched collectively; guaranteeing that multi-user gestures play in sync for every participant and all other observers in the region.
<
##### Avatar Multi Animation Effect Script[β](#avatar-multi-animation-effect-script "Direct link to Avatar Multi Animation Effect Script")
Attach the Avatar Multi Animation Effect Script instead of the Avatar Effect Script;
Clip A / Clip B
Drag the animation takes from the fbx files for each of your two characters into these fields.
Clip A will play on the initiator of the gesture. Clip B will play on the recipient or guest.
Distance Apart
You can offset the characters here if you have not already defined the offset in via the root nodes of your models in your animation editing tool.
Fix Avatar Heights
If your gesture involves both characters engaging in a very prceise interaction, for instance shaking hands, you can align them using Fix Avatar Heights. Gestures played by tall and short avatars may not look correct otherwise.
Start Time
You can delay the initiation of the animations.
IK Targets
You can select one or more nodes on the avatars and impose an IK through the animation to correct for discrepancies in avatar sizes and shapes.
For more information on on FBX settings and setting up gestures;
[Gestures - Single Person Animation](/sinespace-sdk/avatars/gestures/single-person-animation.md)
##### Virtual Goods Script[β](#virtual-goods-script "Direct link to Virtual Goods Script")
Fill out the product details in the Virtual Goods Script and submit your gesture to the staging server for review.
for more information on the Virtual Goods Script go here;
[Virtual Goods](/sinespace-sdk/components/virtual-goods.md)
---
### Props
#### Overview[β](#overview "Direct link to Overview")
In addition to animations and camera paths, there are a number of other components you to can add to speciflc points on the the timeline of a gesture, allowing you to create sophis
In addition to animations and camera paths, there are a number of other components you to can add to speciflc points on the the timeline of a gesture, allowing you to create sophisticated and complex multi-person performances that can be deployed instantly anywhere.
##### Props[β](#props "Direct link to Props")
Props might include;
* Furniture;
* Weapons;
* Costume accessories;
* Particle effects;
* Floating text;
* Other complex compound objects, up to and including entire sets.
To add a prop to your gesture, add the "Create Object, Attach" component.
You can add as many separate props as you want, each with their own attachment points or location, and each with their own start and end times.
\\
Drag the prop itself into the Object field.
Use Start Time and End Time fields to set when your prop spawns and despawns.
For single person gestures leave the Participant field as Initator.
For multi-person gestures you can select the Initiator or Recipient for each prop; so you can put a gun in both avatar's hands simultaneously, or set both their heads on fire...
Use the destination drop down to attach your prop to any bone on the skeleton of the avatar.
---
### Set Up
#### Overview[β](#overview "Direct link to Overview")
Gesture Preview Scene Once you have imported the sinespace Editor Pack into Unity, you will find a Gesture Preview Scene.
##### Gesture Preview Scene[β](#gesture-preview-scene "Direct link to Gesture Preview Scene")
Once you have imported the sinespace Editor Pack into Unity, you will find a Gesture Preview Scene.
This scene contains two rigged character models and is set up to allow you to assemble and test your gestures.
Add only one gesture into the scene at a time.

##### Animation formats[β](#animation-formats "Direct link to Animation formats")
The sinespace virtual world uses the Unity game engine and supports animation files imported as part of a 3D Model file (such as FBX). If you are used to using BVH files there are utilities online that can convert from one format to the other.
##### Avatar Effect Scripts[β](#avatar-effect-scripts "Direct link to Avatar Effect Scripts")
When you import an animation into Unity you will then add that animation to a game object. You can find samples for single person gestures and multi-person gestures in your project window. Go to Sample Art>Gestures and there will be two sample prefabs. Sample 1 is for single person and Sample 2 is multi-person.
That game object has scripts added to it, depending on what you are doing with your gesture.
Please see the [Single Person Gesture](/sinespace-sdk/avatars/gestures/single-person-animation.md) page and [Multi-Person Gesture](/sinespace-sdk/avatars/gestures/multi-person-animations.md) page for more information on how to set gestures up.
##### Virtual Goods Script[β](#virtual-goods-script "Direct link to Virtual Goods Script")
Your gesture will also have a Virtual Goods Script attached, which allows you to add product information and submit the item to the store and / or your inworld inventory.
For more information on the virtual goods script;
[Virtual Goods](/sinespace-sdk/components/virtual-goods.md)
---
### Single Person Animation
#### Overview[β](#overview "Direct link to Overview")
Create Gesture Prefab In the project folder called Gestures (search for "Gestures" in project search) you will see a selection of templates you can duplicate, rename and modify.
##### Create Gesture Prefab[β](#create-gesture-prefab "Direct link to Create Gesture Prefab")
In the project folder called Gestures (search for "Gestures" in project search) you will see a selection of templates you can duplicate, rename and modify.
Highlight the "Sample 1 person template" file and click ctrl D to duplicate.
Rename your new prefab in the project window, then drag it into the scene.

If you don't want to duplicate the template objects, you can also create an empty game object and then add the "Animate Single Avatar" or "Animate Multiple Avatars" components (which will automatically add the two scripts required) and then you also have to add the "Virtual Good" component.

##### Import FBX[β](#import-fbx "Direct link to Import FBX")
When you import the .fbx file containing your animation you need to rig it.
Click the rig tab in the inspector. Set the type to Humanoid. Set the Avatar Definition to Copy From Other Avatar Select the relevant sinespace avatar as the source (click the small circle to the right of the Source field.)

Now click from the rig tab to the Animations tab.
You should be able to see your animation in the preview window in the Inspector.
You may wish to crop or modify the animation using Unity's tools in this panel; see here for more information on Unity's animation tools.
##### Avatar Effect Script[β](#avatar-effect-script "Direct link to Avatar Effect Script")
Set the number of participants to 1.
If your animation is specifically for a single gender then check "Is Gendered" and select Male or Female from the "Nominal Gender" dropdown.
Leave the Trigger fields empty; these will be used with multi-person gestures.
Tick loop if required; e.g. for dances. The user will be able to stop looping in-world by exiting the gesture..

Other Avatar Effect Scripts
[Gestures/Props](/sinespace-sdk/components/avatar-effect-object.md)
[Gestures/FX](/sinespace-sdk/components/avatar-effect-lut.md)
[Gestures/Take Snapshot](/sinespace-sdk/components/avatar-effect-snapshot.md)
##### Avatar Animation Effect Script[β](#avatar-animation-effect-script "Direct link to Avatar Animation Effect Script")
Drag the animation take from within your fbx file into the Clip field.
Leave "Participant" set to Initiator.
You can use the start time to delay the start of the gesture.
If your gesture involves interaction with fixed position prop (e.g. a door handle) or with precise two person gestures (e.g. shaking hands) you may wish to tick Fix Avatar Height. This will set the user's avatar height to the standard height for avatars in sinespace.

##### Preview gesture in scene[β](#preview-gesture-in-scene "Direct link to Preview gesture in scene")
Once you have added the animation track to the Clip field in the Avatar Effects Script you can click play in Unity and see the gesture performed by the model in the scene.
##### Virtual Goods Script[β](#virtual-goods-script "Direct link to Virtual Goods Script")
Fill out the product details in the Virtual Goods Script and submit your gesture to the staging server for review.
for more information on the Virtual Goods Script go here;
[Virtual Goods](/sinespace-sdk/components/virtual-goods.md)
---
### Visual FX
#### Overview[β](#overview "Direct link to Overview")
This component/script is accessed from the Unity Component menu, then Avatar Effects then select "Color Filter - LUT".
This component/script is accessed from the Unity Component menu, then Avatar Effects then select "Color Filter - LUT".
You can add colour treatments to your gesture using the Avatar Effect LUT script.
When you import a texture to apply as a LUT you should apply the following settings to your .png file;
Texture Type: Advanced
Mapping: None
Import Type: Default
Bypass sRGB Sampling: ticked
Generate Mip Maps: Off
Wrap Mode: Clamp
Filter Mode: Bilinear
Aniso Level: 0
For more information on creating LUTs, see Unity's documentation here; [\[1\]](https://docs.unity3d.com/Manual/script-ColorCorrectionLookup.html)
##### Audio[β](#audio "Direct link to Audio")
This component/script is accessed from the Unity Component menu, then Avatar Effects then select "Play Audio".
You can add audio effects, synchronised with other events in the gesture, using the Audio Effect component;
\\
For more information on audio files and Unity see here; [\[2\]](https://unity3d.com/learn/tutorials/topics/audio)
---
### Materials, Sliders and Shaders
#### Overview[β](#overview "Direct link to Overview")
Making A New Material (\_note: this wiki page refers to the Unity standard shader only.
#### Making A New Material[β](#making-a-new-material "Direct link to Making A New Material")
(*note: this wiki page refers to the Unity standard shader only. Uploading custom shaders in space is permitted.*)
To create a new material, right click in your project window, go to Create and choose Material. This will make a default gray material in your project window.
You can then drag this material onto the clothing item in the scene.
You can change the colour of this material here:
1. Metallic Slider
Using the metallic slider will let the Albedo colour control the colour of the specular reflection and most liight will be reflected as specular reflections. In more simplier terms, if you want to create something metallic, you would want to have the metallic slider high and also the smoothness slider high so that the material will reflect light like a metal does.
1. Smoothness Slider
The smoothness slider will reduce the amount of shine and hardness from the clothing. For the t-shirt I made, I have set the smoothness slider to the lowest and also the metallic slider to the lowest so there is no reflective light or specular light coming from the material. You can play around with these sliders until you get the outcome you want.
1. Normal Map
If you have made a high poly version of your clothing item, then you can make the normal map for it in your 3D software and apply it to your low poly item.
You can add normal map images by dragging and dropping your normal map image from where you saved it into your project window, then dragging it into the normal map slot.
Note: Make the normal map image a normal map texture first by clicking on the image and choosing normal map under the texture type in the import settings on the right hand side of the screen.
1. Height Map
Height maps are usually used alongside normal maps, and they are used to give definition to surfaces where the texture maps are responsible for rendering bumps and protrusions.
Add the height map the same way as a normal map, but drag the image into the Height Map slot.
1. Occlusion Map
Occlusion maps are used to provide information for which areas on the clothing item will receive direct or indirect lighting. For example, if you make a metal buckle for a belt, you can add in an occlusion map to create shiner parts of the belt and parts that are darker.
Add the Occlusion Map the same way as a normal map, but drag the image into the Occlusion slot.
1. Emission
Emission controls the colour and intensity of light on your clothing item. If you set the emission to black, there will be no parts of the clothing that look lighter. If you want to make parts look lighter, you can set the emission to gray (for making parts slightly lighter) or white (for making parts look a lot lighter)
I recommend not setting the emission to anything other than black for clothing that would be made from material like cotton, denim or brick, but it can be set for items made out of leather, PVC or metal.
1. Detail Maps
Secondary Maps (or Detail maps) allow you to overlay a second set of textures on top of the main textures. You can apply a second Albedo colour map, and a second Normal map. These would be mapped on a much smaller scale and repeated many times across the objectβs surface, compared with the main maps. The reason for this is to allow the material to have sharp detail when viewed up close, while also having a normal level of detail when viewed from further away. These detail maps are usually used for creating small details like tiny hairs on the skin, pores on the skin, or things like really small cracks in walls and floors.
1. Fresnel Effect
One important visual cue of objects in the real world has to do with how they become more reflective at grazing angles. This is called the Fresnel effect. In the Standard shader there is no direct control over the Fresnel effect. Instead it is indirectly controlled through the smoothness of the material. Smooth surfaces will present a stronger Fresnel, totally rough surfaces will have no Fresnel.
You want to set the smoothness higher for materials like reflective glass, leather, PVC, metals, anything in the real world that would have a hardness and reflectiveness to it.
---
### Skins
#### Overview[β](#overview "Direct link to Overview")
Skin is a texture image that replaces the default skin of your avatar.
Skin is a texture image that replaces the default skin of your avatar. Skins can be re-made and uploaded in Sine Space using the [Virtual Goods](/sinespace-sdk/components/virtual-goods.md) component.
##### Avatar Skin[β](#avatar-skin "Direct link to Avatar Skin")
You can download the default avatar skin template from the following link.
* Sinespace avatar Skin: [Download](http://space-files.s3.amazonaws.com/sample-art/SkinArtistQuickpack.zip)
##### Importing Skin textures to Unity[β](#importing-skin-textures-to-unity "Direct link to Importing Skin textures to Unity")
Once you have created the Skin save the PSD and import it back to Unity.
###### Note on importing assets[β](#note-on-importing-assets "Direct link to Note on importing assets")
Unity uses a working folder called the "Assets Folder" - anything in this folder is accessible in Unity in the 'Project' panel. You can right-click in the 'Project' panel, and select 'Show in Explorer' (or 'Show in Finder' on MacOS) and view the files. To import the texture into Unity, simply save it into this folder. Unity will detect and import the texture when you tab back into it.
Attention: Do not store the edited Skin in the 'Artist Project' folder, it will not be uploaded. (That folder is ignored during uploads)
##### Turning the textures into a skin[β](#turning-the-textures-into-a-skin "Direct link to Turning the textures into a skin")
A skin is a special type of Clothing Item - as of Editor Pack 12, we strongly recommend uploading skins using the new 'Tattoo System' which is documented below.
#### Path A. Upload as Tattoo[β](#path-a-upload-as-tattoo "Direct link to Path A. Upload as Tattoo")
*Video Option: This topic is covered under* [*Masterclass 17*](https://www.youtube.com/watch?v=s55zKHo_hdo)
Create a new blank gameobject using GameObject->Create Empty from the menu

On the right hand side of the screen, locate the "Inspector" panel, and add a Clothing Item Settings component to this new empty object

Locate the Tattoo section on this component

You now need to adjust the settings to indicate this is a skin; the key settings are:
* Skeleton: Make sure to set this Male or Female
* Enabled: Make sure this is ticked
* Type: Set this to Base Skin
* Albedo: Drag the base diffuse/albedo texture into this slot from the Project panel

NOTE: If you are using an older Editor pack, you will also need to tick 'Only Contains Skin' to get it to process correctly, you can find that on the Skin tab. (Newer editor packs such as 12p13 should not require this; however if you encounter an error during processing, you may want to try it.)

The next step is to format it as a item - fill in details on the name, pricing, etc.
Add the virtual good component from the 'Add Component' button

You will then need to adjust some settings - fill in the form until all the red exclamation marks have vanished.

Finally, to save this to disk (so that it is stored as a file, versus simply an object in your scene), click the 'Fix Now' button to convert it to a prefab; be aware the objects name (at the top) will be used in the filename, so you may want to rename the object prior to clicking this button.

You may now upload the item from the Upload tab, this will upload it to the world directly.
##### Previewing (Optional)[β](#previewing-optional "Direct link to Previewing (Optional)")
If you wish to preview it, prior to uploading; you can use the Clothing Previewer to test an item
Create a new GameObject

Add the Statue and Clothing Previewer components to the object
Now, in the Project Panel, locate your object

You can then drag the object into the previewer slot. Set the appropriate gender on the 'Statue' component (note: the Statue component can be used for NPCs, or previewing against a specific avatar - see more in the NPC pages of this wiki)

Hit the 'Play' button in Unity, and the avatar should preview, while wearing the item.
#### Path B. Upload Entire Material[β](#path-b-upload-entire-material "Direct link to Path B. Upload Entire Material")
If you need to use a custom shader or material for your skin, follow this procedure. Note this method may not be as compatible with tattoos and makeup layers.
you can create a new material and drag skin texture and normal map in normal map slot.
Once the material is created you can chose the material shader for skin from built in unity standard, custom shader or SineWave skin shader.
SineWave Skin Shader
* Main Color - Sets the overall color of the skin.
* Specular Color - Tints specular highlights of the skin.
* Shininess - Sets the shine amount of the skin.
* Rim Power - how rim lighting spreads around the edges of the model.
* Rim HDR - Adds a boost to rim lighting, to enable it push into HDR values (i.e. Brighter than white) for bloom.
* Normal Power - controls power of normal map (allowing them to be more/under represented)
* Tessellation - allows DX11 Tessellation which smooth's geometry when camera is up close.
* Specular Amount - Sets the specular amount.
* Gloss Amount - Sets how glossy the skin should look.
* Smoothness - controls specular highlights on PBR platforms (higher = tighter highlights), correlates with Standard shader.
* Occlusion - controls ambient occlusion.
* Loading color - For internal use. PLEASE IGNORE THIS SETTING.

##### Using Make clothing component to fit the Skin[β](#using-make-clothing-component-to-fit-the-skin "Direct link to Using Make clothing component to fit the Skin")
Once the skin material is created, it needs to be converted to fit the skeleton.
Create an empty game object in the scene and add the Clothing Item Settings Component to it.
Skeleton Selection
Chose the relevant Skelton for the clothing item. Please note Space supports multiple third party skeletons as well as it's own native male and female models.
Slots
If you are creating only skin, select Skin Base slot. If you want the skin to have more than just skin select other applicable slots.

Skin Setup
Select Only contains skin if you are uploading skin only. If you are doing a combined outfit Don't select this.
* Note : if you are not making just skin you will have to click on Convert to skinned button later. if you are creating just skin this step is not needed and the button will disappear as soon as you select Skin only.
Replacement Skin
Set the number of material the skeleton you are using has.
Sine Space male and female skin only has 1 material; if you have selected that as the skeleton Set the size to 1.
After the size is set. Drag the skin material in the material slot.

##### Add virtual goods script[β](#add-virtual-goods-script "Direct link to Add virtual goods script")
Attach the virtual goods script and complete the submission process.
See [Virtual Goods](/sinespace-sdk/components/virtual-goods.md) for more details on the virtual goods script.
##### Video Tutorial[β](#video-tutorial "Direct link to Video Tutorial")
To learn more about creating and uploading skins, watch the tutorial below:
[YouTube video player](https://www.youtube.com/embed/vSuhAmnqZJE)
---
### Unified Clothing And Skin (Metal and Tessellate)
#### Overview[β](#overview "Direct link to Overview")
The Unified SkinClothing HighEnd shader is a shader used for adding depth and substance to your clothing and skin (metal and tessellate feature).
The Unified SkinClothing HighEnd shader is a shader used for adding depth and substance to your clothing and skin (metal and tessellate feature). This shader is best used on high end machines.
You can use the basic Unified SkinClothing shader if you have a PC with lower performance.
To use this shader on your clothing and skin items, search for "Unified" in your Unity project window. Create a new material by right clicking in the project window and select 'Create>Material'. Drag the Unified SkinClothing HighEnd shader on to the new material and this will add the shader to the material.
Now to work with the settings. NOTE: The name of the shader will now show as Unified Clothing And Skin (Metal and Tessellate)
* Main Color - Sets the overall color of the skin.
* Specular Color - Tints specular highlights of the skin.
* Shininess - Sets the shine amount of the skin.
* Rim Power - how rim lighting spreads around the edges of the model.
* Rim HDR - Adds a boost to rim lighting, to enable it push into HDR values (i.e. Brighter than white) for bloom.
* Normal Power - controls power of normal map (allowing them to be more/under represented)
* Tessellation - allows DX11 Tessellation which smooth's geometry when camera is up close.
* Specular Amount - Sets the specular amount.
* Gloss Amount - Sets how glossy the skin should look.
* Smoothness - controls specular highlights on PBR platforms (higher = tighter highlights), correlates with Standard shader.
* Occlusion - controls ambient occlusion.
* Loading color - For internal use. PLEASE IGNORE THIS SETTING.
But has the addition of a few more settings:
* Height Map:
\- Single channel (R) texture with height distances encoded on it, you can use a heightmap exported from your 3D package (either Quixel/Substance Painter or from Maya/Max/Blender) - should be derived from the same thing building the normal maps.
Use the height map for encoding fine details (such as for example complex textured fabrics) that are too small or high poly to justify using actual geometry.
* Height:
\- How much in meters to scale the model details by the heightmap. A value of 0.01 is 1cm. Typically you want 0.005 or so.
* Height Offset:
\- This will subtract this value from the heightmap values uniformly; you can use for tweaking the visual appearance. Note: resulting values less than zero are treated as zero.
* Tessellation Edge Length:
\- This defines the maximum size of a triangle on screen in pixels. If a triangle is larger than this many pixels on screen, it will be subdivided. Do not go below 15.
* Tessellation Phong Strength:
\- This defines how "smooth" the surface should become, values larger than 0.2-0.3 will often create weird balloons. Typical values range from 0 (no smoothing corners/edges) to 0.1 (slight smoothing)
*NOTE*: When using this shader, make sure to tick "Generate Lightmap UVs" and disable Mesh Compression on your model in the Unity Model Importer screen ( R ) = (R)
---
### Uploading Tattoos
#### Overview[β](#overview "Direct link to Overview")
This a step by step tutorial on how to upload tattoos to Sinespace.
This a step by step tutorial on how to upload tattoos to Sinespace.
1\. In Photoshop or similar, open the sinespace skin texture file you want to work on (male or female) from this pack - [| Download](http://space-files.s3.amazonaws.com/sample-art/SkinArtistQuickpack.zip)
2\. Create a new layer (in Gimp make sure the layer is set to Transparency) and add your tattoo image to that layer.
3\. Place the tattoo where you want it on the skin texture file

4\. Save this layer as a .png or another file format that saves as transparent such as a psd file in Photoshop. In Gimp you will have to hit βFile, Exportβ then save it as βTattoo\_Chest.pngβ for example.
5\. Once saved, open Unity.
6\. In Unity, create a new folder called Tattoo so you know where to find the png for the tattoo. You can do this by right clicking in the project window and hit βCreateβ then βNew Folderβ.
7\. Add the png of the tattoo to the new folder you just created. You can do this by right clicking in the new folder and hit βImport New Assetβ and click on the png file. OR, just drag and drop the png into this new folder.
8\. In the Unity hierarchy, right click and hit βCreate Emptyβor click on 'Game Object' and choose Empty at the top of Unity. You can name this empty object to something like βChest Tattooβ or whatever you want to name it as.

9\. Make sure in Transform the position is set to 0,0,0.

10\. Add the βClothing Item Settingβ component to the empty object by clicking βAdd Componentβ and search for βClothing Item Settingβ
11.In the clothing item settings, choose the right base avatar skeleton (this will be the same as the skin texture)
12\. Check the Tattoo and Makeup setting under the clothing item settings. Set the settings to these:

For the albedo, drag in the .png of the tattoo.
13\. Once done, add the βVirtual Goodβ component. Once this added, drag your empty object from the hierarchy to the project window to make it a prefab.

14.Click on the prefab in your project window, then fill in the virtual good information.
15\. Set the Type in Virtual good Basics to Clothing, and Category to Clothing/Skin/Tattoos then fill in the rest of the virtual good information and click auto submission to upload to Sinespace. You can check on the progress of your upload at [curator.sine.space](https://curator.sine.space/)
---
### AnimatedVendorConsole
#### Overview[β](#overview "Direct link to Overview")
Fields Radius Set the proximity radius Usage There is an example in Sample art/vendor folder of the Editor Pack.

info
This component is itself a legacy component (and may be depreciated and removed in the future), or is likely to get an update in the future.
#### Fields[β](#fields "Direct link to Fields")
###### Radius[β](#radius "Direct link to Radius")
Set the proximity radius
#### Usage[β](#usage "Direct link to Usage")
There is an example in Sample art/vendor folder of the Editor Pack.
Radius Radius at which the animation will trigger.
eg, if the radius is set to 5, when the avatar comes within 5 meters of the vendor the vendor animation will trigger.
---
### AnimationVendor
#### Overview[β](#overview "Direct link to Overview")
Fields **Play Clickable** Place the play button object/canvas here.

#### Fields[β](#fields "Direct link to Fields")
###### **Play Clickable**[β](#play-clickable "Direct link to play-clickable")
Place the play button object/canvas here.
###### **Buy Clickable**[β](#buy-clickable "Direct link to buy-clickable")
Place the buy button object/canvas here.
###### **Mannequin**[β](#mannequin "Direct link to mannequin")
Place the avatar to animate here.
###### **Click to start**[β](#click-to-start "Direct link to click-to-start")
If unchecked, the animation will always play.
###### **Item ID**[β](#item-id "Direct link to item-id")
Enter the item ID here.
---
### ATM
#### Overview[β](#overview "Direct link to Overview")
Add this component to an ATM mesh / NPC statue.

info
*To find the ATM component you need to search in the Editor Pack with the name "Buy Gold".*
Add this component to an ATM mesh / NPC statue.
Any user that clicks on it will get the Purchase Gold interface
---
### AudioReactive
#### Overview[β](#overview "Direct link to Overview")
To set up your scene in Unity for the audio reactive components, you need to first either drag an audio file from your PC into the project window, and then into the hierarchy, or for music streams, you need to (info).
To set up your scene in Unity for the audio reactive components, you need to first either drag an audio file from your PC into the project window, and then into the hierarchy, or for music streams, you need to (info).
##### Audio Reactive Transform[β](#audio-reactive-transform "Direct link to Audio Reactive Transform")
This component can be attached to the 3D object you want to react to the music and then used to transform the 3D object in time to the audio.
You can transform the object within the component, so you can set the object to scale, rotate or move in certain directions.
To add this component to your object, select the object in your hierarchy and under the Inspector window on the right, click on 'Add component'. Search for audio reactive and choose 'Audio Reactive Transform'.

###### Band Min and Band Max[β](#band-min-and-band-max "Direct link to Band Min and Band Max")
There are different types of bands for the different frequencies in audio. For example, if you want the object to move to only the bass of the audio, you will need to set the band min slider to 0, and the band max to 1. You can play around with the different values until it matches the audio band you want the object to move to.
###### BPM Window[β](#bpm-window "Direct link to BPM Window")
The BPM Window Limit defines how many seconds to analyse for determining the BPM. So, for example, if you set this to 3, it will listen to the last 3 seconds, if you set it to 10, it will listen to the last 10 seconds.
###### Limit Increase/Decrease[β](#limit-increasedecrease "Direct link to Limit Increase/Decrease")
The limit increase/decrease determines how quickly the values can change. If you have fast paced music and want the object you have to react faster to the audio, you can change the limit increase/decrease to 10,000+ to make the object move very quickly in time to the audio.
###### Min Value/Max Value[β](#min-valuemax-value "Direct link to Min Value/Max Value")
These determine how quick the reactions are, so you might want to set these values to your liking.
###### Mode[β](#mode "Direct link to Mode")
This sets the mode to BPM or Band.
###### Position[β](#position "Direct link to Position")
This will change the objects position when checked. You can set how far the object will move and in which direction on the Z,Y and X axis in time to the audio.
###### Rotation[β](#rotation "Direct link to Rotation")
This will change the direction in which the object is rotated when checked. Again, this will set which way the object will rotate on the Z,Y and X axis in time to the audio.
###### Scale[β](#scale "Direct link to Scale")
This will change the size/scale of the object when checked. The object can be scaled in any direction on the Z,Y and x axis separately, or you can set the same value in all of the axis's to make the object scale uniformly.
#### Audio Reactive Lighting[β](#audio-reactive-lighting "Direct link to Audio Reactive Lighting")
Audio reactive lighting will enable lighting to react to the audio you choose. Audio reactive lighting will work with lights which don't need to be baked, such as spot lights, directional lights and point lights.
To add the audio reactive lighting to your light, click on the light you want to use in your hierarchy, and under the Inspector window, click on 'Add Component'. Search for audio reactive and choose 'Audio Reactive Light'.

###### Band Min and Band Max[β](#band-min-and-band-max-1 "Direct link to Band Min and Band Max")
There are different types of bands for the different frequencies in audio. For example, if you want the object to move to only the bass of the audio, you will need to set the band min slider to 0, and the band max to 1. You can play around with the different values until it matches the audio band you want the object to move to.
###### BPM Window[β](#bpm-window-1 "Direct link to BPM Window")
The BPM Window Limit defines how many seconds to analyse for determining the BPM. So, for example, if you set this to 3, it will listen to the last 3 seconds, if you set it to 10, it will listen to the last 10 seconds.
###### Limit Increase/Decrease[β](#limit-increasedecrease-1 "Direct link to Limit Increase/Decrease")
The limit increase/decrease determines how quickly the values can change. If you have fast paced music and want the object you have to react faster to the audio, you can change the limit increase/decrease to 10,000+ to make the object move very quickly in time to the audio.
###### Min Value/Max Value[β](#min-valuemax-value-1 "Direct link to Min Value/Max Value")
These determine how quick the reactions are, so you might want to set these values to your liking. When working with lighting, you might want to lower these values so the lighting colors blend quickly together.
For example, setting the min value to 0, and the max value to 0.1, will mean that lights react quickly to the audio and they also blend and change colors faster.
###### Mode[β](#mode-1 "Direct link to Mode")
This sets the mode to BPM or Band.
###### Range[β](#range "Direct link to Range")
When range is checked, this will change the distance range of the light. For example, set the min range to 1 and max to 5 for a small circle of light.
###### Animate Color[β](#animate-color "Direct link to Animate Color")
When this is checked, this will enable the light to blend the min color and max color you have chosen.
###### Intensity[β](#intensity "Direct link to Intensity")
This will change the intensity of the light. The lower the values, the dimmer the light will be, and the higher the values are, the brighter the light will be.
#### Audio Reactive Animation[β](#audio-reactive-animation "Direct link to Audio Reactive Animation")
Audio reactive animation will enable a 3d object of your choice to move to audio.
This component has a bit more to it than the other audio reactive components, but it is still a simple process to set up.
Click on your object in the hierarchy, and under the Inspector window, click on βAdd Componentβ and search for βAudioβ then choose βAudio Reactive Animationβ.
When this is done, click on βWindowβ at the top of Unity. On the drop-down menu, choose βAnimationβ. This will add an Animation tab at the bottom of the screen.

Click on βCreateβ in the animation tab, and when the Explorer opens, save the animation anywhere you want to save it.
Now in the Animations tab, click on βAdd propertyβ. This will open up a menu with three options; Transform, Mesh Renderer and Box Collider. For audio reactive objects, the best option to choose are Transform and Mesh renderer.
###### Transform[β](#transform "Direct link to Transform")
Transform has more options on the drop down menu. To expand Transform, click on the arrow next to Transform. You will see three more options.
###### Position[β](#position-1 "Direct link to Position")
This will allow you to change the position of the object along the X,Y and Z axis.
###### Scale[β](#scale-1 "Direct link to Scale")
This will scale the object along the X,Y or Z axis, but also let you scale uniformly.
###### Rotation[β](#rotation-1 "Direct link to Rotation")
This will rotate the object.
###### Mesh Renderer[β](#mesh-renderer "Direct link to Mesh Renderer")
Mesh renderer is used for changing the objectβs color or material. When you click on the arrow next to mesh renderer, this will show a lot of options, but they are all related to materials and color.
Choose from either one of the transform options or mesh renderer options, and then click on the β+β sign next to the option.
You can add more than one transform option or mesh renderer option to make the animation more complex.
I have chosen to scale to my object, so I clicked on the plus sign, and two diamond shapes will now show in the animations tab on the timeline. These diamonds are key frames for the animation. The timeline is measured in frames and in seconds.
Click on the key frame at the beginning of the timeline, and you will that it highlights blue. To make sure that the scale values you put in show up in your animations, put the scrubber (red line) over the key frame.

There is another key frame at the end of the timeline. Drag the scrubber to this key frame, and then change the values of scale again. I am changing mine to 2,2,2.
If you want to add more keys, move the scrubber to the position on the timeline where you want to add it, and right click near the scrubber and choose βAdd Keyβ.
The more keys you add, the more precise the movements will be.
Here is my finished timeline.

I have just made a very simple scale transition from 1,1,1 at the beginning to 2,2,2 at the end.
#### Making the Animation work with Audio[β](#making-the-animation-work-with-audio "Direct link to Making the Animation work with Audio")
To make the animation work with the audio, you now need to click on βWindowβ at the top of Unity and choose βAnimatorβ.
When the Animator window is open, it will look like this, with the name of your object and the animation type in an orange box.

Click on your animation in the orange box. On the left hand side, you will see βLayersβ and βParametersβ.

Click on Parameters if it isnβt already selected, and then click on the β+β sign underneath.

When menu appears, choose βFloatβ. This will show a βNew Floatβ directly underneath the plus sign.
Rename this float βAudioβ, exactly as it is shown here, with a capital A.
Now, click on the orange box again, and in the Inspector window, you will see these settings.

You can change the speed of the animation if you want it to be faster or slower, but for this example I am keeping mine on the default of 1.
In the Multiplier setting, click on Parameter next to it, and this should automatically choose βAudioβ.
The animation is set up to work with the Audio!
Go back down to your Animation tab, and un-check the record button, then click on your Scene tab.
Now you can click on βPlayβ and see if the Animation is working with the Audio.
You will need to select the band you want the object to react to in the Audio Reactive Animation component in the Inspector window.
You can adjust the settings in the Audio Reactive Animation component until you are happy with the result.
##### Audio Reactive Material[β](#audio-reactive-material "Direct link to Audio Reactive Material")
*Note*: Audio Reactive Material is working in the experimental editor pack
---
### AvatarAnimationEffect
#### Overview[β](#overview "Direct link to Overview")
Fields Clip Add the animation clip here Participant sets the participant to initiator or receiver Start Time Sets the starting time of the animation Fix Avatar height Force sets av

#### Fields[β](#fields "Direct link to Fields")
###### Clip[β](#clip "Direct link to Clip")
Add the animation clip here
###### Participant[β](#participant "Direct link to Participant")
sets the participant to initiator or receiver
###### Start Time[β](#start-time "Direct link to Start Time")
Sets the starting time of the animation
###### Fix Avatar height[β](#fix-avatar-height "Direct link to Fix Avatar height")
Force sets avatar height to standard
#### Usage[β](#usage "Direct link to Usage")
Click on Add Component under the Inspector window, and search for Animate Single Avatar.
You can chose whether the participant is an initiator or receiver.
Drag the animation taken from within your Animation fbx file into the Clip field.
You can use the start time to delay the start of the gesture.
If your gesture involves interaction with fixed position prop (e.g. a door handle) or with precise two person gestures (e.g. shaking hands) you may wish to tick Fix Avatar Height. This will set the user's avatar height to the standard height for avatars in Space.
For details, check [how to set up an gesture](/sinespace-sdk/avatars/gestures.md) and [create a single animation](/sinespace-sdk/avatars/gestures/single-person-animation.md).
---
### AvatarAudioEffect
#### Overview[β](#overview "Direct link to Overview")
Fields Trigger time set the start time of audio.

#### Fields[β](#fields "Direct link to Fields")
###### Trigger time[β](#trigger-time "Direct link to Trigger time")
set the start time of audio.
###### Effect[β](#effect "Direct link to Effect")
add the audio file here.
###### Volume[β](#volume "Direct link to Volume")
Sets the volume of the audio.
#### Usage[β](#usage "Direct link to Usage")
You can add audio effects, synchronized with other events in the gesture, using the Audio Effect component.
Click on Add Component under the Inspector window, and search in the search bar for Play Audio.
You can set the trigger time of the audio, for example, if you had chosen a high five animation, you want to trigger the time of the clap sound to the gesture animation. Effect is where you add the sound clip for the animation. Volume is used to set the audio volume.
---
### AvatarEffect
#### Overview[β](#overview "Direct link to Overview")
Fields Participants Sets no of participants Is Gendered Lets user choose Nominal gender Nominal Lets user choose Nominal gender Uses Radius Allows you to choose area radius Entry R

#### Fields[β](#fields "Direct link to Fields")
###### Participants[β](#participants "Direct link to Participants")
Sets no of participants
###### Is Gendered[β](#is-gendered "Direct link to Is Gendered")
Lets user choose Nominal gender
###### Nominal[β](#nominal "Direct link to Nominal")
Lets user choose Nominal gender
###### Uses Radius[β](#uses-radius "Direct link to Uses Radius")
Allows you to choose area radius
###### Entry Radius[β](#entry-radius "Direct link to Entry Radius")
Lets you enter radius; this needs entry radius checked
###### Looped[β](#looped "Direct link to Looped")
Sets animation to be looped.
#### Usage[β](#usage "Direct link to Usage")
When you import an animation into Unity you will then add that animation to a game object (there are templates in the Gestures folder in your project).
That game object has scripts added to it, depending on what you are doing with your gesture.
click on Add Component and search for AvatarEffect in the search bar to add animation effects to your avatar.
The settings under this component include:
* Participants- This allows to change from 1 to 2 participants
* Is Gendered- This allows you to choose whether or not the gesture is gender specific
* Nominal Gender- You can choose which gender is nominal, but it will still play with both genders.
* Trigger:
* Uses Radius: This means the gesture will use a radius of an area
* Entry Radius: You can set the entry radius amount for the gesture area
---
### AvatarEffectCamera
#### Overview[β](#overview "Direct link to Overview")
Fields Rail set camera rail path Offsets Sets camera in relation with avatar Tracking targets Usage Click on Add Component under the Inspector window, and search for Camera Follow Character in the search bar.

#### Fields[β](#fields "Direct link to Fields")
###### Rail[β](#rail "Direct link to Rail")
set camera rail path
###### Offsets[β](#offsets "Direct link to Offsets")
Sets camera in relation with avatar
###### Tracking targets[β](#tracking-targets "Direct link to Tracking targets")
#### Usage[β](#usage "Direct link to Usage")
Click on Add Component under the Inspector window, and search for Camera Follow Character in the search bar.
This component has a few settings:
Rail
Type - linear will move the camera straight from start point to end point. Rotation will move around the avatar.
Offsets
The offsets allow you to place the camera in relation to the avatar. Y+ is up. Z+ is forward.
So; X0, Y1, Z2 will put the camera 1 meter above ground, 2 meters in front of the avatar.
Tracking Options
The tracking options will animate the camera in line with the selected bone (Tracking target).
Tracking Target
Start / End Avatar - For two person gestures you can move the camera target from one avatar to the other.
Start - End Target - You can move the camera's focus from one bone to another over the duration of the gesture.
For more info and examples, check [here](/sinespace-sdk/avatars/gestures/animated-cameras.md).
---
### AvatarEffectCameraMovement
#### Overview[β](#overview "Direct link to Overview")
Fields Legacy animation clip drag animation here Child name name of camera in FBX Target name Name of the target camera Tweak axis tweaks orientation of the imported FBX in unity T

#### Fields[β](#fields "Direct link to Fields")
###### Legacy animation clip[β](#legacy-animation-clip "Direct link to Legacy animation clip")
drag animation here
###### Child name[β](#child-name "Direct link to Child name")
name of camera in FBX
###### Target name[β](#target-name "Direct link to Target name")
Name of the target camera
###### Tweak axis[β](#tweak-axis "Direct link to Tweak axis")
tweaks orientation of the imported FBX in unity
###### Tweak position[β](#tweak-position "Direct link to Tweak position")
Tweaks position of the imported FBX in unity
###### Ignore Rotation[β](#ignore-rotation "Direct link to Ignore Rotation")
Ignores rotation of FBX
###### Start Time[β](#start-time "Direct link to Start Time")
Sets the start of animation
###### End Time[β](#end-time "Direct link to End Time")
Sets the end time of the animation
#### Usage[β](#usage "Direct link to Usage")
You can apply animation from an fbx file to the camera using the Avatar Effect Camera Movement Script.
Click on Add Component under the Inspector window, and search for Camera Follow Path in the search bar.
This component has a few settings:
* Legacy Animation Clip
Drag the fbx file containing your animation into the Legacy Animation Clip field. See below for FBX settings.
* Child name
The name of the camera in your FBX file
* Target name
The name of the camera target in your FBX file
* Tweak Axis
Unity's orientation is;
Y+ = Up
Z+ = Forward
If your files export from your animation editor with a different orientation you can align to achieve your desired orientation using the Tweak Axis fields.
* Offset / Ignore rotation
Use these if you want to make universaal adjustments the animation in the editor.
* Start time / End time
Set the end time to the same as your animation file.
For more info and examples, check [here](/sinespace-sdk/avatars/gestures/animated-cameras.md).
---
### AvatarEffectLUT
#### Overview[β](#overview "Direct link to Overview")
Fields LUT Image Drag LUT image here Start Time Start time of LUT effect End Time End time of LUT effect Usage Click on Add Component Under the Inspector window and search for Color LUT in the search bar.

#### Fields[β](#fields "Direct link to Fields")
###### LUT Image[β](#lut-image "Direct link to LUT Image")
Drag LUT image here
###### Start Time[β](#start-time "Direct link to Start Time")
Start time of LUT effect
###### End Time[β](#end-time "Direct link to End Time")
End time of LUT effect
#### Usage[β](#usage "Direct link to Usage")
Click on Add Component Under the Inspector window and search for Color LUT in the search bar.
This has the settings;
* LUT Image- This is the image used for the LUT.
* Start time- Start time of the image playing along with the gesture.
* End time- End time of the image playing along with the gesture.
For more information on how to create the images for the LUT, please go to this page [Gestures/FX](/sinespace-sdk/avatars/gestures/visual-fx.md)
---
### AvatarEffectObject
#### Overview[β](#overview "Direct link to Overview")
Fields Object drag the prop here Start Time Spawn time of the prop End Time DE spawn time of the prop Participant Set the participant type initiator/receiver Destination Choose the

#### Fields[β](#fields "Direct link to Fields")
###### Object[β](#object "Direct link to Object")
drag the prop here
###### Start Time[β](#start-time "Direct link to Start Time")
Spawn time of the prop
###### End Time[β](#end-time "Direct link to End Time")
DE spawn time of the prop
###### Participant[β](#participant "Direct link to Participant")
Set the participant type initiator/receiver
###### Destination[β](#destination "Direct link to Destination")
Choose the bone on which the prop attaches to
#### Usage[β](#usage "Direct link to Usage")
Click on Add Component under the Inspector window, and search for Create object attach in the search bar.
You can add as many separate props as you want, each with their own attachment points or location, and each with their own start and end times.
Drag the prop itself into the Object field.
Use Start Time and End Time fields to set when your prop spawns and despawns.
For single person gestures leave the Participant field as Initator.
For multi-person gestures you can select the Initiator or Recipient for each prop; so you can have them sit down simultaneously, or have them both drop on the floor.
Use the destination drop down to attach your prop to any bone on the skeleton of the avatar, for example, if you wanted an avatar to be holding a whip, you would attach it to the hand bone.
---
### AvatarEffectSnapshot
#### Overview[β](#overview "Direct link to Overview")
Fields Trigger Time Sets the trigger time.

#### Fields[β](#fields "Direct link to Fields")
###### Trigger Time[β](#trigger-time "Direct link to Trigger Time")
Sets the trigger time.
#### Usage[β](#usage "Direct link to Usage")
It will call the snapshot function at the trigger time you set here after start the effect.
The snapshot window is the one as usual, where you can make the snapshot as your profile photo, or upload it to your library or other supported site.
---
### AvatarMultiAnimationEffect
#### Overview[β](#overview "Direct link to Overview")
Fields Clip A Drag the Initiator animation here Clip B Drag the receiver animation here Distance Apart Set the distance between avatars Fix avatar heights Sets avatar height to sta

#### Fields[β](#fields "Direct link to Fields")
###### Clip A[β](#clip-a "Direct link to Clip A")
Drag the Initiator animation here
###### Clip B[β](#clip-b "Direct link to Clip B")
Drag the receiver animation here
###### Distance Apart[β](#distance-apart "Direct link to Distance Apart")
Set the distance between avatars
###### Fix avatar heights[β](#fix-avatar-heights "Direct link to Fix avatar heights")
Sets avatar height to standard
###### IK targets size[β](#ik-targets-size "Direct link to IK targets size")
Fixes discrepancies in avatar sizes and shapes
#### Usage[β](#usage "Direct link to Usage")
Avatar Multi Animation is set up the same as Avatar Effect, but, you will need to set the trigger to 4 under the component settings.
Click on Add Component under the Inspector window, and search for Animate Multiple Avatars in the search bar.
Enable the trigger in the Avatar Effect Script. Set the trigger radius to 4.
Users can initiate a two person gesture inworld with a visible circle around them.
The component has a few settings:
* Clip A / Clip B
Drag the animation takes from the fbx files for each of your two characters into these fields.
Clip A will play on the initiator of the gesture. Clip B will play on the guest.
* Distance Apart
You can offset the characters here if you have not already defined the offset in via the root nodes of your models in your animation editing tool.
* Fix Avatar Heights
If your gesture involves both characters engaging in a very precise interaction, for instance shaking hands, you can align them using Fix Avatar Heights. Gestures played by tall and short avatars may not look correct otherwise.
* Start Time
You can delay the initiation of the animations.
* IK Targets
You can select one or more nodes on the avatars and impose an IK through the animation to correct for discrepancies in avatar sizes and shapes.
You can get more informations and examples at [here](/sinespace-sdk/avatars/gestures.md).
---
### Browser Surfaces
#### Overview[β](#overview "Direct link to Overview")
Examples include using a music video URL for a club, and a training video streaming for business purposes.
Examples include using a music video URL for a club, and a training video streaming for business purposes.
The browser surface script can only be used for streaming from URLs in the desktop client.
##### Browser Surface Script[β](#browser-surface-script "Direct link to Browser Surface Script")
For making a media surface, first make the 3D object you want to use as a screen.
In the inspector window, add the browser surface component to the item you are using for the screen.
This will bring up the browser surface script in the inspector window.
![]()
##### Script Settings[β](#script-settings "Direct link to Script Settings")
Width
Use to set the width of the screen.
Height
Use to set the height of the screen.
Aspect ratios for width and height:
* 1920x1080
* 1024x720
* 3840x2160 (4K)
Zoom
This sets how far the zoom is on the screen.
URL
Place the URL here for the video you want to stream.
Background Color
This is the background color of the screen, which is defaulted to black.
##### YouTube Videos[β](#youtube-videos "Direct link to YouTube Videos")
You can set YouTube videos to play in two different ways, depending on how you want them to be viewed.
You will need to use specific URL addresses for these two different functions.
##### Default to Full-screen[β](#default-to-full-screen "Direct link to Default to Full-screen")
You can choose to set the video to play defaulted at full screen. To do this, choose the YouTube video you want, and copy the video ID.
The video ID is the last component of the URL.

Then, to make the video default to full-screen, you have to use this URL: , and replace the VIDEOID part with the actual video ID.
##### Autoplay[β](#autoplay "Direct link to Autoplay")
You can choose to set the video to autoplay. To do this, first choose the YouTube video you want to stream,then set the autoplay button to autoplay then copy its' URL by righting clicking on the video.
Copy this URL into the browser script URL space, and then add '?rel=0\&autoplay=1' at the end of the URL.

##### Screen Sharing[β](#screen-sharing "Direct link to Screen Sharing")
The media surface works well with screen-sharing applications that stream to the browser.
If you want to use screen sharing, you can use [join.me](https://www.join.me/) or [screenleap.com](http://www.screenleap.com/) to screen share.
##### Recommended Shader[β](#recommended-shader "Direct link to Recommended Shader")
The recommended shader for the screen is a custom shader made by Sine Wave.
[Download EmissiveScreen.shader](/assets/files/EmissiveScreen-447529c4b5fc84badc80a2d864d23745.shader)
Download the file above and drag it into any folder in your Unity project.
Create a new material in your project window by right-clicking and choosing Create>Material in the pop-up menu.
When the new material is in your project window, click on it, and you will see its properties in the inspector window.
On the shader drop-down menu, choose Sine Wave>Emissive Screen.
For the best results, turn the smoothness and metallic sliders down to 0.

##### Viewing the Screen[β](#viewing-the-screen "Direct link to Viewing the Screen")
When you use media surfaces, you are using them so you and other users can view the streaming content. You will need to set up a couple of things to make viewing the content easier.
##### Focus Camera Script[β](#focus-camera-script "Direct link to Focus Camera Script")
The focus camera script is used to create a focus camera. This script needs a target to focus on, and this is where an empty object comes in.
You will need to create a 3D object with a collider attached to it and add the focus camera component to it by choosing the object and clicking on Add Component in the inspector window.
You need to place this 3D object close to your screen but not too close.
Search for focus camera, and add it.
Once it's added, you will see these settings in the focus camera script.
![]()
Target Camera Position
The target camera position is where you want the camera to focus on.
Depth of Field
If you check this, depth of field will be used.
##### Aligning the focus camera[β](#aligning-the-focus-camera "Direct link to Aligning the focus camera")
To align the camera, first, you need to add a camera to your scene (delete the main camera and add a new one). To do this, right-click in the hierarchy and choose 'Camera'.
Now you want to move and rotate this camera so the screen is shown fully in the preview window. The easiest way to move the camera is to use the transform tool and set the position to 0,0,0, then move it until you are satisified with the view.
Here is an example:

As you can see in the preview, the whole screen is in the camera's view.
With the camera selected, in the inspector window, you will see the transform information. The transform information has a small settings button resembling a cog.
Click on this, and it will open up a menu.

In the menu, choose 'Copy Component'. This will copy the transform values of the camera.
Create an empty game object by right-clicking in the hierarchy and choose 'Create Empty'.
Click on the empty game object in the hierarchy, and go to the transform information in the inspector window.
As before, click on the cog, and in the menu, choose 'Paste Component Values'. This will paste the transform values of the camera to the empty game object.
Doing this will ensure that the same view from the camera is now on the empty game object.
##### Choosing the focus camera position[β](#choosing-the-focus-camera-position "Direct link to Choosing the focus camera position")
Now that the empty game object has the correct view of the screen, you will need to set that empty game object to be the focal point of the focus camera.
To do this, click on the 3D object with the focus camera script attached. In the inspector window, you will see the focus camera script settings.
Where it says 'Target Camera Position, drag the empty game object from your hierarchy into this box.
It should look like this.
![]()
You can choose whether or not to use depth of field.
Choosing to turn on depth of field will blur the areas of the surface which the camera is not immediately focused on.
After you have finished with these settings, you can either add the surface into Space as a virtual good or use it in a region and upload the region.
---
### CatalogVendor
#### Overview[β](#overview "Direct link to Overview")
Fields Brand Name or your brand Tagline Tagline for your brand Brand Text Drop UI/3d text for your brand TagLineText Drop UI/3d tagline text for your brand Category Select a catego

#### Fields[β](#fields "Direct link to Fields")
###### Brand[β](#brand "Direct link to Brand")
Name or your brand
###### Tagline[β](#tagline "Direct link to Tagline")
Tagline for your brand
###### Brand Text[β](#brand-text "Direct link to Brand Text")
Drop UI/3d text for your brand
###### TagLineText[β](#taglinetext "Direct link to TagLineText")
Drop UI/3d tagline text for your brand
###### Category[β](#category "Direct link to Category")
Select a category to be displayed
#### Usage[β](#usage "Direct link to Usage")
You can attach this component to an NPC or an object, in your region and it will open the Shopping window to your brand name and items can also be selected by category.
Brand Name Enter your brand name or brand name of the creator your wish to display. The shopping window will be filtered by this name.
Tag line You can set a tagline of your brand here.
Brand Text you can set a 3D or WorldUI brand name text by dropping the item here.
TagLine text you can set a 3D or WorldUI Tagline text by dropping the item here.
Category Select category you wish to display. If not category is select, all the items under your brand name will be shown.
---
### ClickableActivator
#### Overview[β](#overview "Direct link to Overview")
This can be used to open/close doors, lights and all the things you need to activate with a click.
This can be used to open/close doors, lights and all the things you need to activate with a click.

Click the add sign then drag the item want to activate into the slot, then choose an action you need.
The Network options define whether the action will be synchronized with other users in the region.
If you want to control an object which has already got a network ID(for example, defines in Room Floor component), you should use that ID and pick "Override Network ID" to avoid conflicts.
Here is an example to create an object with Open/Close animations:

The component supports play 2 animation like this, to realize a door open/close by clicking it.
Note: you should untick the Loop Time checkbox for each animation or it will cause problems.
---
### Clickable Teleporter
#### Overview[β](#overview "Direct link to Overview")
This tutorial will show you how to turn an object into a clickable teleporter that you can use so visitors can transport to another region in SineSpace with the click of a button.
This tutorial will show you how to turn an object into a clickable teleporter that you can use so visitors can transport to another region in SineSpace with the click of a button.
#### Find and select an object to turn into a clickable teleporter[β](#find-and-select-an-object-to-turn-into-a-clickable-teleporter "Direct link to Find and select an object to turn into a clickable teleporter")
First, in the Unity Editor you need to select an object to add the functionality to. This can either be an object in a scene, or an object that will be uploaded as furniture. The example shows a simple sign that has been created as furniture.
#### Add the Scripting Runtime component[β](#add-the-scripting-runtime-component "Direct link to Add the Scripting Runtime component")
After selecting the object, in the Inspector panel click on the Add Component button and start typing 'Scripting Runtime' - as you type, you will see search results and can click once you see it.
#### Enter the script[β](#enter-the-script "Direct link to Enter the script")
Copy and Paste in the code below into the Scripting Runtime component
regionID = 15 coordinates = Vector.New(0,100,0) rotation = Quaternion.Euler(0,15,0)
function activate() Space.Scene.PlayerAvatar.Teleport(regionID, coordinates, rotation) end
After you've pasted in the text, replace the regionID in the top line with your destination's regionID. If the destination is your build, you can find the region ID on the [Curator site's Items page](https://curator.sine.space/items/list), on the listing for that region. If the destination is someone else's build, you will need to talk to the region owner to get their permission and the region ID *(as well as the coordinates below)*.
The coordinates and rotation values *(lines 2 and 3 of the above script)* is where you want the avatar to arrive in your region. If you are not sure what to use, enter the transform coordinates from your region's main landmark.
Once you've entered the coordinates, change the dropdown setting for Index to Legacy.
#### Add the Clickable Activator component[β](#add-the-clickable-activator-component "Direct link to Add the Clickable Activator component")
Now that the script is ready, you add a Clickable Activator to call it. Click the Add Component button and start typing 'clickable' and you should see it appear in the search results
To configure the component, first you need to drag your GameObject from the scene hierarchy into the Object slot. Once you do that, you will be able to set the rest of the On Click Event () section up as pictured below. Enter whatever you like in the Tooltip section, this will display to users when they hover over your object in-world.
#### Upload and test in-world[β](#upload-and-test-in-world "Direct link to Upload and test in-world")
Finish and upload your region or furniture item and test it on the preview grid. The clickable object should highlight when you hover your pointer over it, and then clicking should transport you to your destination.
---
### Clothing Previewer
#### Overview[β](#overview "Direct link to Overview")
.png>) Fields Player Outfit ID Here you can add one of your saved outfits by copying the outfit ID from the viewer outfit window.
![]()
#### Fields[β](#fields "Direct link to Fields")
###### Player Outfit ID[β](#player-outfit-id "Direct link to Player Outfit ID")
Here you can add one of your saved outfits by copying the outfit ID from the viewer outfit window.
###### Detail Level[β](#detail-level "Direct link to Detail Level")
The detail level of the preview.
###### Clothing Item[β](#clothing-item "Direct link to Clothing Item")
The clothing item you want to preview.
Pattern The clothing pattern you want to preview.
info
When using patterns, make sure to also include the original item in the βClothing Itemβ slot.
---
### Collider Trigger Activator
#### Overview[β](#overview "Direct link to Overview")
Fields Triggers Owner Only If checked this script will ignore owner.

#### Fields[β](#fields "Direct link to Fields")
##### Triggers[β](#triggers "Direct link to Triggers")
###### Owner Only[β](#owner-only "Direct link to Owner Only")
If checked this script will ignore owner. i.e not will happen if owner is within the range.
###### Exclude owner[β](#exclude-owner "Direct link to Exclude owner")
if checked the effect will only trigger on client side. i.e triggered effect won't be shown to all avatars present in the regions. (better performance in certain cases.)
##### Events[β](#events "Direct link to Events")
Events Activate Click the add sign then drag the item to be activated when avatar is within the range here. Then select what function should be activated. Eg: Particle system function select start. You can click on add to add multiple items and select function for each
Events Deactivate Click the add sign then drag the item to be deactivated when avatar is out of the range here. Then select what function should be activated. Eg: Particle system function select start. You can click on add to add multiple items and select function for each.
#### Usage[β](#usage "Direct link to Usage")
This can be used to open/Close doors. Activate deactivate particle effects. Auto light the interior of a house etc.
---
### Components by Function
#### Overview[β](#overview "Direct link to Overview")
This page lists particularly common functionalities, and describes the best tool for the job with a focus on commonly used terms in other popular virtual worlds.
This page lists particularly common functionalities, and describes the best tool for the job with a focus on commonly used terms in other popular virtual worlds.
##### Animate Anything[β](#animate-anything "Direct link to Animate Anything")
* Use Mecanim, you can animate *anything* - objects, materials/textures, texture scrolling, skinned animation (including mocap imports). Can be used on any object (Clothing, Gestures, Regions, Vehicles, etc.) See [Unity Documentation](https://docs.unity3d.com/Manual/AnimationOverview.html)
##### Doors[β](#doors "Direct link to Doors")
* Use Mecanim (see above) and one of:
* [Components/ProximityActivator](/sinespace-sdk/components/proximity-activator.md)
* [Components/ClickableActivator](/sinespace-sdk/components/clickable-activator.md)
* World Space UI Canvas (Unity Feature) -- use to make buttons.
##### Seat / Poseball[β](#seat--poseball "Direct link to Seat / Poseball")
* [Components/SeatImproved](/sinespace-sdk/furniture/seatimproved.md)
##### Tip Jars[β](#tip-jars "Direct link to Tip Jars")
* Check [Tip Jar](/sinespace-sdk/components/tip-jars.md) for details.
##### NPC[β](#npc "Direct link to NPC")
See:
* [Components/Statue](/sinespace-sdk/components/statue.md) - base NPC component
* [Components/WanderingNPC](/sinespace-sdk/components/wandering-npc.md)
* [Components/QuestNPC](/sinespace-sdk/components/quest-npc.md)
* [Components/QuestDesigner](/sinespace-sdk/quests/questdesigner.md)
##### Audio[β](#audio "Direct link to Audio")
Music, see:
* [Components/StreamingBackgroundMusic](/sinespace-sdk/components/streaming-background-music.md) - for linked MP3/OGG files.
* [Components/SceneBackgroundMusic](/sinespace-sdk/components/scene-background-music.md) - for Shoutcast/streaming music.
SFX and Environmental Audio:
* See Unity Manual, all parts work (including Reverb Zones and other audio filters and effects like low/high-pass, distortion, echo, etc.) [Audio Sources](https://docs.unity3d.com/Manual/class-AudioSource.html)
##### Particles[β](#particles "Direct link to Particles")
* Use Shuriken, the [Unity3d Particle System](https://docs.unity3d.com/Manual/ParticleSystems.html)
##### Vendor / Merchant[β](#vendor--merchant "Direct link to Vendor / Merchant")
See:
* [Components/InventoryVendor](/curator-dashboard/items/inventoryvendor.md)
* [Components/CatalogVendor](/sinespace-sdk/components/catalog-vendor.md)
##### Teleports[β](#teleports "Direct link to Teleports")
See:
* [Components/TeleportPad](/sinespace-sdk/components/teleport-pad.md) - intraregion teleports with UI
* [Components/TeleportLocal](/sinespace-sdk/components/teleport-local.md) - intraregion teleports
* [Components/TeleportWorld](/sinespace-sdk/components/teleport-world.md) - interregion teleports
##### Vehicles[β](#vehicles "Direct link to Vehicles")
See:
* [Vehicles](/sinespace-sdk/vehicles.md)
##### Clothing Customisation[β](#clothing-customisation "Direct link to Clothing Customisation")
##### HUDs[β](#huds "Direct link to HUDs")
* Use a UI Canvas (Unity, see [documentation](https://docs.unity3d.com/Manual/UICanvas.html)). Screen Space or World Space, can be embedded in regions.
* You *probably* don't need these.
##### Gatcha / Lucky Dip[β](#gatcha--lucky-dip "Direct link to Gatcha / Lucky Dip")
See:
---
### Customize Components
#### Overview[β](#overview "Direct link to Overview")
If you want to create your own special game in Sinespace, you may find that itβs very important to know how to customize the components -- instead of throwing all things to lua scr
If you want to create your own special game in Sinespace, you may find that itβs very important to know how to customize the components -- instead of throwing all things to lua script, using the components we offered in the Editor pack with a clear logic should be the best way for creation.
Basically, we could let you do the same thing as you can do in Unity vanilla(which means the pure original version of Unity, doesnβt include 3rd party plug-ins), but we still havenβt package all the things into our SDK. So, if you find something can easily done in Unity, but feel hard to realize it in Sinespace, donβt hesitate to contact the staff.
Here I will show some easy examples for you to create different types of game.
##### A collider-based checkpoint in racing game[β](#a-collider-based-checkpoint-in-racing-game "Direct link to A collider-based checkpoint in racing game")
*Note: This is one component like I said above. It uses a component called Trigger Activator -- originally it only functions with Avatars, when you drive a car in Sinespace and pass a collider with Trigger Activator, it wonβt be activated. In future version(test/release build from 2019 Feb), this Trigger Activator will also affected by vehicles, so you can use this component and a isTrigger Box collider to simply create a checkpoint/start-finish line(but of course you may still need lua script if you want to put a counter or some other function which is not directly supported by unity in it).*

For example, in this scene, we have a thin box collider between two cylinder here, works as a checkpoint. When the vehicle pass it, it will play the particle effect(no loop), raise the counter by 1, and refresh a text of the counter indicator on the UI layer.
*Because of unknown reason, it is suggested that not have any other collider contact with this box collider, otherwise the event will be triggered once when the region is loaded. Or you can check the Exclude Owner option to avoid this happen(but it will also cause your avatar wonβt be able to trigger the event anymore, which may be annoying when doing the tests).*
Using the component βScripting Runtimeβ to add lua script to game objects. Donβt worry if you are not familiar with writing codes -- to create a game, the logic is more important than the technique of programming. It is more important that before doing the work, make yourself be clear about what function you need, and a simple way to realize it.
In this example, we can use a simple flow-process diagram to show what we want to do:

So from this diagram, you may find out what you need to prepare for realizing these.
Let's do them one by one.
First, create a Text object, and change its name to something unique, i.e. here it's "checkpointindicator". Add Scripting Runtime to it, and add the code below:
```lua
Space.Shared.SetGlobal("racingComponent", "ctr", 0);
counter = Space.Shared.GetGlobal("racingComponent", "ctr");
local obj = Space.Host.ExecutingObject;
obj.UIText.text = "Counter:" .. counter;
function RefreshText()
counter = Space.Shared.GetGlobal("racingComponent", "ctr");
obj.UIText.text = "Counter:" .. counter;
end
```
It declare a global variable and initialize it with 0 using SetGlobal, which can be used in other script by using GetGlobal. Then find the Text component attached to itself.
The function RefreshText is the function refresh the text when the counter's value changes. It will only be effected when called.
For example, when can call it when the vehicle exit the collider of checkpoint:

The code for the checkpoint is like below:
```lua
local obj = Space.Host.ExecutingObject;
local particle = obj.ParticleSystem;
local txt = Space.Scene.Find("Notify");
function AddCounter()
counter = Space.Shared.GetGlobal("racingComponent", "ctr");
if(counter == 0)
then
counter = counter + 1;
Space.Shared.SetGlobal("racingComponent", "ctr", counter);
particle.Play();
txt.UIText.text = "";
Space.Log("counter:" .. counter);
else
txt.UIText.text = "Checkpoint Missed";
end
end
```
Notify is another Text gameobject for showing the message of missing checkpoint. To find other object in the scene, use function Space.Scene.Find(object name) is one method, that's why set a unique name to game object is needed.
When a checkpoint is ready, you can duplicate them, and don't forget to modify the line "if(counter == 0)", where the 0 should be n-1 where the n is the order of the checkpoint.
And for finish line:
```lua
local obj = Space.Host.ExecutingObject;
local particle = obj.ParticleSystem;
local txt = Space.Scene.Find("Notify");
local txt2 = Space.Scene.Find("CheckpointIndicator");
function Reset()
counter = Space.Shared.GetGlobal("racingComponent", "ctr");
if(counter == 3)
then
particle.Play();
txt.UIText.text = "";
txt2.UIText.text = "Finished!";
counter = 0;
Space.Shared.SetGlobal("racingComponent", "ctr", counter);
else
txt.UIText.text = "Checkpoint Missed";
end
end
```
I put 3 checkpoints in total, so here the check condition is counter == 3. You can also add a lap counter in this finish line so it can use for multiple laps race. The function Reset will be called when the vehicle reach the finish line.
---
### Day/night cycle
#### Overview[β](#overview "Direct link to Overview")
First you will need a directional light to which to attach the script component.
First you will need a directional light to which to attach the script component. A directional light was included when you created a new scene. If one isn't in the hierarchy panel (maybe you deleted it), you'll need to add one. Go to the menus at the top of the editor window and click Game Object - Light - Directional Light.
You'll need to add the Day Night Circle component (script) to your directional light. You can create a new empty object to attach with this component.
***
![]()
***
###### Component Settings[β](#component-settings "Direct link to Component Settings")
#### **Preview**[β](#preview "Direct link to preview")
Preview is where you can toggle on and off 'Preview Enabled' to be able to see the lighting for different times of day in your Unity scene. You can drag the Preview Time of Day along to see what different times of day look like. The slider is set to 0 to begin with, this is midnight. 0.5 is midday. You should disable the preview before uploading the region.
#### **Clock Set-up**[β](#clock-set-up "Direct link to clock-set-up")
By default, the light will be particularly harsh, the cycle will be set to 1440 minutes (a full 24 hr day), and start from mid night. You can modify the duration as you wish. Toggle the "Use local System Clock" on will use your local timestamp instead of using server time.
If you pick "Use Fixed", the time will be locked, you can set the time you want fixed by modify the slider bar of "Fixed Time of Day", the value is from 0 to 1, corresponding the color bar of sun.
#### **Sun Light**[β](#sun-light "Direct link to sun-light")
Next drag the "Sun light" object into the Sun Light slot. If you create the region by using quick start, then it's the object called "Directional Light" that controls the sun light. You can find the Quick-start region by going to Assets>Sample Art>Quickstart in the Project window.
| |
| -------------------------------- |
| *Fig. 2: How to find quickstart* |

| |
| ------------------------------------ |
| *Fig. 3: Directional Light Settings* |
![]()
If white light is too harsh for you, you can change the color of this by changing the 'Sun Light' color on the Day /Night cycle component, not on the directional light.
You will need to change the 'Flare' setting on the Directional Light so that the flare is set to Sun. You can do this by clicking on the circle next to the Flare box, and choose Sun.
##### **Environmental Cubemaps**[β](#environmental-cubemaps "Direct link to environmental-cubemaps")
This is to update the reflection probes in the region. The 'Update Cubemap Frequency' number is in seconds, so if you want to update the cubemap frequency every 30 seconds, leave it as it is. This basically changes the amount of light reflection on objects in the region, e.g. at night time you don't want reflective surfaces to reflect too much light.
##### **Sun Light**[β](#sun-light-1 "Direct link to sun-light-1")
This is where you drag in the directional light for the 'Sun'. You can set the color of the sunlight here, and also set the Sun Offset Rotation and Sun Rotation Axis. The Sun Offset Rotation and Sun Rotation Axis control the value of the movement of the sun during the day time. If you don't need a custom trail of movement for the sun, just leave it as default.
##### **Sun Shafts**[β](#sun-shafts "Direct link to sun-shafts")
The Sun Shafts image effect simulates the radial light scattering (also known as the βgod rayβ effect) that arises when a very bright light source is partly obscured. Here you can change the colors of the sun shafts. You can check the 'Update Sun Shafts' to keep the sun shafts updated when objects are placed in the region.
##### **Ambient Light**[β](#ambient-light "Direct link to ambient-light")
This will change the ambient light in the region. You can change the sky color, Equator color (This is the horizon area) and ground color.
##### **Fog**[β](#fog "Direct link to fog")
You can change the colors for fog here and change the fog minimum curve and maximum curve. The fog curves set the minimum distance and maximum distance of fog, which in turn changes the amount of fog at certain times of day. You can click on the fog bar to change the curve between the values of 0 and 1.
##### **Water Set-up**[β](#water-set-up "Direct link to water-set-up")
If you have water-like things in your scene, you can attach its material to the water material slot, which can make the light affect to the water too. You can change the colors for the water here if you wish.
##### **Events**[β](#events "Direct link to events")
You can add events like playing music and animations. The events trigger is set to Dawn, Midday, Dusk, and Midnight. You can set this up to notify specific animators as well.
##### **Shader Parameters**[β](#shader-parameters "Direct link to shader-parameters")
Toggling the 'Use local System Clock' and 'Shader send time of day' together will align your day/night cycle with your real-world local time. The Shader Send Color option will send the colors under the shader bar to the Lighting, meaning the lighting will change to these colors at certain times of day.
---
### EdyCompatibleVehicle
#### Overview[β](#overview "Direct link to Overview")
This component allows you to turn a vehicle designed using \[Edy's Vehicle Physics] in Space.
This component allows you to turn a vehicle designed using \[Edy's Vehicle Physics] in Space. It must be attached to the same object that contains 'Car Control', 'Car Settings' and 'Car Cameras', if any of these components are missing, it will not function.
Note: This component has not been tested in a while; it may have bugs. Please report them if you find them.
---
### Enemy NPCs and NPC spawners
#### Overview[β](#overview "Direct link to Overview")
FPS Components Shooter games FPS The safe zone lobby Guns and gun givers Health and ammo givers Traps King of the hill zone Player spawn points The NPC Spawners spawn NPCs that will then attack players.
###### FPS Components[β](#fps-components "Direct link to FPS Components")
[Shooter games FPS](/sinespace-sdk/games/shooter-games-fps.md)
[The safe zone lobby](/sinespace-sdk/games/the-safe-zone-lobby.md)
[Guns and gun givers](/sinespace-sdk/games/guns-and-gun-givers.md)
[Health and ammo givers](/sinespace-sdk/games/health-and-ammo-givers.md)
[Traps](/sinespace-sdk/games/traps.md)
[King of the hill zone](/sinespace-sdk/games/king-of-the-hill-zone.md)
[Player spawn points](/sinespace-sdk/games/player-spawn-points.md)
The NPC Spawners spawn NPCs that will then attack players. Standard NPCs currently attack with melee actions. (Ranged NPCs are in development.)
Enemy NPCs have configurable settings for range, attack rate and damage, and for damage, attack, death and victory events.
NPC Spawners are placeable inventory items that players can deploy in their maps and which will spawn NPCs according to their settings. Individual NPC spawners can spawn multiple NPC types.
Public variables on the NPC spawner allow players to customise settings including spawn rate and lifetime of NPCs.
This video tutorial shows how to configure and publish your own Enemy NPCs and NPC Spawners as inventory items that players can in place in their multi-player maps in Sinespace;
[Watch on YouTube](https://youtube.com/watch?v=V2-5ATy5kTs)
##### NPCS[β](#npcs "Direct link to NPCS")
1. Public Variables
There are 15 public variables on the NPC.
1. attackModes
This number should parallel the number set up in the NPCβs Animation Controller.
In the default Animation Controller there are four unique attack moves, two damage moves, one kill celebration and one death move.
You can alter these but remember to define that in the parameters here. Animations are selected randomly.
1. attackRange
Attack range is the distance from the player at which the NPC will begin itβs attack animation.
To get a good experience you want to align three different distances; the **attackRange**, the **meleeRange** (below) and the radius of the collider on the NPC.
The collider hitting the player is the actual damage event.
The **meleeRange**, also a public variable on the NPC script, defines the closest the NPC will get to the player; if it gets too close then the playerβs gun will stick out behind the NPC and the player will not be able to shoot the NPC.
The NPC may be partially off camera and itβs attack animations will probably look wrong.
For a regular biped you might set **attackRange** to 2 meters, set the radius of the collider to 1.5 and set the **meleeRange** to 1 meter.
1. deathModes
deathModes, like the attackModes, defines the number of death sequences the NPC will randomly select from. Double click on the dying node in the first layer of the Animation Controller and you can see the four options the default art pack offers.
1. damageModes
damageModes are also randomly selected, as animations playing when the NPC takes damage.
1. meleeRange
meleeRange is the closest the NPC will get to the player before stopping moving toward the player.
1. intervalNoTarget
intervalNoTarget defines how often the NPC will scan the scene looking for players during itβs idle cycles. It defaults to 5 seconds which to be honest makes for some pretty sleepy NPCs. You might set yours to 1 second.
Much lower than that could impact performance in a scene full of NPCs.
1. intervalTarget
intervalTarget defines how often the NPC scans for players when it is actively hunting and attacking a player; the default is .25 seconds which should be sufficient for any NPC.
1. viewDistance
viewDistance defines how far the NPC can see. The NPC cannot see behind itself. It will attack if a player shoots it but does not (yet!) attack if it sees a bullet go by.
1. viewHeight
viewHeight is the height the NPC scans for players at. If you are working with our standard character player avatar system or any regular biped costume avatars you shouldnβt need to adjust this.
1. attackSpeed
attackSpeed defines how fast the NPC moves when hunting and attacking the player.
1. wanderSpeed
wanderSpeed defines the NPCβs idle movement speed.
1. collisionDamageValue
collisionDamageValue defines how much damage the NPC does each time it strikes.
1. collisionInterval
collisionInterval defines how often the NPC inflicts damage when the player is within the NPCβs collider.
1. repeatDamage
repeatDamage is a toggle, 0 or 1. Leave it on 1 for any regular attacking NPC. If you are creating some kind of bomb or other single attack event set repeatDamage to 0 to go off only once when triggered.
1. startHealth
startHealth defines the amount of health the NPC has when it spawns.
1. Events
There are 9 available events on the NPC.
* Spawn
* Hide
* Die
The Spawn, Hide and Die events are configured with specific triggers that the game depends on. Please donβt change these settings.
* Discover
* Attack
* Attackend
* Losttarget
* Damage
* Kill The other six are available for triggering various events at your discretion.
1. Object references
There are three object references;
* HealthValue\*\* and **HealthWrapper** reference the world space canvas on the NPC that is hovering over its head.
You can change the font and size of these if you want to bring them in line with the rest of your game UI.
The **animator** references the AO for the NPC.
The **Trigger activator** triggers damage from the capsule collider. Again note it needs to be set to owner only.
The **navmesh agent and character controller** are both standard Unity components. Both are required for the NPC to function. The default settings should be fine for a regular biped.
Please note the navmesh agent should be left disabled in your project.
##### NPC spawner[β](#npc-spawner "Direct link to NPC spawner")
The NPC Spawner is a spawnable furniture item that players can place in their maps to spawn enemt NPCs that will attack players.
1. Public variables
There are seven public variables.
1. npcTypes
npcTypes defines the number of different NPCs that the spawner will emit.
Each NPC type needs to be referenced in the **Resources** below. If you upload a spawner that spawns 3 enemy types and you let the player change the number, going over 3 wontβ do anything.
Coming down to 2 or 1 will cut back on a numbered basis; e.g. if the player sets this to 1 inworld then only the npc1 in the **Resources** will spawn.
1. npcPoolSize
npcPoolSize defines the number of NPCs that will be created and set inactive, per type, per spawner in the scene. Running a pool of NPCs improves performance compared to destroying and creating NPCs individually.
To calculate the appropriate pool size you need to consider three factors;
* Lifetime of NPC
* Spawn rate
* Types
For example, if the lifetime of an NPC is 60 seconds and the spawn rate is three seconds you can only ever have two in the scene at once from that spawn point. So the pool required is 2 max.
If you have multiple different types the pool actually comes down because it will pool for every type and it will cycle through types in order not randomly.
To cross check your pool size use this calculation;
Lifetime / spawn interval / type, then round up.
* npcSpawnMinRange and npcSpawnMaxRange\*\* define the radius from the Spawner where the NPCs will appear.
You might want them to spawn from one single spawner across the whole map randomly or you might want to lock it down so they visually appear in the middle of a visible portal.
* npcLifetime\*\* defines the lifetime of individual NPCs, which will die on their own when their lifetime expires.
You might want to set this to be higher than the default 60 seconds. If you set it too high you will risk exceeding your pool and further NPCs may not spawn until the available ones are killed.
If you dramatically increase both the pool and the npcLifetime you might hit some performance issues.
If you are developing a map or a game that is more like a coop campaign than an arena then you might set your npcLifetime very high and the spawn rate (the delay between spawing) very high too.
You can also put a trigger on the spawner itself that switches it off completely once the first generation of NPCs are spawned.
* npcSpawnHeight\*\* lifts the biped above the ground when it spawns to ensure it does not spawn fractionally below the terrain.
1. Resources
Add all your NPC types to the **resources** slots available. The name of the prefab doesnβt matter but the naming convention on the resources does and it should be npc1 npc2 etc. all lower case.
1. Events
There is one **event** available which is the spawn event. You can add a particle effect or anything else you want to coincide with the enemy being spawned.
---
### FocusCamera
#### Overview[β](#overview "Direct link to Overview")
Fields Target Camera Position Drag the target Camera here Use Depth of field Enables depth of Field on camera Usage When combined with other components, it can be used as switching

#### Fields[β](#fields "Direct link to Fields")
###### Target Camera Position[β](#target-camera-position "Direct link to Target Camera Position")
Drag the target Camera here
###### Use Depth of field[β](#use-depth-of-field "Direct link to Use Depth of field")
Enables depth of Field on camera
#### Usage[β](#usage "Direct link to Usage")
When combined with other components, it can be used as switching the view from your avatar to this extra camera by a clickable activator.
You can check [here](https://app.gitbook.com/o/-M1WuIvOi8-UsP7Qc00_/s/-MAUay5St6OsKydrbQTw/~/changes/101/sinespace-sdk/components/browser-surfaces#focus-camera-script) for an example of utilisation.
---
### FollowAvatar
#### Overview[β](#overview "Direct link to Overview")
Fields Offset Position Offset (World Coords) Usage Once an object with this component is active in a region, each user in the region will have this object following him, but it doesn't show to other clients.

#### Fields[β](#fields "Direct link to Fields")
###### Offset[β](#offset "Direct link to Offset")
Position Offset (World Coords)
#### Usage[β](#usage "Direct link to Usage")
Once an object with this component is active in a region, each user in the region will have this object following him, but it doesn't show to other clients.
The position can be offset with a world-space offset specified compared to the player's Avatar in the Offset field.
info
*this component is easy to create some visual effect which only shows to the player. This is not the one for creating following pets/minions.*
---
### General
#### Overview[β](#overview "Direct link to Overview")
This page lists every Sinespace SDK component, grouped by function.
#### Common & creator[β](#common--creator "Direct link to Common & creator")
* [Components by Function](/sinespace-sdk/components/components-by-function.md)
* [Customize Components](/sinespace-sdk/components/customize-components.md)
* [Virtual Goods](/sinespace-sdk/components/virtual-goods.md)
#### Avatar effects & gestures[β](#avatar-effects--gestures "Direct link to Avatar effects & gestures")
* [Avatar Animation Effect](/sinespace-sdk/components/avatar-animation-effect.md)
* [Avatar Audio Effect](/sinespace-sdk/components/avatar-audio-effect.md)
* [Avatar Effect](/sinespace-sdk/components/avatar-effect.md)
* [Avatar Effect Camera](/sinespace-sdk/components/avatar-effect-camera.md)
* [Avatar Effect Camera Movement](/sinespace-sdk/components/avatar-effect-camera-movement.md)
* [Avatar Effect LUT](/sinespace-sdk/components/avatar-effect-lut.md)
* [Avatar Effect Object](/sinespace-sdk/components/avatar-effect-object.md)
* [Avatar Effect Snapshot](/sinespace-sdk/components/avatar-effect-snapshot.md)
* [Avatar Multi Animation Effect](/sinespace-sdk/components/avatar-multi-animation-effect.md)
* [Clothing Previewer](/sinespace-sdk/components/clothing-previewer.md)
* [Follow Avatar](/sinespace-sdk/components/follow-avatar.md)
#### Vehicles[β](#vehicles "Direct link to Vehicles")
* [Edy Compatible Vehicle](/sinespace-sdk/components/edy-compatible-vehicle.md)
* [Modular Buoyancy](/sinespace-sdk/components/modular-buoyancy.md)
* [Sail Strip](/sinespace-sdk/components/sail-strip.md)
* [Slider Vehicle](/sinespace-sdk/components/slider-vehicle.md)
* [Speedometer](/sinespace-sdk/components/speedometer.md)
* [Vehicle Physical Animator](/sinespace-sdk/components/vehicle-physical-animator.md)
* [Vehicle Respawn](/sinespace-sdk/components/vehicle-respawn.md)
#### Teleporting[β](#teleporting "Direct link to Teleporting")
* [Clickable Teleporter](/sinespace-sdk/components/clickable-teleporter.md)
* [Teleport Local](/sinespace-sdk/components/teleport-local.md)
* [Teleport Pad](/sinespace-sdk/components/teleport-pad.md)
* [Teleport World](/sinespace-sdk/components/teleport-world.md)
#### Quests[β](#quests "Direct link to Quests")
* [Quest Counter Clickable](/sinespace-sdk/components/quest-counter-clickable.md)
* [Quest Counter Proximity](/sinespace-sdk/components/quest-counter-proximity.md)
* [Quest Game Object](/sinespace-sdk/components/quest-game-object.md)
* [Quest NPC](/sinespace-sdk/components/quest-npc.md)
* [Startable Clothing Requirement](/sinespace-sdk/components/startable-clothing-requirement.md)
* [Startable Gesture Requirement](/sinespace-sdk/components/startable-gesture-requirement.md)
* [Startable Item Requirement](/sinespace-sdk/components/startable-item-requirement.md)
* [Startable Room Visit](/sinespace-sdk/components/startable-room-visit.md)
* [Startable Sit Requirement](/sinespace-sdk/components/startable-sit-requirement.md)
* [Startable Snapshot](/sinespace-sdk/components/startable-snapshot.md)
* [Startable Teleport](/sinespace-sdk/components/startable-teleport.md)
* [Startable Timed Counter](/sinespace-sdk/components/startable-timed-counter.md)
#### NPCs[β](#npcs "Direct link to NPCs")
* [Enemy NPCs and NPC Spawners](/sinespace-sdk/components/enemy-npcs-and-npc-spawners.md)
* [NPC Crowd](/sinespace-sdk/components/npc-crowd.md)
* [NPCs](/sinespace-sdk/components/npcs.md)
* [Statue](/sinespace-sdk/components/statue.md)
* [Upgrade Account NPC](/sinespace-sdk/components/upgrade-account-npc.md)
* [Wandering NPC](/sinespace-sdk/components/wandering-npc.md)
#### Merchant & vendors[β](#merchant--vendors "Direct link to Merchant & vendors")
* [Animated Vendor Console](/sinespace-sdk/components/animated-vendor-console.md)
* [Animation Vendor](/sinespace-sdk/components/animation-vendor.md)
* [ATM](/sinespace-sdk/components/atm.md)
* [Catalog Vendor](/sinespace-sdk/components/catalog-vendor.md)
* [Modular Vendors](/sinespace-sdk/components/modular-vendors.md)
* [Tip Jars](/sinespace-sdk/components/tip-jars.md)
* [Vendors for Your Business Region](/sinespace-sdk/components/vendors-for-your-business-region.md)
#### Zones & environment[β](#zones--environment "Direct link to Zones & environment")
* [Audio Reactive](/sinespace-sdk/components/audio-reactive.md)
* [Day-Night Cycle](/sinespace-sdk/components/day-night-cycle.md)
* [Gravity Zone](/sinespace-sdk/components/gravity-zone.md)
* [Lens Flare Distance](/sinespace-sdk/components/lens-flare-distance.md)
* [Meta Balls](/sinespace-sdk/components/meta-balls.md)
* [Music Zone](/sinespace-sdk/components/music-zone.md)
* [Scene Background Music](/sinespace-sdk/components/scene-background-music.md)
* [Streaming Background Music](/sinespace-sdk/components/streaming-background-music.md)
* [Substitute Animation Zone](/sinespace-sdk/components/substitute-animation-zone.md)
* [Voice Zone](/sinespace-sdk/components/voice-zone.md)
* [Volumetric Light](/sinespace-sdk/components/volumetric-light.md)
#### Activators & triggers[β](#activators--triggers "Direct link to Activators & triggers")
* [Clickable Activator](/sinespace-sdk/components/clickable-activator.md)
* [Collider Trigger Activator](/sinespace-sdk/components/collider-trigger-activator.md)
* [Proximity Activator](/sinespace-sdk/components/proximity-activator.md)
#### Other components[β](#other-components "Direct link to Other components")
* [Browser Surfaces](/sinespace-sdk/components/browser-surfaces.md)
* [Focus Camera](/sinespace-sdk/components/focus-camera.md)
* [Mailbox](/sinespace-sdk/components/mailbox.md)
* [Move Object](/sinespace-sdk/components/move-object.md)
* [Pool](/sinespace-sdk/components/pool.md)
* [Simple Networking](/sinespace-sdk/components/simple-networking.md)
* [Simple State Machine](/sinespace-sdk/components/simple-state-machine.md)
* [Synced Physics Doodad](/sinespace-sdk/components/synced-physics-doodad.md)
* [Timer](/sinespace-sdk/components/timer.md)
* [VIP Collider](/sinespace-sdk/components/vip-collider.md)
---
### GravityZone
#### Overview[β](#overview "Direct link to Overview")
Fields Priority Sets the priority Local Gravity Set the gravity values for x,y,z axis Usage Create an empty object add GravityZone component.

#### Fields[β](#fields "Direct link to Fields")
###### Priority[β](#priority "Direct link to Priority")
Sets the priority
###### Local Gravity[β](#local-gravity "Direct link to Local Gravity")
Set the gravity values for x,y,z axis
#### Usage[β](#usage "Direct link to Usage")
Create an empty object add GravityZone component. Add a Box collider with isTrigger checked, edit the constrains of the box collider to set the area size.
Priority Sets the priority of the gravityzone
local Gravity Sets the local gravity for x,y,z axis.
As an example, the default gravity could be Priority = 10, and the axis is (0,-1,0). If you want to make an environment like moon, set the Priority < 10, otherwise Priority > 10.
(0,-1,0) means the direction of Gravity is downward. You can also set to another direction as your wish.
---
### LensFlareDistance
#### Overview[β](#overview "Direct link to Overview")
Fields Min Distance Sets min distance for lens flare.

#### Fields[β](#fields "Direct link to Fields")
###### Min Distance[β](#min-distance "Direct link to Min Distance")
Sets min distance for lens flare.
###### Max Distance[β](#max-distance "Direct link to Max Distance")
Sets max distance for lens flare.
---
### Mailbox
#### Overview[β](#overview "Direct link to Overview")
Fields Mail Animation to play Open Mail On-Click Sound Mail Arrive On-Mail Arrive Sound This is used to create Mail boxes within the scene; specifically objects which when clicked on will open the players Mail window.

#### Fields[β](#fields "Direct link to Fields")
###### Mail[β](#mail "Direct link to Mail")
Animation to play
###### Open Mail[β](#open-mail "Direct link to Open Mail")
On-Click Sound
###### Mail Arrive[β](#mail-arrive "Direct link to Mail Arrive")
On-Mail Arrive Sound
This is used to create Mail boxes within the scene; specifically objects which when clicked on will open the players Mail window. It will play an animation when new mail has been received, or the player walks into range and has unread mail. This uses the Legacy Animation Component in Unity3D for it's animations (this likely will be updated to Mecanim soon).
info
This component is itself a legacy component (and may be depreciated and removed in the future), or is likely to get an update in the future.
---
### Meta Balls
#### Overview[β](#overview "Direct link to Overview")
Fields IsoLevel is a threshold value that determines the strength of the field that defines the metaballs.


#### Fields[β](#fields "Direct link to Fields")
###### IsoLevel[β](#isolevel "Direct link to IsoLevel")
is a threshold value that determines the strength of the field that defines the metaballs.
###### Random Seed[β](#random-seed "Direct link to Random Seed")
for metaballs refers to a value that is used to generate random noise that is added to the field that defines the metaballs.
###### Debug Max Tri[β](#debug-max-tri "Direct link to Debug Max Tri")
when the scene is running, this will show the number of triangles the metaball is using.
####
Usage[β](#usage "Direct link to usage")
Create an empty game object and attach a mesh filter and mesh renderer component.
Then search the project for metaball and drag the metaball script from the project to the game object.
( normal add and search does not work with this component)
---
### Modular Buoyancy
#### Overview[β](#overview "Direct link to Overview")
.png>) Fields Density represents the density of the object that is being simulated, which is used to calculate the volume and mass of the object.
![]()
#### Fields[β](#fields "Direct link to Fields")
###### Density[β](#density "Direct link to Density")
represents the density of the object that is being simulated, which is used to calculate the volume and mass of the object. This parameter is important for the buoyancy simulation because it determines how much the object will displace the water around it.
###### SlicesPerAxis[β](#slicesperaxis "Direct link to SlicesPerAxis")
represents the number of slices that the object will be divided into along each of its three axes to create a grid of voxels. This grid is used to simulate the buoyancy of the object by calculating the displacement of the voxels in response to the physics simulation. A higher number of slices will result in a more detailed and accurate simulation, but it will also require more computational resources to run.
###### IsConcave[β](#isconcave "Direct link to IsConcave")
(mesh colliders only) determines whether or not the generated voxels will be allowed to create concave shapes. Concave shapes can complicate the buoyancy simulation and may require more computational resources to simulate accurately. If IsConcave is set to true, the buoyancy simulation will be more accurate but may be slower to compute.
###### VoxelsLimit[β](#voxelslimit "Direct link to VoxelsLimit")
sets a maximum for the number of voxels used in buoyancy simulation. If the number of voxels in the object exceeds this limit, the script will stop generating additional voxels and will instead use the existing voxels to simulate buoyancy. This is done to prevent the simulation from becoming too computationally expensive and to ensure that it runs smoothly in real-time.
In general, adjusting these parameters requires a trade-off between accuracy and performance, and the optimal values will depend on the specific requirements of the buoyancy simulation and the available computational resources.
###### Gravity[β](#gravity "Direct link to Gravity")
defines effective gravity.
---
### Modular Vendors
#### Overview[β](#overview "Direct link to Overview")
We have added some new vendors to our features, and these vendors are called modular vendors.
We have added some new vendors to our features, and these vendors are called modular vendors. Modular vendors are vendors which can be placed in your region, and act like a clickable shop. Other users can click on the object the modular vendor script is attached to, and browse through the items you have on sale. You can have an individual modular vendor, which will only display and sell one item, or you can use a catalogue modular vendor, which will allow you to display and sell items from a specific collection, range or line.
To make things simpler, in our Editor Pack we have two samples of modular vendors: New Basic Catalog and New Basic Single Item Vendor. You can find these samples in the editor pack under Assets>Sample Art>Vendors>Vendors
#### Adding the modular vendor to your region[β](#adding-the-modular-vendor-to-your-region "Direct link to Adding the modular vendor to your region")
To add the modular vendor to your region, you need to add it into the region scene where you want the vendor to be.
For the vendor script to work, you need to attach it to an object in the scene. Make a new 3D object, such as a cube, by right clicking in the hierarchy, and choose 3D Object>Cube. Place the cube where you want it to be in your region.
#### Setting up for the modular vendor[β](#setting-up-for-the-modular-vendor "Direct link to Setting up for the modular vendor")
Right click in your hierarchy, go to UI>Canvas. This canvas will be used in conjunction with a panel for displaying the information about your item/items.
Drag the canvas in the hierarchy into your cube. Under the Inspector window, make sure the Canvas script Render Mode is set to World Space.
In the hierarchy, right click, go to UI>Panel. The panel should automatically be under the cube in the hierarchy. Next, you need to resize the canvas so it fits the cube. To resize it, you can use the Scale tool in the top toolbar. Scale it down until it looks something like this:
After the resizing, you can customize the color of the panel. You can do this by clicking on the Panel in the hierarchy, and going to the Image Script under the Inspector Window.
Now you need to add a few Text scripts and a RawImage script into your heirarchy. Right click in the heirarchy, and choose UI>Text. This will automatically be placed as a child object of the cube. Duplicate this text script by right clicking on it, and duplicate until you have six Text scripts. Rename your Text scripts in the heirarchy by clicking on the Text script, and go to the Object Name box at the top of the Inspector Window.
Rename your texts like this:
* Item Name
* Item Description
* Gold Label
* Gold Price
* Silver Label
* Silver Price
You will also need to add these titles to the actual text script as well by changing the text in the Text Script in the Inspector Window. When you name the Gold Label and Silver Label in the Text Script, name them as Gold Price and Silver Price, as the actual digits of the price need to go under the texts you named as Gold Price and Silver Price in the hierarchy. There will be a screenshot of this later on.
Right click in your heirarchy again and choose UI>RawImage. Drag the RawImage until it is between the Item Description and Gold Label. The RawImage Script will hold the image of the item which is for sale.
#### Positioning the text[β](#positioning-the-text "Direct link to Positioning the text")
You will need to lay out the text on the panel to make sure it is readable and also has space for the rawimage. You can move the boxes around with the normal move tool, but to scale the text box, you will need to use the rect transform tool.
To resize the text, you will need to change the size in the Text script.
Make sure Best Fit is ticked, and set the min to 9, and max to 96. That is the optimal size for the text as it will be readable.
Here is a screenshot of the best layout:
When you are happy with the placement of the text and image, you can move on to attaching the modular vendor script.
To attach the script, click on the cube, click on 'Add Component' under the Inspector window, and search for Modular Vendor.
#### Single Item Vendor[β](#single-item-vendor "Direct link to Single Item Vendor")
To fill this script up, you first need to pick the Vendor Mode. This can either be single or catalog. For this instance, choose 'Single'.
For the product ID, add the product ID of the item you want to sell which is on \[].
Under the UI Fields, you will need to drag the text scripts into the appropriate boxes. So, for the Name box, you will need to drag the Item Name from the hierarchy into the Name box. This is how it should be:
* Name - Item Name
* Description - Item Description
* Brand Name - (You can make a new text script for this and add it in)
* Brand Image - (You can make a new RawImage for this and add it in)
* Item image - The original Raw Image
* Item Icon - Same as Brand Name
For the Gold heading, make sure you have the Display checked.
For the Gold text field, add the Gold Price text from the hierarchy.
Make sure Display Free is set to 'Use world free'.
Set Display Unavailable as 'Use Dash Character'.
Container Game Object you can leave empty.
For the Silver, do the same as above, but drag the Silver Price from the hierarchy into the Silver text field.
Scroll down, and set the Interaction activation mode to Collider Click.
All of the above information, such as item name, description and price will be automatically taken from the virtual good script of the item on curator.
#### Catalog Vendor[β](#catalog-vendor "Direct link to Catalog Vendor")
The catalog vendor works a little differently to the single item vendor. The catalog vendor has categories for you to choose from which will sort the Shop.
You can set the Primary Content type to whatever you need to be, for example, if you make clothing, you can set it to 'Clothes' being primary.
You can also set the catalog to filter items. These are the filters:
* Filter by Brand - This will only show items from a specific brand. If you want to have every item you have created show up in the Shop, this is the one to choose.
* Filter by Creator - This is pretty much the same as above;It will filter the Shop to only show a certain creators items. Note - if you use another creators ID, these items will not show on the preview viewer and you will need to publish the vendor to live to see the content correctly.
* Filter by search term - This will filter the items by search term. For example, if you put in 'Skirt', all skirts in the Shop will show.
* Filter by item IDs - This will filter specific items only using their IDs. You will need to put the number of items you want in the 'Size' box under the checkbox. If you want to add five item IDs, put 5 in the box for example.
Activation mode is how the vendor is activated. This should be set to Collider Click; just make sure the object with the vendor component script on it has a collider.
Now you can upload your region as normal, and these modular vendors will be in your region for users to buy items from.
---
### Move Object
#### Overview[β](#overview "Direct link to Overview")
Fields Location the location the target transform will be moved to.

#### Fields[β](#fields "Direct link to Fields")
###### Location[β](#location "Direct link to Location")
the location the target transform will be moved to.
###### Rotation[β](#rotation "Direct link to Rotation")
the rotation the target transform will be moved to.
###### Target[β](#target "Direct link to Target")
the transform you want to move.
#### Usage[β](#usage "Direct link to Usage")
This component needs to be triggered by another components event, βMoveObject.Fireβ.
For example, the image below uses a proximity activator to trigger the event.
![]()
#### Sample[β](#sample "Direct link to Sample")
Place the sample in the scene and walk into the proximity activator to trigger the move object component.
---
### MusicZone
#### Overview[β](#overview "Direct link to Overview")
*Fields* Name Sets the name of the music zone.

#### *Fields*[β](#fields "Direct link to fields")
###### Name[β](#name "Direct link to Name")
Sets the name of the music zone.
###### Radius[β](#radius "Direct link to Radius")
Set the area of the music zone
###### Clip Size[β](#clip-size "Direct link to Clip Size")
Sets the number of clips
###### Elements[β](#elements "Direct link to Elements")
Drag the audio clips here
info
*This component currently is not working, please use other sound related component instead.*
#### Usage[β](#usage "Direct link to Usage")
Create an empty GameObject and attach MusicZone component to it.
Name Sets the name for music zone.
Radius Set the radius of the zone/sound to be played within.
Clipsize Set the number of clips to be added.
Element Drag the each clip in one of the element field.
| Format | Extensions |
| ----------------------------- | ------------ |
| MPEG layer 3 | .mp3 |
| Ogg Vorbis | .ogg |
| Microsoft Wave | .wav |
| Audio Interchange File Format | .aiff / .aif |
| Ultimate Soundtracker module | .mod |
| Impulse Tracker module | .it |
| Scream Tracker module | .s3m |
| FastTracker 2 module | .xm |
---
### NPCCrowd
#### Overview[β](#overview "Direct link to Overview")
Fields Female Clips Size set the number of custom female animations Elements Drag the animations here Male Clips sets the number of custom Male animations Male ID Sets the number c

#### Fields[β](#fields "Direct link to Fields")
###### Female Clips Size[β](#female-clips-size "Direct link to Female Clips Size")
set the number of custom female animations
###### Elements[β](#elements "Direct link to Elements")
Drag the animations here
###### Male Clips[β](#male-clips "Direct link to Male Clips")
sets the number of custom Male animations
###### Male ID[β](#male-id "Direct link to Male ID")
Sets the number custom male outfit IDs
###### Female ID[β](#female-id "Direct link to Female ID")
sets the number of female outfit IDs
###### Max[β](#max "Direct link to Max")
Max number of NPCs to spawn
####
Usage[β](#usage "Direct link to usage")
Female clips: this sets the number of custom animations you want female NPC to have.
After setting the size drag animation for each in the element field.
Male clips: this sets the number of custom animations you want male NPC to have.
After setting the size drag animation for each in the element field.
Female IDs: this sets the number of custom outfits you want female NPC to have.
After setting the size drag outfit ID for each in the element field.
Male IDs: this sets the number of custom outfits you want Male NPC to have.
After setting the size drag outfit ID for each in the element field.
Player Outfit ID Log in to and click the "Outfit" menu button. Create and save the outfit you want for your NPC. You will see when you save your named outfit that a unique number is added at the end.
MAX: this sets the max number of NPCs to spawn
---
### NPCs
#### Overview[β](#overview "Direct link to Overview")
Non-player characters (NPCs) and other bots can be deployed easily β baked into regions or placed like furniture as spawnable items.
#### Creating an NPC[β](#creating-an-npc "Direct link to Creating an NPC")
Setting up an NPC takes three steps: position it in your scene, give it an appearance with an outfit ID from sine.space, then add interactive functions and submit.
 *Pictured:* Position the NPC in the scene.
 *Pictured:* Grab the outfit ID from sine.space.
 *Pictured:* Add interactive functions and submit.
#### Statue component[β](#statue-component "Direct link to Statue component")
See [Statue Component](/sinespace-sdk/components/statue.md).
---
### Pool
#### Overview[β](#overview "Direct link to Overview")
Field Swim Set the swimming animation Swim Idle Sets the idle animation Splash template sets the small splash effect Big Splash template Sets the splash template for bigger splash

#### Field[β](#field "Direct link to Field")
###### Swim[β](#swim "Direct link to Swim")
Set the swimming animation
###### Swim Idle[β](#swim-idle "Direct link to Swim Idle")
Sets the idle animation
###### Splash template[β](#splash-template "Direct link to Splash template")
sets the small splash effect
###### Big Splash template[β](#big-splash-template "Direct link to Big Splash template")
Sets the splash template for bigger splash
###### Splash Sound[β](#splash-sound "Direct link to Splash Sound")
sets the sound for splash effect
#### Usage[β](#usage "Direct link to Usage")
Add this component to your water, add a box collider to set the area of the water, and check IS Trigger to enabled.
Swim Drag a swimming animation here, this will override avatars default swimming animation.
Swim Idle Changes the idle animation of avatar while he/she is in the area.
Splash template you can drag a splash effect for big and small splashes here.
Splash audio this sets the sound for the splash effect.
---
### Proximity Activator
#### Overview[β](#overview "Direct link to Overview")
Fields Ignore Owner If checked it will ignore owner.

#### Fields[β](#fields "Direct link to Fields")
###### Ignore Owner[β](#ignore-owner "Direct link to Ignore Owner")
If checked it will ignore owner.
###### Client Only[β](#client-only "Direct link to Client Only")
check to set script to client only
###### Minimum Distance[β](#minimum-distance "Direct link to Minimum Distance")
Sets the minimum distance for activation
###### Maximum Distance[β](#maximum-distance "Direct link to Maximum Distance")
Sets the Max distance for activation
###### Event Activate[β](#event-activate "Direct link to Event Activate")
Activates the function when avatar comes within the range.
###### Event Deactivate[β](#event-deactivate "Direct link to Event Deactivate")
Deactivates the function when avatar is out of range.
#### Usage[β](#usage "Direct link to Usage")
This can be used to open/Close doors. Activate deactivate particle effects. Auto light the interior of a house etc.
Trigger Ignore Owner: If checked this script will ignore owner. i.e not will happen if owner is within the rage.
Trigger client only if checked the effect will only trigger on client side. i.e triggered effect won't be shown to all avatars present in the regions. (better performance in certain cases.)
Distance Set the closest and farthest area of activation. Eg: If min is set to 0 and max to 1. it will activate when any avatar is within 1 meter of the object. If min distance is set to 5 and max to 10, it will only activate when avatar is between 5 and 10 meters of the object.
Events Activate Click the add sign then drag the item to be activated when avatar is within the range here. Then select what function should be activated. Eg: Particle system function select start. You can click on add to add multiple items and select function for each.
Events Deactivate Click the add sign then drag the item to be deactivated when avatar is out of the range here. Then select what function should be activated. Eg: Particle system function select start. You can click on add to add multiple items and select function for each.
---
### QuestCounterClickable
#### Overview[β](#overview "Direct link to Overview")
Add the Quest Counter Clickable component to counters the user must click on to collect.
Add the Quest Counter Clickable component to counters the user must click on to collect.

Counter ID
Enter an ID of your own creation to the Counter ID field and add the same ID to the Counter ID field of the Counter quest step or the Startable Timed Counter component.
---
### QuestCounterProximity
#### Overview[β](#overview "Direct link to Overview")
dd the Quest Counter Proximity component to counters the user must be within a certain proximity of in order to collect.
dd the Quest Counter Proximity component to counters the user must be within a certain proximity of in order to collect.

Counter ID
Enter an ID of your own creation to the Counter ID field and add the same ID to the Counter ID field of the Counter quest step or the Startable Timed Counter component.
Trigger Distance
Specify the distance from the object that will trigger a successful collection.
---
### QuestGameObject
#### Overview[β](#overview "Direct link to Overview")
This allows you to rez and and derez items in your scene during specified quest steps.
This allows you to rez and and derez items in your scene during specified quest steps.

Configurable parameters:
* QuestID
* MinStep
* MaxStep
Attach to other objects (preferably a parent group, if you're updating multiple in a single step)
It enables or disables the object it is on, based on whether the user is inclusively on any step between Min and Max.
Objects can only be seen by the player.
---
### QuestNPC
#### Overview[β](#overview "Direct link to Overview")
To turn any object in your scene into the Quest NPC, add the Quest NPC component to it.
To turn any object in your scene into the Quest NPC, add the Quest NPC component to it. (You might normally make the Quest NPC a humanoid NPC, with the Statue component on it, rendering it as a character, but you can add the Quest NPC component to anything with a collider on it that the user can click to start the quest.)

Once you have added the quest NPC component to an object in your scene, drag that object into the Destination NPC field in the first step of your quest.
Now when a user clicks that object it will allow them to start your quest.
---
### SailStrip
#### Overview[β](#overview "Direct link to Overview")
Fields Resolution sets the resolution Points Size Sets the size Gravity sets the gravity amount Curvature Sets the curvature Need Update sets update to ??

#### Fields[β](#fields "Direct link to Fields")
###### Resolution[β](#resolution "Direct link to Resolution")
sets the resolution
###### Points Size[β](#points-size "Direct link to Points Size")
Sets the size
###### Gravity[β](#gravity "Direct link to Gravity")
sets the gravity amount
###### Curvature[β](#curvature "Direct link to Curvature")
Sets the curvature
###### Need Update[β](#need-update "Direct link to Need Update")
sets update to ??
###### Always update[β](#always-update "Direct link to Always update")
Sets to update all time
Attach this component fill ?
---
### SceneBackgroundMusic
#### Overview[β](#overview "Direct link to Overview")
Fields Server URL of the shout cast server Port port of the shoutcast Playing Check this to stream music.

#### Fields[β](#fields "Direct link to Fields")
###### Server[β](#server "Direct link to Server")
URL of the shout cast server
###### Port[β](#port "Direct link to Port")
port of the shoutcast
###### Playing[β](#playing "Direct link to Playing")
Check this to stream music.
#####
##### Using an audio file that is in your Project Assets[β](#using-an-audio-file-that-is-in-your-project-assets "Direct link to Using an audio file that is in your Project Assets")
Create an empty object in your scene that will be used for your region.
Under the Inspector window, click on Add Component and add an Audio Source.
Add in a suitable audio clip from your Project assets.
Select the output as "Music" (if its left as "None" it may play but at a reduced volume level).
If you want the audio clip to repeat, tick "Loop".
##### Using audio from Shoutcast[β](#using-audio-from-shoutcast "Direct link to Using audio from Shoutcast")
You can also stream music from Shoutcast into your region.
Create an empty object in your scene that will go in your region. Under the Inspector window, click on Add Component. Search in the search bar for Shoutcast Streaming and click on it.
Add in the server and port from Shoutcast and check the box playing to have the music playing in your region after uploading.
---
### Simple Networking
#### Overview[β](#overview "Direct link to Overview")
Fields Network Name Networks that share a name will communicate with each other.

#### Fields[β](#fields "Direct link to Fields")
Network Name Networks that share a name will communicate with each other. Minimum of 20 characters network name. You should make this something unique unless you want cross/talk to happen.
A common networking name is to use a DNS format, such as space.sine.mycoolwidget where you have a unique prefix just for you, followed by an application name.
Loopback Does this networking component react to events it sends.
Instanced If enabled, appends this objectβs global unique ID to the network name, so that multiple copies of the same object will not cross-talk on the network.
Events A list of events you want this component to react to when sent over the network.
---
### Simple State Machine
#### Overview[β](#overview "Direct link to Overview")
Fields Component Name See networking. Bindings Auto Bind To UI If enabled, state machine will automatically attach to Toggles, Buttons,Sliders, and Dropdowns on the same object at runtime.

#### Fields[β](#fields "Direct link to Fields")
###### Component Name See networking.[β](#component-name-see-networking "Direct link to Component Name See networking.")
###### Bindings[β](#bindings "Direct link to Bindings")
Auto Bind To UI If enabled, state machine will automatically attach to Toggles, Buttons,Sliders, and Dropdowns on the same object at runtime.
If you have a slider with a range of like 1 to 10, you can create 10 states called 1, 2, 3, 4, etc and it'll switch between them automatically as you move the slider around.
You can skip numbers too.
If you have 1, 3, 7, 10, then basically 1,2 will use the '1' state, 3,4,5,6 will use the '3' state, 7,8,9 will use the '7' state, and 10 will be itself.
If there's no exact state match, and you are in between numbers, it rounds down to the nearest available state.
You can also call StateMachine.BindUI(object) to bind it to UI elements on some other object, 'auto bind' only works if there's something on the same object.
###### Networking[β](#networking "Direct link to Networking")
NetworkedState If enabled, state machine will network its state to all other users in the scene persistently that have the same component name.
NetworkedUnique If enabled, state machines on different objects will not work together even if they have the same component name.
###### State Settings[β](#state-settings "Direct link to State Settings")
Start State 0 or 1 will be the first state in the list as default. States are 1-based, so 1 is the first state in the list.
Wrap States When reaching the last state, does it wrap back around to first state again (and vice versa).
Exit State On Start Automatically run the Exit Event on all states except the start state when component starts.
Redo States If told to switch to the state it is already in, redo the events anyway.
###### State Events[β](#state-events "Direct link to State Events")
StateChangeEvent Event that happens every time the state changes, no matter what state it is coming to or from.
Machine States A simple state machine typically consists of a set of states, events that trigger state transitions, and actions that are performed upon entering or leaving a state.
---
### SliderVehicle
#### Overview[β](#overview "Direct link to Overview")
Using this component(with Slider Physics), you can create a silder-type vehicle(for example, a sledge).
Using this component(with Slider Physics), you can create a silder-type vehicle(for example, a sledge).
The core parts is same as the Module vehicle so you can check [here](/sinespace-sdk/vehicles.md) for thouse value settings.
The slider physics decide how the vehicle moves exactly.
---
### Speedometer
#### Overview[β](#overview "Direct link to Overview")
Fields **Rigid Body** The rigid body of the vehicle.

#### Fields[β](#fields "Direct link to Fields")
**Rigid Body** The rigid body of the vehicle.
**Meter** The UI text element.
**Use Imperial Units** What it says.
**Animator** Use a custom animator( for example an animation moving a speed dials arm)
**Animator Float Variable Name** A float variable will be fed in, in meters per second.
#### Usage[β](#usage "Direct link to Usage")
create a UI Text Component under your vehicle object, and another empty game object with this speedometer component.
Attach the rigidbody of the vehicle and the UI Text component to the slots of the speedometer, you can leave the rest option as it was, or fill it on your own request. Change the position and style of the UI Text as a normal UI element as you wish. And, remember, disabled the Canvas object at the beginning, and activate it by the events function as I present above.
A simple example here, is a meter with blue text in the right-bottom corner:

---
### StartableClothingRequirement
#### Overview[β](#overview "Direct link to Overview")
This requires the user to wear a specific clothing item.
This requires the user to wear a specific clothing item.

Clothing Item ID1/ID2
Allows you to specify for instance one male and one female item.
You can identify the ID of a clothing item from the virtual goods component attached to the gesture once it has been submitted, or from the item list in your account at curator.sine.space
---
### StartableGestureRequirement
#### Overview[β](#overview "Direct link to Overview")
This will require the user to play a specific gesture before the quest moves on.
This will require the user to play a specific gesture before the quest moves on.

ItemID
The item ID for a specific gesture you need played for it to succeed. You can get this from the virtual goods component attached to the gesture once it has been submitted, or from the item list in your account at curator.sine.space
Any
Tick this if you want playing any gesture to complete the quest step.
Min Participants
Defines the minimum number of gesture participants required to complete the step. So, for instance, you can set to 2 and tick Any to require the user to do any two person gesture with another user.
---
### StartableItemRequirement
#### Overview[β](#overview "Direct link to Overview")
This requires the user to have a specific item in their inventory before the quest continues.
This requires the user to have a specific item in their inventory before the quest continues.
They do not need to use the item; they just need to have it in their inventory.

Item ID
Put the ID of the item here. You can identify the ID from the virtual goods component attached to the gesture once it has been submitted, or from the item list in your account at curator.sine.space
---
### StartableRoomVisit
#### Overview[β](#overview "Direct link to Overview")
This requires the user to visit a specific region for the quest to continue.
This requires the user to visit a specific region for the quest to continue.

Background ID
Put the region ID in this field to specify where the user needs to go.
---
### StartableSitRequirement
#### Overview[β](#overview "Direct link to Overview")
This requires the user to sit on a specific furniture item.
This requires the user to sit on a specific furniture item.

Target Object
Add the SeatImproved component to any game object in your scene and then drag that game object into the Target Object field. Remember this item can also be animated so you could for instance use this step to fly someone from one part of your region to another.
The step will complete as soon as the user sits so you may want to make the next step not initiate automatically but require the user to click another Quest NPC object to continue, if sitting initiates a sequence that you want to play out before the next step launches.
---
### StartableSnapshot
#### Overview[β](#overview "Direct link to Overview")
This requires the user to take a snapshot with the in world snapshot feature.
This requires the user to take a snapshot with the in world snapshot feature.

Number of Snapshots
You can specify the number of snapshots the user needs to take in order to complete the step.
---
### StartableTeleport
#### Overview[β](#overview "Direct link to Overview")
This step will teleport the user to a specific location in the same region as the quest.
This step will teleport the user to a specific location in the same region as the quest.

Target
Drag any game object in your scene into the target field to teleport the user to that location.
To ensure they do not arrive on top of a tree or similar, it usually makes sense to create an empty game object exactly where you want them to arrive.
Delay
Allows you to add a time delay before the teleportation. A small delay (1 second) is recommended to ensure all actions as part of the prior step have time to complete. A longer delay might for instance be used in conjunction with a specific gesture playing in the prior step.
---
### StartableTimedCounter
#### Overview[β](#overview "Direct link to Overview")
Startable Timed Counter is a game component you can add to your quest, requiring the user to collect a number of counters inside a specified time frame.
Startable Timed Counter is a game component you can add to your quest, requiring the user to collect a number of counters inside a specified time frame.
Use this startable in conjunction with objects in the scene that have either the Quest Counter Clickable or Quest Counter Proximity component attached.

Number required
Specify the number of counters the user needs to collect. This can match the total number available in the scene or there can be far more in the scene than the required number, depending on the nature of your game.
Seconds Limited
Define the duration of the round. If the user fails they can reclick the NPC to restart the step.
Counter ID
Add whatever ID you have manually applied to the Counter ID field of the Quest Counter Clickable or Quest Counter Proximity component attached to your counters.
---
### Statue
#### Overview[β](#overview "Direct link to Overview")
Fields Gender set the gender of the NPC Name Set the name of the NPC Player outfit ID Sets the outfit of the NPC Material Sets the material of NPC skin and outfit Skip material Cha

#### Fields[β](#fields "Direct link to Fields")
###### Gender[β](#gender "Direct link to Gender")
set the gender of the NPC
###### Name[β](#name "Direct link to Name")
Set the name of the NPC
###### Player outfit ID[β](#player-outfit-id "Direct link to Player outfit ID")
Sets the outfit of the NPC
###### Material[β](#material "Direct link to Material")
Sets the material of NPC skin and outfit
###### Skip material Change ID[β](#skip-material-change-id "Direct link to Skip material Change ID")
Skips material change for outfit if set to 1
###### Scale[β](#scale "Direct link to Scale")
Sets the scale of the NPC
###### Disable shadows[β](#disable-shadows "Direct link to Disable shadows")
Toggles shadows on/off
###### Cull Distance[β](#cull-distance "Direct link to Cull Distance")
Sets the culling distance
###### Do NOT Cull[β](#do-not-cull "Direct link to Do NOT Cull")
Disables culling
###### Animation[β](#animation "Direct link to Animation")
Select the animation NPC should Play
###### Random Position[β](#random-position "Direct link to Random Position")
Sets random start position for the animation
#### Usage[β](#usage "Direct link to Usage")
The Statue component is most commonly used for creating [NPCs](/sinespace-sdk/components/npcs.md) within a scene, it allows you to dress your NPC using any clothing or accessory you can own inworld; both your own virtual goods and any item you buy or are given by another creator.
Apply the script to an empty capule collider in your scene, or use the NPC template prefab in your Space Editor Pack.
Name NPCs are easily distinguished from real avatars inworld because they do not have hover text showing their names over their heads. However, you can still give your NPC a name in this field, that will appear in quest dialogue steps.
Player Outfit ID For more information how to get the player outfit ID, please see [Outfit IDs](/sinespace-viewer/outfits/outfit-ids.md)
Enter just this number in the Player Outfit ID field.
Rendering settings
If you want to apply a material on top of the NPC you can add it here.
You can make your NPCs look like holograms or stone statues etc.
If you want store mannequins that show of a specific item, add the store ID of that item to the "Skip Material Change ID" field.
This will allow you, for instance, to create a silver mannueqin with just the sunglasses you are selling retaining their original materials.
You can get the item ID from the virtual good component attached to it; the ID will appear as soon as the item is submitted.
Scale
You can enlarge your NPC to the status of a giant towering over the scene or shrink it to a sprite. *Statues (and avatars in general) will not respect Unity embedded scales on the Transform. This is to prevent them from being scaled when you have them seated on an object which is not 1,1,1.*
Disable shadows / Culling distance
You can use the NPC system to deploy crowd scenes; where disabling shadows and optimising draw distance on each NPC will improve performance.
Custom animation
By default your NPC will use the standard Space idle animations.
You can override this here by adding your own animations. See here for details on importing and rigging animations for Space avatars; [Single Person Animation](/sinespace-sdk/avatars/gestures/single-person-animation.md)
Random animation position
Tick this and the animation will launch at a random point in it's timeline. As above this is useful for any kind of crowd scene where you do not want multiple NPCs doing identical moves in sync on the screen.
---
### StreamingBackgroundMusic
#### Overview[β](#overview "Direct link to Overview")
*Fields* Url's Size No of songs Element Enter URL for each song.

#### *Fields*[β](#fields "Direct link to fields")
###### Url's Size[β](#urls-size "Direct link to Url's Size")
No of songs
###### Element[β](#element "Direct link to Element")
Enter URL for each song.
###### Shuffle Loading[β](#shuffle-loading "Direct link to Shuffle Loading")
Check to randomize the list.
info
*This component currently is not working, please use other sound related component instead.*
This allows you to stream music in your region from URLs.
Create an empty object in your scene which will be in your region.
Click on the object in the hierarchy and then click on Add Component under the Inspector window. Search for Streaming Background Music.
This will add the component to your object. You will see the component has settings called URLS and Shuffle loading.
If you click on the drop down arrow next to URLS, you will see it has a Size option. If you have 3 URLs of songs you want to add to you region, you would enter the number 3 in this size option, press Enter, and three element boxes will appear. You then add the URLs into these boxes. If you have ten, you would add the number 10 and so on.
Shuffle loading unchecked will play the songs in the order you have added the URLs in the URLs settings, and checking it will shuffle the tracks.
---
### SubstituteAnimationZone
#### Overview[β](#overview "Direct link to Overview")
Fields Walk Male Overrides walk animation for male Walk Female Overrides the walk animation for female Run Male Overrides run animation for male Run Female Overrides the run animat

#### Fields[β](#fields "Direct link to Fields")
###### Walk Male[β](#walk-male "Direct link to Walk Male")
Overrides walk animation for male
###### Walk Female[β](#walk-female "Direct link to Walk Female")
Overrides the walk animation for female
###### Run Male[β](#run-male "Direct link to Run Male")
Overrides run animation for male
###### Run Female[β](#run-female "Direct link to Run Female")
Overrides the run animation for female
###### Idle[β](#idle "Direct link to Idle")
Overrides the idle animation
#### Usage[β](#usage "Direct link to Usage")
Create an empty object, add component search and add Substitute animation Zone.
Add a box Collider to define the area of the zone; check is trigger on the collider.
Drag animations you want to override in this zone into substitute Animation Zone script fields.
---
### SyncedPhysicsDoodad
#### Overview[β](#overview "Direct link to Overview")
Fields Unique Name Gives Unique name to the item Usagto e Attach this component to share the updates with the server.

#### Fields[β](#fields "Direct link to Fields")
###### Unique Name[β](#unique-name "Direct link to Unique Name")
Gives Unique name to the item
#### Usagto e[β](#usagto-e "Direct link to Usagto e")
Attach this component to share the updates with the server.
This will mirror to all client, and the object will appear synced.
For example, if you attach this component to a beach ball with rigid body enabled, everyone in the region will see the ball movement same time.
---
### TeleportLocal
#### Overview[β](#overview "Direct link to Overview")
Fields Destination Drag the destination object here Teleport Local allows you to set up a teleport from one point within your region to another in your region.

#### Fields[β](#fields "Direct link to Fields")
###### Destination[β](#destination "Direct link to Destination")
Drag the destination object here
Teleport Local allows you to set up a teleport from one point within your region to another in your region.
#### Usage[β](#usage "Direct link to Usage")
Add an object into your hierarchy to be the starting point for your teleport system. Click on this object in the hierarchy, and click on Add Component. Search for Local Region Teleport in the search bar and click on it to add it to the object.
No need for collider nor trigger : the avatar need to reach the object's "Transform coordinate" to self-activate the teleportation process.
Add another object into your hierarchy to be the end point of your teleport system. Drag this item from your hierarchy into the Destination box under the Teleport Local component.
When you upload your region, the teleport objects will allow you to travel from where you have placed the first teleport to a spot in your region where you have placed the second teleport.
---
### TeleportPad
#### Overview[β](#overview "Direct link to Overview")
Fields Name Location Name Teleport FX FX Instance GameObject Usage Use this component to link large scenes together, allowing the user to access popular locations easily.

#### Fields[β](#fields "Direct link to Fields")
###### Name[β](#name "Direct link to Name")
Location Name
###### Teleport FX[β](#teleport-fx "Direct link to Teleport FX")
FX Instance GameObject
#### Usage[β](#usage "Direct link to Usage")
Use this component to link large scenes together, allowing the user to access popular locations easily.
The object this component is attached to needs another collider to detect avatar stepping on it/colliding. To do so add component - Box/capsule collider and set the collider to is trigger. If the collider is not set to is trigger it will not let avatar pass through it.
Teleport FX should be a timed particle effect or other object which is instantiated when the user arrives at this pad; at the pads location.
---
### TeleportWorld
#### Overview[β](#overview "Direct link to Overview")
Field Custom Destination Name Name of the destination(This doesn't have to be the regions name) Custom Destination Background ID ID of the destination Region (Must match an existin

#### Field[β](#field "Direct link to Field")
###### Custom Destination Name[β](#custom-destination-name "Direct link to Custom Destination Name")
Name of the destination(This doesn't have to be the regions name)
###### Custom Destination Background ID[β](#custom-destination-background-id "Direct link to Custom Destination Background ID")
ID of the destination Region (Must match an existing region id)Usage
#### Usage[β](#usage "Direct link to Usage")
Create a portal or an object which you would like to act as world teleport. Add component, search and select "Inter-Region Teleport (TeleportWorld)".
No need for collider nor trigger : the avatar need to reach the object's "Transform coordinate" to self-activate the teleportation process.
Once added, set a Name for destination region. Then click on destination background ID and add your region background ID.
Region background id is show in the Scene setting when you upload a region it is right bellow region URL.
You may also find the *Region background id* on your *Curator page* then *Items* list.
---
### Timer
#### Overview[β](#overview "Direct link to Overview")
Usage Fill the Target time in seconds if you want the timer to stop by certain time.

info
*This is a new component and may not included in the current Editor pack. It would add in the builds later(after Feb 14, 2019)*
#### Usage[β](#usage "Direct link to Usage")
Fill the Target time in seconds if you want the timer to stop by certain time. It is necessary if you choose "count down" type.
Now there are 3 format: HHMMSS is stand for hours:minutes:seconds, MMSS means minutes:seconds, and the last is only display seconds.
If you need to display the fraction after seconds, pick "Show fraction" option.
You can add Events here, and trigger them when:
1\. Pick the option "Call Event When Timer End", the events will be fired when the timer reaches the Target time(or decrease to 0 from the Target time if count down);
2\. Fire the events once in a delay after the timer start if the value here is above zero;
3\. Fire the events every certain time by the value set if it is above zero;
All these method can be used together, which means you can trigger the event after a short while for the first time, then repeat it periodically, and trigger it last time when the timer reaches the preset end.
The component offer a default output method, so you can directly drag a game object with Text Component into the slot, the timer will display in that Text Label. But if you want to construct your own way for output, call the function OutputByFormat(), which returns the string of current value of timer.
To start/pause the timer by event, change the bool value of timeRunning, where true start the timer and false pause it.
To stop and reset the timer, call the function of ResetTimer(), it will set the timer back to the initial state you set.
---
### Tip Jars
#### Overview[β](#overview "Direct link to Overview")
Usage Add the component "Charity(Tip jar)" to the object you want to create as a tip jar.\ Then you can add room furniture and virtual good component to make it as a furniture, or
#### Usage[β](#usage "Direct link to Usage")
Add the component "Charity(Tip jar)" to the object you want to create as a tip jar.
Then you can add room furniture and virtual good component to make it as a furniture, or simply add virtual good component and choose generic type to make it a spawnable object.
The tip jar component is already contained other function necessary like clickable, so normally you don't need to add other components.
Just like the image below is enough:

---
### UpgradeAccountNPC
#### Overview[β](#overview "Direct link to Overview")
Usage To add this component, simply choose an object you want as an NPC.

#### Usage[β](#usage "Direct link to Usage")
To add this component, simply choose an object you want as an NPC. This can be an object or an avatar NPC that will be included in your region.
Choose the item in your hierarchy. Under the Inspector Window, click on Add Component. Search for UpgradeAccountNPCBaseInternal in the search bar and click on it to apply it to your object.
This will add the component script to your NPC/object to allow you to click on it in world once you have uploaded the region.
---
### Vehicle Physical Animator
#### Overview[β](#overview "Direct link to Overview")
.png>) Fields Animator The animator of the mesh (e.i.
![]()
#### Fields[β](#fields "Direct link to Fields")
Animator The animator of the mesh (e.i. An animated horse ).
Vehicle The object containing the vehicle script.
Rigid Body The vehicle's rigid body.
---
### Vehicle Respawn
#### Overview[β](#overview "Direct link to Overview")
.png>) Usage VehicleTemplateArray can spawn some random cars(need test!).
![]()
#### Usage[β](#usage "Direct link to Usage")
VehicleTemplateArray can spawn some random cars(need test!).
If you want to spawn a specfied car, fill its item ID(get it from the Crutor page) in Unique ID slot.
You can also add some sound effect for denied noise and spawn noise.
---
### Vendors for your business region
#### Overview[β](#overview "Direct link to Overview")
Having vendors in your region will make it easier for users to shop for your items.
Having vendors in your region will make it easier for users to shop for your items.
There are different varieties of vendors to use in Sinespace. You can have a vendor which only shows specific items or have a vendor which shows a range of items like a catalog.
#### Creating NPC Vendors[β](#creating-npc-vendors "Direct link to Creating NPC Vendors")
If you want to place a NPC in your region as a vendor, you can do this as well. You will need to create an empty object in Unity by right clicking in the hierarchy and choose 'Create Object'. Add the Statue component to this. Alternatively, you can customize the sample NPC found in the Editor Pack. The NPC sample is under Assets>Sample Art>NPC.
Once you have the NPC in Unity, you can see how to set the NPC up on the [NPC statue](/sinespace-sdk/components/statue.md) page.
Once you have added done this, in the Inspector window, click on 'Add Component' and search for 'Modular Vendor'. Add this to your NPC.
---
### VIPCollider
#### Overview[β](#overview "Direct link to Overview")
Fields Invert Invert behaviour - block VIP users instead Usage This component when attached to a collider, will disable the collider if the user is a VIP user (or the opposite if 'Invert' is checked).

#### Fields[β](#fields "Direct link to Fields")
###### Invert[β](#invert "Direct link to Invert")
Invert behaviour - block VIP users instead
#### Usage[β](#usage "Direct link to Usage")
This component when attached to a collider, will disable the collider if the user is a VIP user (or the opposite if 'Invert' is checked). A VIP user is defined as one who has bought real currency (i.e. Gold) within the last several weeks (the status fades over time).
---
### Virtual Goods
#### Overview[β](#overview "Direct link to Overview")
The Virtual Goods component is added to any item you upload, whether it is for sale in the shop or for your own use, including content used in your regions.
The Virtual Goods component is added to any item you upload, whether it is for sale in the shop or for your own use, including content used in your regions.
The component is divided into tabs so you can fill in the required information more easily.
#### Basic[β](#basic "Direct link to Basic")
Use the Basic tab to set the content type, category, audience rating, and customization options.
**Content Type** is where you choose the broad content category. For example, choose `Clothing` when uploading an item of clothing.
**Category** places the item in the correct shop category. For example, if the content type is `Clothing` and the item is a jacket, choose `Clothes > Tops > Jackets`.
**Audience Rating** lets you choose the rating for the item. The available ratings are `Everyone`, `Teen`, `Mature`, `Adult`, and `Explicit`. This section also includes checkboxes for content such as violence or adult content.
**Customization Capabilities** controls how much in-world customization is allowed for the item. Options include basic, disallowed, full, and source access. The editor shows a short explanation when you choose an option.
note
The `Pet` type is currently locked and is no longer used. To create a following minion-style pet, choose `Generic` to set it as a spawnable item, then use the pet category if you want to place it in the shop.
#### Detail[β](#detail "Direct link to Detail")

Use the Detail tab to add the primary description, optional fields, and translated descriptions.
**Primary Description** is where you add the item name and description. Include any special instructions, graphics requirements, file size notes, or other important details.
Add your brand name here as well.
**Optional Fields** are not yet shown in the shop. This is an upcoming feature.
**Translated Descriptions** lets you add translations for the item name, description, instructions, and release notes. Click **Add New Translation**, choose a language from the drop-down, and enter the translation. You can add multiple translations.
#### Pricing[β](#pricing "Direct link to Pricing")

Use the Pricing tab to set the item price and promotion limits.
Enable **Not for Sale** if you want to upload an item for personal inventory use without listing it in the shop.
**Price Gold** sets the item price in Gold, the premium currency. To sell an item for Gold only, enter `-1` in the Silver field and enter the Gold price.
**Price Silver** sets the item price in Silver, the base Sinespace currency.
**Promotions** controls whether the item can be used in seasonal or promotional sales. Enable **Allow use in Promotions** to make the item eligible, then set the maximum discount from 0 to 100 percent.
#### Icons[β](#icons "Direct link to Icons")

Use the Icons tab to add the item store icon, inventory icon, and brand icon.
**Image Store Icon** is used for the item in the Sinespace shop. You can create it outside Unity and add it to the Project window, or click **Take Screenshots** to auto-generate it. This also auto-generates the inventory icon. It may take a little time for the generated images to appear.
The **Brand Icon** is the image used for your brand. You can copy it from Upload Settings in Unity.
To add brand information to Upload Settings, click **Space > Upload Settings** in Unity. Under Defaults, add the brand name, brand icon, copyright label, and default inventory icon.
After those defaults are set, return to the Icons tab on your item prefab and click **Copy** under Brand Icon to copy the brand information from Upload Settings.
You can also add the brand icon manually by importing the image into the Project window and dragging it into the Brand Icon field. The brand image must be a `140x60` PNG.
You can add extra preview images for the shop by expanding **Extra Preview Images** and adding images. Preview images should be `1024x1024`.
#### Copyright[β](#copyright "Direct link to Copyright")
Use the Copyright section to enter the developer name and copyright information.
The developer name can be your business name or your individual name. For the copyright, add your name or business name after the copyright year.
You can also add copyright information in Upload Settings so it can be copied to other components.
#### Upload[β](#upload "Direct link to Upload")

Use the Upload tab to add upload information for the item.
**Status** shows whether you have already uploaded the item to Curator.
**Resume Existing Item** lets you enter a resume ID when re-uploading an item. This overwrites the old version. You can find an item's resume ID on `curator.sine.space`, or in Unity under **Space > Items and Status**.
**Grid** lets you enter a grid ID to restrict the item to a specific grid.
**Upload Content** includes an automatic submission option. This submits the item for upload to Sinespace.
After the item is on Curator, the Sinespace team reviews it. If it passes review, the item goes live in Sinespace.
---
### VoiceZone
#### Overview[β](#overview "Direct link to Overview")
Usage Create an empty object and add voiceZone component to it.

#### Usage[β](#usage "Direct link to Usage")
Create an empty object and add voiceZone component to it.
Add a box collider, click on edit constrains to scale the collider to desired area and check is trigger.
The voice will get enabled for the avatars entering this area.
Note: This component Only works on desktop client.
---
### Volumetric Light
#### Overview[β](#overview "Direct link to Overview")
Features Volumetric fog effect for multiple lights.

#### Features[β](#features "Direct link to Features")
Volumetric fog effect for multiple lights. Point, spot and directional lights are fully supported.
Volumetric shadows
Volumetric light cookies
Volumetric noise implemented as animated 3D texture.
#### Fields[β](#fields "Direct link to Fields")
Sample count - number of raymarching samples (trade quality for performance)
Scattering Coef - scattering coefficient controls amount of light that is reflected towards camera. Makes the effect stronger.
Extinction Coef - controls amount of light absorbed or out-scattered with distance. Makes the effect weaker with increasing distance. It also attenuates existing scene color when used with directional lights.
Skybox Extinction Coef - Only affects directional light. It controls how much skybox is affected by Extinction coefficient. This technique ignores small air particles and decreasing particle density with altitude. That often makes skybox too "foggy". Skybox extinction coefficient can help with it.
MieG - controls mie scattering (controls how light is reflected with respect to light's direction)
Height Fog - toggle exponential height fog
Height Fog Scale - scale height fog
Noise - enable volumetric noise
---
### WanderingNPC
#### Overview[β](#overview "Direct link to Overview")
Fields Start Position set the custom starting position of the NPC Target Position Sets the target positon of the NPC Wander sets the NPC to wander in random direction Max Wander Di

#### Fields[β](#fields "Direct link to Fields")
###### Start Position[β](#start-position "Direct link to Start Position")
set the custom starting position of the NPC
###### Target Position[β](#target-position "Direct link to Target Position")
Sets the target positon of the NPC
###### Wander[β](#wander "Direct link to Wander")
sets the NPC to wander in random direction
###### Max Wander Distance[β](#max-wander-distance "Direct link to Max Wander Distance")
Sets the maximum wandering distance
###### Rotation SpeedRotation Speed[β](#rotation-speedrotation-speed "Direct link to Rotation SpeedRotation Speed")
sets the rotation speed of the NPC
###### Move Speed[β](#move-speed "Direct link to Move Speed")
Sets the movement speed of the NPC
#### Usage[β](#usage "Direct link to Usage")
Refer [Statue](/sinespace-sdk/components/statue.md) to see how to create NPC, once created attach wandering NPCs component to move them from one location to another.
Start and Target position: Use this to set NPC to move to a custom location.
Wander: Check this to set the NPC to a wander randomly on are set by max distance.
Move Speed sets the movement speed of the NPC.
---
### Creating A Shop
#### Overview[β](#overview "Direct link to Overview")
Mirage Scene Download \* Mirage This page is based on the Mirage shop template which you can download and modify yourself (see right).

Mirage Scene Download
* [Mirage](http://space-files.s3.amazonaws.com/sample-art/Mirage-Region.unitypackage)
This page is based on the Mirage shop template which you can download and modify yourself (see right).
We will cover;
##### Creating a shop[β](#creating-a-shop "Direct link to Creating a shop")
The Mirage region is built without using any 3D modelling or mesh creation tools at all. Everything in the region has been created with Unity or Photoshop. The base region is approximately 25 mb download for users.
Scene set up - interior or exterior scene?
The Mirage shop template region is just a skybox. There is no need to create a full environment around this template.

The building - using simple tools
The walls and floors and all the interior props were built using basic primitive shapes in Unity. These can be added to your scene, sized and positioned using the Unity editor's standard gizmos. Once a building has been created, you can add materials to your objects, to combine textures and shaders and create detailed and attractive spaces. You can also choose to use ProBuilder a free Unity asset to build basic or advanced geometry, right in Unity, with zero creative barriers.

A 3D logo - text extrusion with Blender of Photoshop
The logo above the door was extruded from text using Photoshop and saved as an fbx file. You can also use Blender to do this.
* [Materials And Shaders](https://docs.unity3d.com/Manual/Shaders.html)
* [Asset Store](https://www.assetstore.unity3d.com/)
Materials - combining textures with shaders
Unity offers a huge array of options for physical materials. You can buy cool materials and shaders in the Unity Asset Store; you can even create your own. Just the Standard Shader which will automatically be applied to any new material you create provides you with enormous power when it comes to creating the look and feel of your space. This region has two different wooden floors and concrete walls. It also has glass panels, plastic fittings and some leather stools, all created using the Unity standard shader.

Mirrors - a camera and a render material
The region also has two mirrors, one in the entrance hall and one in the main store room.
Details on how to create a mirror:
1. \- In your hierarchy, right click and select 3D Object and plane to create a new plane in your scene view. Then position your plane to face where you want it to be.
2. \- Right click in your project and make a Render Texture.
3. \- In your hierarchy, right click on the plane you just made and add a camera.
4. \- In your inspector, remove the audio listener by right clicking over that module and selecting Remove Component.
5. \- Rotate your camera to face out from the front of the mirror plane.
6. \- Drag the render texture into the Target Texture block of your mirror's camera.
7. \- Drag that same Render Texture you made into the plane you made in hierarchy.
8. \- Set scale on the plane x value to -1
9. \- Switch the shader on the Plan you made to Self-Illumin/Transparent/Diffuse(HDR)
10. \- Set the shader's Emission Gain to 0.1
11. \- Click on the white in the Main Color area at the top of the shader and adjust the A (alpha) slider towards the bottom to adjust the transparency if needed for use in something like a window
It is worth noting that mirrors like these have almost no performance impact; Big mirrors like these will not cause lag in your regions.

Lighting - using different light types
The lighting in this scene is described in more detail in our [Lighting an Interior](/sinespace-sdk/regions/lighting-an-interior.md).
The different types of lights in this scene are;
* Ambient light
* Area lights
* Point lights
* Emissive surfaces

Baking - using realtime and baked lights
Once all the lights and reflection probes are laid out, if you are baking anything (instead of using realtime lighting for everything)
Baked lights have their impact on textures and light probes applied during a one click bake process in Unity before you upload your region. The actual light source is then not used inworld. This improves inworld performance; your frame rate will be higher; but it increases the size of the download by creating lightmaps; large textures that blend with the scene textures to deliver the impact of the original light source.
Realtime lights are physical lights operating in your scene. They can cast live shadows on moving objects in your scene. Lots of lights may have an impact on performance but they reduce the size of the region when it is downloaded by your visitors.
* [Reflection Probes](https://docs.unity3d.com/Manual/ReflectionProbes.html)
Reflection probes - bringing shiny surfaces to life
Reflection probes influence all the static and moving shiny surfaces in the scene.
That includes the glass shelves and metal lights in this scene, and any metallic or shiny surfaces worn by visitors.
Once laid out reflections probes can be baked into the scene like light probes.

Sliding doors - animating objects without scripting
* [Animated Doors](/sinespace-sdk/creating-items/making-animated-doors.md)
space creators can easily keyframe animate a huge variety of attributes of inworld objects; not just position and rotation but colour, light intensity, etc.
In this scene the doors have been designed to open and close in response to a proximity trigger. No scripting is needed to build interactive components like this.
##### Vending machines[β](#vending-machines "Direct link to Vending machines")
* [Inventory Vendor](/curator-dashboard/items/inventoryvendor.md)
* [Catalog Vendor](/sinespace-sdk/components/catalog-vendor.md)
* [Animated Vendor](/sinespace-sdk/components/animation-vendor.md)
The Mirage demo scene contains two types of vending machine;
* Catalogue β displays all virtual goods with a specific brand name that you define
* Preview β Displays a specific product in preview window

NPCs - creating mannequins without scripting
* [Statue Component](/sinespace-sdk/components/statue.md)
The Mirage demo scene contains three NPCs, each dressed wearing a skin that is also on sale in the store.

##### Virtual goods[β](#virtual-goods "Direct link to Virtual goods")
* [Video tutorial](/sinespace-sdk/components/virtual-goods.md)
* [Virtual Goods](/sinespace-sdk/components/virtual-goods.md)
Whatever products you are selling, from whole regions to clothes, accessories, furniture or gestures, all you need to do is add the virtual good component to each asset and upload it to the store.

---
### Creating Menus for Interactive Objects
#### Overview[β](#overview "Direct link to Overview")
This article walks through building a menu or 'HUD' for an interactive, scripted object in Sinespace.
#### Introduction[β](#introduction "Direct link to Introduction")
This article describes how to create menus or 'HUDs' for interactive objects in SineSpace. This article depends heavily on previous work from Mike (CNDG), published in the SineSpace Forum HowTos, and with foundational work supported greatly by Torgon Woodget, Xulain, Trilo Byte, and the unstoppable Adam Frisby.
#### Let's get busy[β](#lets-get-busy "Direct link to Let's get busy")
There are a few conditions upon which any such HUD project would be predicated. Mainly, that the HUD interface described in this article is specifically for use with scripted objects. There are also some simple circumstances where the HUD could be wired up to certain components, or certain predefined operations. We will employ such operations to the ends of managing the HUD, but our primary focus will be the slightly more complex case of driving scripted operations. This should provide a good survey of the use of the UI for creating HUDs of various sorts. The other condition, of course, is that you have some object to which to attach your scripts and interface. For our purposes, we'll use a *Unity Primitive* of the type *Cube*. To create the cube, use the menu click path *Game Object->3D Object->Cube*. In this article, we'll reference all Unity Editor menu operations in this fashion.
The HUD we will develop in this article is a non-modal screen overlay with a background and a few buttons. The buttons will invoke certain functions within the accompanying script. The HUD will be invoked by clicking on the object proper, and will be dismissed with one of the buttons, styled as a classical 'Close' button.
This type of HUD is very versatile and can be adapted to a considerable set of interactive objects. It's ideal for a certain class of objects, in that it appears only as a result of manual interaction with the object, and uses no valuable screen real-estate when not in operation. I've used this type of HUD to great effect in my 'Nuklear Radio', which can be found in the SineSpace marketplace (\).
#### Setting up the object[β](#setting-up-the-object "Direct link to Setting up the object")
The entire object is organized under an Empty Game Object, so create one in your scene, position it conveniently, and give it an appropriate name. Various components and at least one object will be involved. Firstly, lets get the object out of the way: add it as a child to the Empty Object just created in the scene, and adjust the object's relative position accordingly. For purposes of the article, the object will be the cube created earlier.
Next, add the 'Scripting Runtime Component'. This is where the Lua script lives that implements the HUD functionality.
\- After selecting it, add a *Canvas* to the now not-so-empty game object we created at the beginning. Henceforth, we will refer to that foundational game object simply as *GO*.
(Game Object->UI->Canvas)
\- To the new canvas, add an *Image*. While we won't be doing so in the tutorial, this is where the opportunity resides to 'dress up' the UI with a background illustration. Note also that we are passing over some significant detail here in this process; there are various things which must be done to properly size and position the HUD; those are properties of the image, and potentially the canvas. For our purposes, the canvas goes untouched. (Game Object->UI->Image)
\- To the image, we will add some buttons. Specifically, three of them: 'Red Alert', 'All Clear', and 'X' (our classical close button)'. Go ahead and create three buttons. Be sure they are all children of the UI image created in the previous step. Edit the position relative to the image, and labeling of the buttons accordingly.
(Game Object->UI->Button)
You should end up with something similar to this:
Your buttons should resemble this in the inspector:
#### Wiring up the UI[β](#wiring-up-the-ui "Direct link to Wiring up the UI")
Management of the UI is accomplished with two clicks; one is the click on the object to invoke the HUD, and the other is the button used to close the HUD. While the object itself is not a button in the UI, it will be treated essentially as if it were, once we have added a *Clickable Activator* component. Go ahead and do that now.
Click on the GO and then in the inspector, 'Add Component'. This should work all more or less as you would expect.
A note about the general unity strategy for exposing screen overlays like this HUD: they are set up and then disabled by default. This allows them to be toggled via some stimulus. The *Clickable Activator* added in the previous step will provide the stimulus to enable the HUD in our application, and the 'Close' button will provide the stimulus to close it.
In the inspector, the *Clickable Event* for the activator should be set to 'canvas.enabled'. Before the proper click path becomes available, you will first need to slot the canvas in the clickable activator. You can set a tooltip value here as well, though it isn't required. The other necessity is the state to which 'canvas.enabled' should be set; it is indicated by the presence or absence of a check in the (unlabeled) checkbox. For the object's click event, we want this enabled status set 'on', so a check goes in the box. Make sure that the UI *Canvas* is slotted in the event's 'target' object, noting that yours most likely *wont* be called 'RadioUICanvas'. None of the other options in the clickable activator component are required.
The completed component should look about like this:
Now to the close button. Apart from a large set of parameters concerning the button's appearance, it has an 'event' setup, just like that on the clickable activator component. It should be set up identically, except in this event, the status for the canvas.enabled handler operation should be set to 'disabled', so no checkmark in the box. It too should have the UI *Canvas* slotted in the event's 'target' object.
It should look about like this:
Now to wire up the other two buttons, we need a script. It's important that we have a few addressable functions exposed by the script that we can tie into the events on the buttons, like we did for the object and the 'close' button. We're not going to get into too much depth about lua scripting beyond cutting and pasting a very simple script into the script window of the *Scripting Runtime Component*. This script will be simple enough such that it's fairly obvious what it's doing, and easily over-explained for purposes of this article ;)
If you haven't already, add a *Scripting Runtime* component to your original GO, by selecting the GO and using the *Add Component* button.
Here's the script:
```text
function redAlert()
Space.Log("Red Alert! All Hands!! Man your Battle Stations!")
end
function allClear()
Space.Log("All clear. All Hands, At Ease.")
end
```
The forgoing script should be copied and pasted into the *Scripting Runtime* component attached to the GO. You will perforce want to slot the GO into the events tied to each of the buttons. *This is so that the system 'knows' to use a scripting runtime context in the event operations dropdown, and where to look for requested functions.*
Now we will set up the buttons. Select the 'RedAlert' button, and find it's event block. Add an event. Note that if you set all these events 'Editor and Runtime' you will be able to experiment with this technique directly in the Unity Editor. In the new event for the button (dont forget to slot the GO!) select 'scripting.runtime' from the dropdown, and in the text field opposite the target object slot, enter 'redAlert'. Note that while this *is* in fact a function reference, you *should not* provide an empty argument list \[i.e., '()']. The function label should be completely bare.
Repeat this process for the AllClear button. in the text box, enter 'allClear' instead of 'redAlert'.
Save your work ;)
If you click the preview button in the editor, you should be able to click the cube, get the menu, and issue red alerts and all clears to your heart's delight. As you may be able to tell from the simple script, these do nothing but write to the system log.
In editor mode, you will only be able to see notifications of new chats, not the chats themselves; for that you will have to switch to the console window.
#### In conclusion[β](#in-conclusion "Direct link to In conclusion")
This should give you a fairly good overview of making object-bound huds for SineSpace. If you have questions, feel free to hit me up on the developer channel. I'm generally around :D
---
### Making Animated Doors
#### Overview[β](#overview "Direct link to Overview")
We'll be updating both the doors themselves and the wiki as needed.
We'll be updating both the doors themselves and the wiki as needed.
Doors could be said to be *complex game objects*. They are structured collections of GameObjects and Components, and how they are assembled and "wired up" is essential to their operation. They will typically consist of some sort of framing in which the door proper and possibly a hinge sits, and the door, which may be a single mesh or in the case of the swinging door, an empty GameObject "hinge" to which the door mesh is a child.
Additionally, the various GameObjects will have certain components associated with them, typically to facilitate user interaction and to animate the GameObject.
Setting up doors can be a bit tricky, but creating content for Unity is not for the faint of heart. Hopefully, with this tutorial we can make that workflow somewhat less painful for Sinespace creators.
Level:
* Beginner Unity/Sinespace, intermediate experienced with animation and game level design
Goals:
* Learn your way around Unity with Sinespace editor extensions
* Learn about the animation system and collision triggers
* Reproduce three different self contained game object doors
Note that the first tutorial walks the content maker through very detailed workflows in order to acclimate the user to the tools and processes by which the game object is created. The remaining tutorials will not seek this depth of instruction, but rather will refer back to the first. Therefor, it's fairly important you should build at least the first door in order to grasp the fundamentals that will be somewhat bypassed in the tutorials for the remaining two doors.
If you are an experienced Unity user who is using this wiki article as a reference, feel free to skip ahead or around as needed, and god love you and help you :)
###### The Sliding Door[β](#the-sliding-door "Direct link to The Sliding Door")
The *Single Panel Sliding Door* is perhaps the simplest possible articulated door. Before we get into a step-by-step walk-through of it's construction, lets break it down conceptually from the top level.
Firstly, there are three requirements of any door:
* it must be somehow attached or stationary relative to some enclosure
* it must provide ingress to the enclosure to which it is attached
* similarly, it must provide egress from the enclosure to which it is attached
Given these requirements, we could say that we will need a structure for the door frame, of arbitrary complexity, and a structure for the door proper, of equally arbitrary complexity.
For this door, our doorframe will be fairly complex, consisting of a transom piece, a threshold piece, and left and right door posts. The door will be a single cube mesh of appropriate size and proportions to fit suitably within the frame.
To get started, create a new project for space, or perhaps use one that you have available for experimentation and development. Use the *Main Menu* to create the first of the cubes we'll use (*Main Menu: GameObject->3D Object->Cube*). Just under the left side of the main menu, click the button to expose the scaling tools. Scale the cube a bit higher than the head of the avatar you would use to walk through the door, and then a little wider than that avatar; on the remaining axis, make it proportionately thick.
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 1: Sizing the door* |
***
Next duplicate this cube. Be sure it is selected, as in the image above, then on the object in the hierarchy, *right click->Duplicate*. Now switch to the translation tool, and move the copy along the X axis until it is clear of the door. Switch back to the scaling tool, and edit the thickness in each horizontal direction to form the left door post. Duplicate this one just as you did the door previously, and using the translate tool, move it to the right of the door.
Perform similar operations for one each of a transom (above the door) and a threshold (below the door). It should look something similar to the image below:
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 2: The completed door frame* |
***
Now, we can't very well just fling down a couple of cube meshes and expect it to behave as a door; and we really need to start organizing things as a unit. This will be important structurally. Note also that the door's 'frame' is not as simple as it could be; it really just needs to be any rigid body mesh; in actuality, it doesn't have to be that even; it could simply be an empty game object, as in the next tutorial. The one constraint is that animation of the door will occur relative to this piece; it can be as simple or as elaborate as you like. I'd perhaps stop short of making it the bulk of a building's construction.
So first, lets rename those cubes. Let's make sure to get the names right, recognizing them will be important a little later in the process. Additionally, some structure will be important. Within the hierarchy window, create an empty GameObject (*RightClick Hierarchy Window->Create Empty*). Drag all the door and door frame pieces and drop them on the empty GameObject; then (again, in the hierarchy window) rename the game object something like 'SinglePanelSliding Door'. It should resemble the following image; no changes should occur in the geometry of your construction; only the logical structure in the hierachy window.
Should your door objects be oddly nested, just drag them all out and nest them as shown in the image below.
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 3: The logical structure of the door, highlighted in the Hierarchy view* |
***
This structure is actually very important, if not elaborate. We're working with the simplest possible door, so the structure is the simplest possible; but rest assured that it is crucial to the operation of the door.
Before we move on to the next thing, there's one last thing we need to do to each of the elements of the door frame: make them rigid bodies. This is accomplished by adding the 'Rigid Body' script component to the inspector pane when the object is selected in the hierarchy. Once this is added, uncheck 'Use Gravity' and check 'Is Kinematic'.
Now we can begin adding the components to the structure that facillitate it's operation.
First select the container GameObject created and renamed in the last step. Then click the large 'Add Component' button at the bottom of the inspector pane in the Unity interface. In the search field at the top of the window that appears, type 'Animator'. Click on the Animator component that appears as a search result, adding the component. Repeat once for each of 'Box Collider' and 'Proximity Activator'.
Lastly (for this step), resize the box colider as shown in the following image. Editing the box collider is initiated by clicking the icon labelled 'Edit Collider' in the inspector pane. Editing the colliders uses a slightly different interface than other unity editing widgets. There are small dots in the face center of each of the collider's faces; these are handles for translating the face along it's perpendicular axis. This is the only type of editing operation to which a box collider can be subjected.
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 4: The Box Collider* |
***
Next, in the inspector tab for the box collider, click the box for 'Is Trigger'. This will turn off collisions in a physics simulation sense, and enable the collider to behave as a sensor that triggers it's associated Proximity Activator. The Proximity Activator script multiplexes various signals to the animations defined in the *Animation Controller* configured within the Animator component. In our construct, these signals take the form of strings that are sent up as a result of the occurance of the events 'Activate' and 'Deactivate'. Multiple reactions to each of these two events may be configured in the inspector using the '+' button. They can also be removed with the '-' button.
At this point, it would probably be a good idea to create a folder in your project to contain the various elements of the animation. But you already did that probably :) If not, do that now, and get into the folder. Right click the emptiness, and *Create->Animation Controller*. Double clicking the object in the folder (the Animation Controller) will allow you to begin editing the component. Before you do though, be aware we still don't have animation(s) created for the door, so what you see there will neccessarily reflect that degree of completion of the door's construction.
The animation controller is what is referred to as a *State Machine*. It is often misidentified as a *Finite State Machine* or *FSM*. It does not meet the requirement, however, as the state machine will exist in multiple states during transitions between states.
It is configured with an interface called a *Node Editor*. More on that in a few minutes.
When you've finished fiddling with the Animation Controller (hopefully you didn't change stuff substantially), make sure you have the top-level door game object selected, and press 'Ctrl 6' on your keyboard (FYI you can also open the animation window for the selected object from the *Windows* menu on the *Main Menu*). This will open the animation editor. The animation editor is a scene graph editor. *Almost anything* can be animated in unity. If you can click on it in the hierarchy and see modifiable properties in the inspector pane, chances are it is possible to use a scene graph to generate values for that property over the course of time, producing an animation of that property.
We will be using the scene graph editor to create three scene graphs: 1. the door in it's inactive state; essentially empty from an animation perspective. 2. The door transitioning from it's idle, *closed* state to an *open* state. and finally 3. The door transitioning from it's *open* state to it's *closed* state. These animations will form the basis for what happens once the collider triggers the proximity activator sending up the appropriate signals to the animation controller via the animator component. Starting to get the picture here? don't worry, if it hasn't already, it will start to come together soon.
Following is a screenshot of the unity editor with the animation controller exposed in the node editor interface, as it looks without our animations in the object's context:
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig 5: An early peek at the animation controller state machine within the node editor.* |
***
If your animation editor is not already open and displaying a button center-window labled 'Create', then select the top-level door game object in your hierarchy, and press 'Ctrl 6' on your keyboard. Then click that 'Create' button.
This will open a system file browser and prompt you for a new name for the *clip* as they are called within the context of the scene graph editor. Give it a unique and descriptive name; this will be the first of the three previously mentioned animations (Idle or 'closed'). When this is done, you will see the animation's name displayed on the scene graph editor's window/tab at the far left of the second row (toolbar). This is a drop down list, with the final item on the list always being 'Create New Clip...'. Go ahead and create all three and make sure they appear on the drop down list as shown in the image that follows:
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 6: Setting up the animation clips.* |
***
Select the clip for 'open' in the dropdown list, and click the 'Add Property' button. What this is going to do is instantiate a *picker* containing a tree of all the object properties who's values may be varied by scene graph. This picker structures the items into the tree based on the container hierarchy reflected in the folder-like organization in the hierarchy view. This is how that structure begins to impact the context of of the object vs it's animated properties.
The property you'll want to add will be *Door->Transform->Position*. If your door is named something other than 'Door', then you'll want to pick your door name out of the picker tree instead. To finally add the property to you clip, click the little '+' to the right of the property you're adding. It should look a lot like this:
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 7: Adding properties to a clip so their scene graphs can be manipulated.* |
***
Having clicked the little plus, you'll now have a position property above the 'Add Property' button. Click the switch triangle to it's left to open it. You'll now see the scene graphs for each of the three properties of the position: X, Y, and Z. We'll be animating the 'X' property. On the time scale across the top of the scene graph opposite the properties, click about two thirds right on the scale. This should set the time cursor forwards about 2/3 the way through the scene graph. Next, right-click on the intersection between the X axis on the scene graph (horizontal, top property of the position), and the time cursor you just set. Select 'add keyframe' from the popup menu this click generates. You'll see a screen greatly resembling this:
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 8: Setting up Keyframes*. |
***
Now click on the diamond that appeared on the scene timeline. This is your keyframe. You should also notice to the right of the property label back on the left side of the screen, a number. Click it. Select the number and copy it with 'Ctrl-C'. Change it from '0' to '1'. If yours has a different number, say, 6.73, make it 7.73, or perhaps 5.73 if you'd like to have the door slide to the other side. If you have rotated your door to some arbitrary rotation, you're going to have problems moving forward with this tutorial; but don't be concerned, there are straightforward methods for doing that, we're just not going there at this time. So, if you switch to your 'Scene' view, you'll see very something like this:
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 9: The scene view, with the scene graph cursor in the animation editor positioned on the final frame of the 'Open' animation.* |
***
If you haven't yet, switch back to the 'Animation' view. Don't confuse it with the 'Animator' view. Now on the dropdown list just above the properties tree for the door, select your 'close' clip. We've yet to fiddle with this one, so we repeat the process starting with adding a position property for the door (hint: it's a *Transform*).
Next add a keyframe by right-clicking the intersection between the 'X' positional property and somewhere around 40 frames into the scene graph timeline. Finally, select the last diamond at the intersection of the scene graph and the 'X' property axis (it's the first frame). Now back on the left hand side where the numbers are, click whatever number is there and replace it with the one you copied earlier (Ctrl-V or Shift-Ins). You should have something approximating this:
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 10: Setting the initial value for a property in the animation editor.* |
***
Additionally, if you have a peek at your scene view, you will see that the door has closed again. That's a good thing (tm). Don't forget, we've been working in the 'Animation' view, not the 'Animator' view. That's about to change, though.
A quick note on authoring animations in Unity: be *very* careful that your animations are doing what you think they are. An animation with an 'off' keyframe can make everything look faulty, even when it's actually otherwise perfect. Additionally, if you can at all, run the unity editor on two monitors. It will save you no end of headache, as you can actually get everything on the screen and open at once so as to be able to tell with absolute precision what your animations are doing, and what is transpiring in your state machine, vs what is happening in the scene. This made the difference in struggling to find a problem all afternoon and recognizing it within a few mins for me at the time that I wrote this tutorial.
Note also that the numbers showin in the scene graphs likely reflect some of the animation errors I made when making the tutorial, and should not be trusted. Before operating your door, be sure to drag the scene graph cursor down the timeline of your animation clip, and watch it in the scene view to insure it is doing exactly what you would have it do.
One last thing before diving into the 'Anitmator' view: locate the animations you've recently created, specifically the 'Open' and 'Close' animations. Uncheck the 'Loop Time' setting. This will keep them from firing repeatedly. Next locate the 'Idle' animation, and insure that 'Loop Time' *is* checked in the inspector interface.
If you switch to your animator view, you will see something quite interesting. The view of our animation controller has changed dramatically. This is because it is contextually aware of what we're doing. This is not miraculous, but it is pretty decent engineering. The makers of unity understood that we were going to establish a relationship between animations and arbitrary *states* in a *State Machine*, and added those to our animation controller view. It also arranged them logically for us, though we will need to insure that the proper conditions are met to permit or preclude transitions between states.
Here's a view of the state machine in the node editor for the animation controller:
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 11: The node editor with the animation controller state machine loaded.* |
***
It's worth taking a moment to go a little more in-depth with respect to the *Node Editor*. Examining the state machine, we can see it is a sort of flowchart. However, not all of the salient information about the state machine is present in this graphic representation; only the structure, as presented by an ordered set of colored and labeled icons positioned on a grid.
Three types of these icons are present in our view in the previous image ('Any State', 'Entry' and 'Exit'), and are *terminal* (in the literal sense), meaning that they describe entry/end points for the state machine. 'Any State' can be wired up to a state that can be entered at any time; and 'Entry' and 'Exit' are fairly self explanatory; in our animation, we never want the state machine to exit, and to only be entered according to signals from the proximity activator so these two are not wired up.
Additionally, there is one of the states that is orange: this is the default state. It is just that, and 'Entry' is always wired to it unconditionally with a transition that cannot be previewed or modified. Any otherwise mundane state can be made the default state using a pop-up menu that appears with a right-click on it's icon.
The wiring, or arrows in the view, indicate the direction of state transitions explicitly; but there are also a potential set of conditions that must be met in order for the transition to occur. The interface for setting these appears in the inspector when one clicks on the transition icon (arrow).
One last thing about this node editor: if you have it open when playing back animation clips associated with the controller that's loaded into it, it animates and indicates the state it's presently in, active transitions as they occur, and progress through the clip indicated in the state. This can be indispensible when troubleshooting animated objects.
Note the sort of clockwise flow between the states associated with our three animation clips. This is because it is only possible to reach one of these states having arrived at the one prior to it in the cycle. One does not go from an idle state to a door closing state; that is not logical. One only closes a door that is open. What we must do next is to configure the state machine such that it only opens the door when signaled to do so, and only closes it after it has been opened. This is done by setting conditions in the transitions represented by the connecting arrows. We can't do that just yet though, first we have to declare the functions in the proximity activator that are sent up as a result of the collider events. Unity has already predefined the signals for us in the state machine. To the left of the node editor interface, you's see a *parameters* tab open on top. The two parameters given are the signals, 'Open' and 'Close'.
The functions are to be declared in the inspector, with the Proximity Activator exposed in the interface.
At the bottom of the Proximity Activator pane in the inspector, see the *Events* block. There are two events, we examined briefly when we added the component; these are *Activate* and *Deactivate*. Now, what we want to happen under either of these conditions is for a string to be sent up to the animation controller that matches a parameter there. This is accomplished with the *animator.SetTrigger()* function. This function will send up whatever string is passed to it to the Animation Controller. We want to set this funtion on both events, but each invocation with appropriate string value. These functions are added and configured in the interface by clicking the '+' sign near the event in the interface, and the resulting configuration options for the event filled from the picker in the popup. What you ultimately arrive at should be something a bit like this:
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 12: Tieing the Gameobject back to the Proximity Activator.* |
***
Now we should be ready to set conditions on the transitions in the Animation Controller's state machine. Switch to the Animator view, and in the node editor click on the transition arrow between the 'idle' state and the 'open' state. The names are just descriptive, but they should be recognizable in the interface. In the inspector, you should now see the properties for the transition. The important thing is that the right states are associated with the correct animations, and that the transitions occur in a logical fashion. The control of the transitions is through *conditions* set in the inspector with the transition selected:
***
|  |
| ----------------------------------------------------------------------------------------------------------------------------------------- |
| |
| *Fig. 13: A look at the properties of a transition in the node editor.* |
***
Take a peek at the 'Conditions' pane in the inspector: notice that it specifies 'Open' as a condition for the transition from the 'Idle' state to the 'Open' state. This is because we open the door as soon as the controller is activated by the proximity activator. The next transition in the flow has a condition set for 'Close', which is only ever activated when the proximity activator is deactivated. The final transition in states, from 'Close' back to 'Idle', happens without conditions. Configure yours as such and you should be ready to preview your door in the editor's 'play' mode.
---
### Recipes
#### Overview[β](#overview "Direct link to Overview")
Recipes are a special type of item upload that exchange input item IDs for one output item ID, or for one weighted random output from a list.
A recipe can only produce one output. If multiple output IDs are provided, Sinespace picks a random item from the list, weighted by the `weight` field.
The user must have the desired input items in their inventory. These items are destroyed when the recipe is executed. If no input items are specified, the recipe gives out a random item from the output list.
Recipes can be used for:
* Quests where parts of a whole object are collected and transmuted into the finished product.
* Treasure hunts and other activities where random rewards are desired.
* Lucky Dip sales, such as buying raffle tickets that return random items.
note
Recipes must be approved by Sine Wave. Open a support ticket if you want to set one up. Output items may be split across many creators with the consent of all parties.
---
### Spawnable Objects: Uploading and Spawning Objects
#### Overview[β](#overview "Direct link to Overview")
Creating spawnable objects for Space is very different from creating objects for more simulation-oriented platforms, where such construction activity occurs *in-situ*. As Unity's method of distinguishing and storing scene elements is the *Prefab*, as in other application areas, Space picks up the concept and extends it to our use case.
#### Creating the object[β](#creating-the-object "Direct link to Creating the object")
First the object to be used as a Space rezzable is created in Unity. The Space Editor Pack must be imported and installed; prior to uploading, the creator must be logged in to the Space creator servers.
Once the object's construction has been completed, drag it from the heirarchy back into the project folder where you can find it. Attach the *Virtual Good (virtual good) Script* component to the prefab of your object.
Examining the Virtual Good (virtual good) Script component in the inspector, fill in the minimum fields: Name, Brand, Developer Name and Category.
Set the *Content Type* for object type to 'Generic'.
#### Uploading the object[β](#uploading-the-object "Direct link to Uploading the object")
Click the *Automatic Submission* button at the bottom of the script's property pane (you might need to scroll the inspector to see it).
This will initiate the item upload, which, you will find, goes a lot more quickly than a region upload. Once it completes, you will find the item in your Space avatar's inventory.
#### Spawning the object in-world[β](#spawning-the-object-in-world "Direct link to Spawning the object in-world")
Once you've logged into Space with a web browser or Space desktop client, you will find the object in the avatar's inventory. You can either click it and add it to your hotbar (dragging to the hotbar works too, but be careful you don't over-write something already there), where it can be clicked for quick spawning, or alternatively, drag the item from your inventory onto the ground.
You can delete the item from your inventory once you have placed it in world.
---
### Adding Poses to Furniture
#### Overview[β](#overview "Direct link to Overview")
You can add poses to furniture to make the item sittable.
You can add poses to furniture to make the item sittable. This will add a blue arrow icon to the piece of furniture, which a user can click on and then the avatar will sit on the furniture in the pose/animation you have added to it.
##### SeatImproved Component[β](#seatimproved-component "Direct link to SeatImproved Component")
Once you have the piece of furniture in the scene, click on the furniture item in the hierarchy, then click Create and choose Create Empty Child.

You can rename this to 'Pose' or 'Seat' to make it easier. Making a child for this is so you can move the pose independently from the main furniture mesh to help position the avatar correctly once animation is added.
With the child/Pose highlighted, click on Add Component in the Inspector window and search for Seat Improved.
When you have added the Seat Improved component, you will see a green box show up on your furniture item and also see the Seat Improved script settings in the Inspector Window.

Under the Seat Improved script, you will see a few options.
* Animation
* Gender-Specific Overrides
* Action Tag (Optional)
* Network Adjustments
* Events
* IK Targetting
###### Animation[β](#animation "Direct link to Animation")
This is the slot for the animation clip you want the chair to play when an avatar sits here. You can have a static animation or a dynamic animation.
###### Gender-Specific Overrides[β](#gender-specific-overrides "Direct link to Gender-Specific Overrides")
These will override the animation clip you have placed in the Animation slot with a gender specific animation. There is a slot for male animation, female animation and also a slot for NPC. The NPC override will make the animation static.
###### Action Tag[β](#action-tag "Direct link to Action Tag")
These are optional settings to change the location of the action tag. You can override the location here and also add a collider to hide the tag. Note: You won't be able to see the tag in Unity. You will have to check the tag position by uploading the furniture to staging and testing it on the preview server.
###### Network Adjustments[β](#network-adjustments "Direct link to Network Adjustments")
If you are placing your SeatImproved component on something that moves, e.g. a swinging chair, you will need to check the Slot ID box, and then add in a Seat Slot ID number. You can choose any number you like as long as it is unique, for example something like 403.

###### Events[β](#events "Direct link to Events")
These are optional settings where you can set up an action to activate or deactivate when the user sits down or stands up.

The top two, On Stand Up and On Sit are global, so this means any action will affect all avatars including your own. The bottom two, On Player Stand Up and On Player Sit trigger locally for yourself. This is handy for HUDs, buttons and other such things. In the image above, this local event setting is being used to active the player camera to focus on the browser screen when the user sits, and switch back to normal player camera view when the user stands.
###### IK Targetting[β](#ik-targetting "Direct link to IK Targetting")
IK targetting is used to override the default placement of the hands and feet in the animation. This is particularly useful to make sure that the avatars' feet don't go through the floor e.g, if you have placed a chair on a rock and you don't want the avatars' feet to fall through the rock.
If you want to use IK targetting, you will need to create an Empty Object. Name it with reference to the IK targetting such as LeftFoot or RightFoot e.t.c Place the empty object at roughly the same height and placement as the avatars' ankle (this will make sure that avatars' of different height don't have their feet going through the floor). Drag this empty object into the Transform box on the IK targetting.

You can test the placement by clicking on the 'Play' button at the top of Unity and switch to the 'Game' tab. If the positioning is not correct, you can move the empty object until it is in the right place.
##### Adding the Animation[β](#adding-the-animation "Direct link to Adding the Animation")
For this chair, I am going to use the Animation slot as I want this to be used by both genders.
Find an animation you want to use for the pose that your avatar will use on the chair.
Once you have the animation, click on it in the Project window. It's Import settings will be shown in the Inspector Window.

Under the Rig tab, there will be a couple of sub headers:
* Animation Type
* Avatar Definition
* Source
The animation type will want to be set to Humanoid.
If you are setting the animation up to be used with our default avatars, choose Copy From Another Avatar under the Avatar Definition header.
Go to Source and choose the fitting avatar for the animation. If you are using gender specific animations, please select the right gender from the 2015 Female and 2015 Male avatars .fbx files.
Click Apply.

Go to the Animation tab and scroll down to Motion. You want to set this to None so you can independently move the avatar when playing the animation under the Game tab.
Click Apply.

##### Testing And Finalizing the Animation[β](#testing-and-finalizing-the-animation "Direct link to Testing And Finalizing the Animation")
Once this is done, click on the child of the furniture (Or Pose if you renamed it), and drag the animation into the rightful animation slot under the Inspector Window. Remember to place the specific animations for female and male overrides if this is what you want to do.

After doing this, you can search for 'PlayerChar' in the search bar of your project window, and drag it into the hierarchy. You will also need to add a Plane mesh if you are using an empty scene as the player-character will fall through the ground of the Unity scene without it. To add a plane, click Create under the hierarchy and go to 3D Object and choose Plane. You will want to place this underneath the furniture you are using.
Once this is done, you can click on the Play button at the top of the screen. This will take you to the Game tab, and you will see the Space UI, your avatar and the furniture. When you hover over the furniture, a hand icon will appear. (In-world, this will be a blue arrow action tag). Click on it and your avatar will 'Sit' on the piece of furniture with the animation/pose you have chosen.
If the avatar is not in the right position, click on the Scene tab, but do NOT stop the Game. You might have to right click the Game tab to minimize it if it is maximized. Click on the child/pose in the hierarchy. You can move your avatar along with the animation to fit the furniture properly.
Once you have moved it, you will see that the new placement is marked under the Transform header in the Inspector window. Right click the Transform header, and choose Copy. This insures you won't lose the correct placement when you stop the Game tab.

Stop the Game tab from running by clicking the Play button at the top of the screen. You will see that the Transform position is back to 0,0,0. Right click the Transform header, and choose Paste Component Values. This will add the coordinates you copied to put the animation in the right position.
The furniture is now set up with the animation/pose.
##### Uploading the Furniture[β](#uploading-the-furniture "Direct link to Uploading the Furniture")
To upload the furniture item with the SeatImproved script, click on the parent object of the furniture item in the hierarchy, for example, a chair with the SeatImproved component on it. In the Inspector Window, click on 'Add Component' and search for 'Room Furniture'. Add this component and set it up. If you need to know how to do this, please see [here](/sinespace-sdk/furniture/how-to-upload-items-as-furniture.md). Once this is set up, you can then add the virtual good component to the furniture item, then drag this from the hierarchy into the project window to make a prefab. When you have made the prefab, click on it, and fill in the virtual good component. For furniture items, the Type must be set to Furniture. The category should be Furniture, then choose the appropriate category. Fill in the rest of the details on the virtual good component, then you can hit the Automatic Submission button under the Upload tab to start the process of uploading to Sinespace. You can check on the progress of your upload at curator.sine.space
---
### How to upload items as furniture
#### Overview[β](#overview "Direct link to Overview")
\#firstheading You can upload items as furniture items to place in room templates with the 'Edit Room' button.
#### [#firstheading](#firstheading)[β](#firstheading "Direct link to firstheading")
You can upload items as furniture items to place in room templates with the 'Edit Room' button. These furniture items can be dragged from your inventory and placed in your room. The items don't necessarily have to be furniture such as chairs, and they can be game items (like the Greedy Greedy table in the Welcome Center), a presentation tool or pieces of a structure which users can use to build a larger item (e.g. pieces of a race track).
If you want to make the furniture item sittable, you will need to add the SeatImproved component to an empty child object and parent it to the furniture. Here is a [tutorial](/sinespace-sdk/furniture/adding-poses-to-furniture.md) on how to do that.
###### Attaching the Furniture Component[β](#attaching-the-furniture-component "Direct link to Attaching the Furniture Component")
1\. Have the item object you want to upload as a furniture item in your scene in Unity. Once it is in the scene, click on it in the hierarchy.
2\. In the Inspector window, click on 'Add Component', search for Furniture and add the 'Room Furniture' component.

3\. Once added to your object, you can change the settings to best fit what the furniture will be used for. Tick the Place on Floor box for objects such as chairs, sofas e.t.c, tick Place on Walls for things such as paintings and tick Place on Ceiling for things such as ceiling fans. If you are uploading furniture which will be placed on the floor or ceiling, make sure that the Y axis (green arrow) in Unity is facing outwards. If you are uploading furniture which will be placed on walls, make sure that the Z axis (blue arrow) points outwards (away from the wall).
4\. In the Collider section of the Room furniture component, drag in the furniture items main collider. This should be done for all furniture uploads. If your furniture item does not have a collider, you can add a box collider to it by clicking on 'Add Component' and search for 'Box Collider'. You can then adjust the box collider to fit around the item. There is also the option to 'only enable collider during editing'. This should be checked if normally the collider should be disabled, e.g for particles or lights.

5\. Next is Transform Controls. In here, you can check the 'Allow Scale' box if you want users to be able to scale the furniture once they place it in their room;if not, leave it as it is.
6\. In Appearance, there is the Icon Position. This is the position of the blue arrow (action tag) which hovers above the furniture for users to click on to enable them to sit on the furniture.
###### Uploading the furniture[β](#uploading-the-furniture "Direct link to Uploading the furniture")
1\. Underneath the Room furniture component in the hierarchy, you will see an 'Add Component' button. Click on this, and search for Virtual Good. Add this.
2\. Once the virtual good component is added, under Basics, set the Type to Furniture then the Category to the appropriate category.

Fill in the rest of the virtual good component with the information for your item and then upload the item to Sinespace.
---
### SeatImproved
#### Overview[β](#overview "Direct link to Overview")
The seat Improved component is added to any item that you want to enable animation on; specially furniture.
The seat Improved component is added to any item that you want to enable animation on; specially furniture.
##### Adding Seat Component[β](#adding-seat-component "Direct link to Adding Seat Component")
Create an empty Child in the furniture(To be able to move the animation easily). Add component on child and select Seat improved script.
##### Seat Improved Properties[β](#seat-improved-properties "Direct link to Seat Improved Properties")
Animation: You can upload the animation you wish to play here.

##### Gender Specific Overrides[β](#gender-specific-overrides "Direct link to Gender Specific Overrides")
This is used to set specific animation for male and female avatars.
Animation male : Animation can be specific to Male Avatars only if it is added here.
Animation female : Animation can be specific to Female Avatars only if it is added here.
NPC : NPC can be placed on the furniture by dragging and dropping the Statue(NPC) in the scene here. To read more on how to create an NPC in scene refer to [Statue](/sinespace-sdk/components/statue.md).
##### Seat Improved video tutorial[β](#seat-improved-video-tutorial "Direct link to Seat Improved video tutorial")
To know more about seat improved watch the tutorial shown [here](https://www.youtube.com/watch?v=Hw0mjkaLs7Y\&index=18\&list=PL3MZuSlVM0J9c42EyQuOWzl6F_ZEfHWAM%7C)
---
### Guns and gun givers
#### Overview[β](#overview "Direct link to Overview")
FPS Components Shooter games FPS The safe zone lobby Player spawn points Health and ammo givers Traps King of the hill zone Enemy NPCs and NPC spawners The gun The gun system is a raycasting gun.
###### FPS Components[β](#fps-components "Direct link to FPS Components")
[Shooter games FPS](/sinespace-sdk/games/shooter-games-fps.md)
[The safe zone lobby](/sinespace-sdk/games/the-safe-zone-lobby.md)
[Player spawn points](/sinespace-sdk/games/player-spawn-points.md)
[Health and ammo givers](/sinespace-sdk/games/health-and-ammo-givers.md)
[Traps](/sinespace-sdk/games/traps.md)
[King of the hill zone](/sinespace-sdk/games/king-of-the-hill-zone.md)
[Enemy NPCs and NPC spawners](/sinespace-sdk/components/enemy-npcs-and-npc-spawners.md)
##### The gun[β](#the-gun "Direct link to The gun")
The gun system is a raycasting gun. The gun has a muzzle flash and impact event. Players can shoot each other and NPCs.
Players can hold up to eight guns in inventory at once.
The public variables on the gun include settings for bullet type, fire rate, range and damage. (Upcoming features will include configurable reload speeds, magazines, etc.)
Each gun also contains the Animation Override that plays idle, walk, run, damage and death sequences on the player.
This video tutorial shows how to configure and publish your own Guns and Gun Givers as inventory items that players can in place in their own customised multi-player maps in Sinespace;
[Watch on YouTube](https://youtube.com/watch?v=Lnwkd94yaqk)
The gun consists of three versions of the gun barrel (the visible gun). The other unique assets for each gun are;
* The muzzle flash
* The bullet
* The crosshair
* The Animation Override
1. Barrels
In the Elements folder of the Shooter project there are three gun barrels;
* Barrel,
* Barrel Mouselook, and
* Barrel Remote
The Barrel is the version players see in their own hands in third person view. The Barrel Mouseview is the version they see in mouseview, which they get to by zooming in on their mouse wheel.
The Barrel Remote is the version other players see. It has less scripts than the playerβs own two versions and not use unnecessary resources during gameplay.
1. Public variables
There are six public variables;
* bulletType
* fireRate
* range
* hitDamageNPC
* hitDamagePlayer
* showhits
* Bullet type\*\* will be referenced in the ammo crates and the gun bar on the Player HUD.
We recommend keeping **fire rate** down to a max of 8 bullets per second. (Networked pooling of bullets is in development to support higher fire rates).
* The range\*\* defines how far away a target can be and still take damage.
* hitDamageNPC\*\* and **hitDamagePlayer** set the damage done by the gun. Guns can be configured to inflict different levels of damage on player or NPC.
You can set **showHits** to 0 if you do not want other players to see each otherβs shots. (Which is pretty sneaky, frankly.)
1. Resources
In the resources you can see we have the **pool bullet**. This is a particle effect for impact.
The other resource on the barrel is the **third person animator**. This is the animation override for idle, walk, run, take damage and die while carrying the gun.
Notice on the movement blend tree we blend though three sets of the idle. This ensures the player moves to idle pose even if there is marginal movement on the character and prevents it from appearing to be walking on the spot.
The damage and death animations can be used to trigger events other than character animations. For instance you can combine the FollowAvatar component with a Cinemachine camera to move to a third person, bird eye view during the death sequence, so players witness themselves dying. Horribly.
Any events you animate as part of a death sequence should match the time you set in the deathSequenceDuration public variable on the Combat Meter in the Safe Zone Lobby. Remember you also want this timed with any animated event on the Death canvas in the Killed screenspace canvas.
1. Events
The Fire event triggers when the player fires the gun. It can trigger your muzzleflash and any other events, like a recoil animation on the gun (see tutorial video).
1. Object reference
The cylinder referenced in the barrel object reference is used to position the gun in the playerβs hands. It should be disabled but not deleted when you upload the gun.
1. Grip
The grip inside the barrel contains the disabled cylinder referenced above. You can enable this and use it to line up your gun so it fits into the playerβs hands. Donβt forget to disable it. Donβt delete it!
You need to apply your gun model to all three copies of the barrel. In our experience the mouselook version benefits from being enlarged compared to the others.
1. Barrel mouselook
The barrel has all the same settings, scripts and components as the main gun.
The Barrel mouselook has a canvas where you can insert a unique crosshair for the gun.
##### Gun giver[β](#gun-giver "Direct link to Gun giver")
This is an object in the scene that gives a specific gun type to the player. The template art Gun Giver is configured as a spawnable item which players can place in the map from inventory when laying out a customised map.
The Gun Giver can be configured in numerous other ways, for instance to spawn and destroy itself as a child of an NPC, making it possible to grab the gun of a dead NPC.
Or it could be configured to give a gun as a reward for completing a side quest (see the side quest video and documentation here and here.)
The public variables on the Gun Giver include settings for gun type, bullet type and the number of bullets in the gun when first collected by the player.
1. Public variables
There are 5 public variables on the script.
* gunType
* bulletType
* bullets
* bulletInterval
* order
* gunType\*\* is referenced here, in the gun bar and gun changer. Ensure you give each gun a unique name.
* bulletType\*\* we give the same naming convention as on the barrels.
* bullets\*\* is the number of bullets in the gun when you pick it up.
* bulletInterval\*\* is a cooldown rate; the gun giver will also give ammo for the gun.
* Order\*\* is where in the gun bar this gun will appear.
1. Resources
There are six resources on the Gun Giver; the three gun barrels, the 3rd person animator and the gun icon that appears in the gun bar.
Drag your versions in from the project. Do not alter the naming conventions.
1. Trigger activator
The trigger activator on the base of the Gun Giver triggers the event giving the gun when the player walks within the collider attached to the object.
Note this activator is set to owner only, so I donβt give the gun to everyone in the game at once!
---
### Health and ammo givers
#### Overview[β](#overview "Direct link to Overview")
FPS Components Shooter games FPS The safe zone lobby Guns and gun givers Player spawn points Traps King of the hill zone Enemy NPCs and NPC spawners The template examples of the He
###### FPS Components[β](#fps-components "Direct link to FPS Components")
[Shooter games FPS](/sinespace-sdk/games/shooter-games-fps.md)
[The safe zone lobby](/sinespace-sdk/games/the-safe-zone-lobby.md)
[Guns and gun givers](/sinespace-sdk/games/guns-and-gun-givers.md)
[Player spawn points](/sinespace-sdk/games/player-spawn-points.md)
[Traps](/sinespace-sdk/games/traps.md)
[King of the hill zone](/sinespace-sdk/games/king-of-the-hill-zone.md)
[Enemy NPCs and NPC spawners](/sinespace-sdk/components/enemy-npcs-and-npc-spawners.md)
The template examples of the Health Givers are configured as spawnable inventory items that players can place in their maps, adding to the unique challenges they can set for themselves and their friends when they play together.
The public variables on the Health Giver and Ammo Giver allow players to define the amount of health or ammo given, bullet type, and the cool down rate on individual items spawned in the map.
This video tutorial shows how to configure and publish your own Health and Ammo Givers as inventory items that players can in place in their own customised multi-player maps in Sinespace;
[Watch on YouTube](https://youtube.com/watch?v=h-q-id5eaew)
1. Public variables
* Health
* Interval
Health is the amount of health you get each time. Interval is the cool down rate before you can use it again.
There are no resources, events or objects.
The default art template has a trigger activator triggering the addhealth function when the player passes through the collider. It is set up as a placeable item in the map but you could configure the same component to drop as a one time vial that destroys itself when the player collects.
##### Ammo givers[β](#ammo-givers "Direct link to Ammo givers")
Ammo Givers let players collect ammo. Gun Givers also act as Ammo Givers. Individual Ammo Givers are tied to specific bullet types.
1. Public variables
The Ammo Givers have three public variables which players can configure when placing the items in their maps.
* bulletType
* bullets
* bulletInterval
* bulletType\*\* corresponds with the type defined in the Gun Giver.
* bullets\*\* defines the number of bullets the player gets each time they use the Ammo Giver.
* bulletInterval\*\* defines the cool down rate on the item.
The trigger activator triggers the script to call the bulletCrateTryGive function. This is triggered by walking through the collider which must be set to βIs trigger.β
---
### King of the hill zone
#### Overview[β](#overview "Direct link to Overview")
FPS Components Shooter games FPS The safe zone lobby Guns and gun givers Health and ammo givers Traps Player spawn points Enemy NPCs and NPC spawners The King Of The Hill (KOTH) Zo
###### FPS Components[β](#fps-components "Direct link to FPS Components")
[Shooter games FPS](/sinespace-sdk/games/shooter-games-fps.md)
[The safe zone lobby](/sinespace-sdk/games/the-safe-zone-lobby.md)
[Guns and gun givers](/sinespace-sdk/games/guns-and-gun-givers.md)
[Health and ammo givers](/sinespace-sdk/games/health-and-ammo-givers.md)
[Traps](/sinespace-sdk/games/traps.md)
[Player spawn points](/sinespace-sdk/games/player-spawn-points.md)
[Enemy NPCs and NPC spawners](/sinespace-sdk/components/enemy-npcs-and-npc-spawners.md)
The King Of The Hill (KOTH) Zone is a spawnable item that players can place in their maps. It is the first in a series of items that will provide a range of different game modes for the FPS system.
The KOTH Zone gives players points when they defend it. Successful defence of the KOTH zone is defined as one player or players from one team being within the KOTH zone for a period of time, alone or with no other teams present in the zone.
The public variables on the KOTH Zone allow players to define the time required to earn points and the number of points earned.
The points are integrated with the leaderboard and round system, deployed in the Safe Zone Lobby, allowing players to define the number of points required to win a round.
The KOTH zone supports a number of visible events including a dynamic animation system that will time animations to fit with the point duration defined by the player (e.g. in the tutorial video we show a flag rising up a flag pole.
If the players define a point as taking 10 seconds to accrue, the KOTH zone will time the animation of the flag rising to fit with that 10 second time period, resetting the animation if the point is not completed.)
This video tutorial shows how to configure and publish your own Health and Ammo Givers as inventory items that players can in place in their own customised multi-player maps in Sinespace;
[King of the Hill Zone tutorial](https://www.youtube.com/embed/HoMxzoriq4g)
1. Public variables
There are four **public variables** on the KOTH Zone script.
* pointInterval
* points
* team
* pointInterval\*\* is the time it takes for a point to be won.
* points\*\* is the number of points you get each time.
* team\*\* is currently pending; we will support team games on the KOTH zone shortly.
1. References
There is one reference; the animator. The animator. The default animator shows a cylinder going from large and green to red and small over the course of one point period.
1. Events
You can trigger events for the zone being free, taken (in an all against all mode) or taken by a specific team.
1. Animation Controller
Please note the speed is set to 0 and the animation is one second long.
Whatever you choose to animate, keep it to 1 second overall.
The script then updates the object you are animating in time with the time period defined in the pointInterval public variable; which defaults to 30 seconds but can be configured by the developer or the player setting out the item in their map.
1. Trigger activators
There are two trigger activators on the KOTH Zone. One is set to owner only and the other is set to exclude owner.
These are calling enterplayer / exitplayer and enterother / exitother functions on the script. You do not need to adjust these.
##### Server side script for koth zone[β](#server-side-script-for-koth-zone "Direct link to Server side script for koth zone")
The KOTH Zone requires a server script that coordinates events across the network.
To upload a server script you need to create an empty game object and add the **Server Script** component.
Attach the KingOfTheHillServerSide LUA script from the Shooter / scripts project folder.
Give the script a class ID. This can be anything so long as you reference it on the King of the Hill zone itself. Best practice would be to follow Java style namespaces; com.sinewavecompany.sinespace.fps.koh
Add a virtual goods component to the object and select type / Server Script.
Fill out the virtual good component as usual and upload.
Please note the server script will not appear anywhere in your inworld inventory.
Once uploaded, copy the item ID; when you upload a virtual good item you can see the item ID both in the title bar of the virtual good component in the editor and in the item list in your curator.sine.space account.
On the KOTH zone itself add the **Require Server Script** component.
Add the item ID from the server script you uploaded. Add the class ID, copying and pasting it from the server script.
Now when you upload the KOTH Zone with the **Require Server Script** component attached it will listen to the **Server Script** you have uploaded.
---
### Player spawn points
#### Overview[β](#overview "Direct link to Overview")
FPS Components Shooter games FPS The safe zone lobby Guns and gun givers Health and ammo givers Traps King of the hill zone Enemy NPCs and NPC spawners Multiple **Player Spawn Points** can be placed anywhere in a map.
###### FPS Components[β](#fps-components "Direct link to FPS Components")
[Shooter games FPS](/sinespace-sdk/games/shooter-games-fps.md)
[The safe zone lobby](/sinespace-sdk/games/the-safe-zone-lobby.md)
[Guns and gun givers](/sinespace-sdk/games/guns-and-gun-givers.md)
[Health and ammo givers](/sinespace-sdk/games/health-and-ammo-givers.md)
[Traps](/sinespace-sdk/games/traps.md)
[King of the hill zone](/sinespace-sdk/games/king-of-the-hill-zone.md)
[Enemy NPCs and NPC spawners](/sinespace-sdk/components/enemy-npcs-and-npc-spawners.md)
Multiple **Player Spawn Points** can be placed anywhere in a map. When each player leaves the Safe Zone Lobby to enter the game they are teleported randomly to one of the spawn points.
These are separate items that can be uploaded as furniture items so that players can place the spawn points across their maps how they want to. The positioning of the spawn points themselves is far more strategically important than the positioning of the safe zone.
This video tutorial shows how to wire up and publish your own Player Spawn Point as an inventory item players can in place in their own customised multi-player maps in Sinespace;
[YouTube video player](https://www.youtube.com/embed/3f-pcwu0LBk)
1. Public variables
The public variable on the Player Spawn Point allows players to define a team for individual spawn points when they are placed in the map. The spawn point will then only be available to players on that team.
A spawn point can also be left open for all players. (Please note, as of writing the team system for the FPS is still in development and the team functions on the Player Spawn Point are not yet active.)
1. Events
There are three events on the Player Spawn Point; free, red and blue.
These trigger particles or other events relating to the status of the spawn point. Players laying out team based maps can configure individual spawn points to spawn only players on specific teams or to be open for all players.
---
### Racing Games
#### Overview[β](#overview "Direct link to Overview")
Racing game components are easily accessible for everyone.

Racing game components are easily accessible for everyone. Racing game furniture items can be found in the Sinespace Shop. When in the Shop, click on the Furniture tab, then use the search-bar to look for dotEnterprise, and you will see all of the below items listed:

You will need all of these items to create a racing game.
##### Unpacking the furniture items[β](#unpacking-the-furniture-items "Direct link to Unpacking the furniture items")
The Racing Item Bundle will need to be unpacked before you can use the items. To unpack the bundle, click on it in your Inventory, then click on Use.


When you have clicked on 'Use' there will a pop up for the bundle.

Click on the 'Get' button, and this will add all the listed items to your inventory.
##### Setting up a private region as a race track[β](#setting-up-a-private-region-as-a-race-track "Direct link to Setting up a private region as a race track")
You will need a large region to set up a race track. You can either make your own race region in Unity and upload it, or you can use a home template from the Shop. If you are making your own region for the race track, you will need to upload the region as a home template. To see how to do this, please see our Room Floor Component page and our Regions page. To find a home template in the Shop, go to the Regions tab and you will see all of the home templates we have.
##### Placing the Racing Items in a region[β](#placing-the-racing-items-in-a-region "Direct link to Placing the Racing Items in a region")
You can set up these racing items to make a lap race in your region.
###### Placing the Racing Start Gate[β](#placing-the-racing-start-gate "Direct link to Placing the Racing Start Gate")
You will need to place the Start Gate where you want the race to start. The racers will start on the side of the gate that has the green marks:

###### Placing the first Checkpoint[β](#placing-the-first-checkpoint "Direct link to Placing the first Checkpoint")
Once you have placed the start gate, you can then place the first checkpoint. This is the Racing Lap Checkpoint furniture item. This will need to go after the Starting Gate. Here is an example:

Each checkpoint you place down will be labeled Checkpoint 1 to begin with. You will need to change the checkpoint numbers for the race laps to work correctly. To change the checkpoint number, walk up to the checkpoint you want to change, and you will see a cube. Click on it.

When you click on it, it will open a UI. Here you can enter the checkpoint number.

Click on the Update button to update it to the number you entered.
###### Placing more checkpoints[β](#placing-more-checkpoints "Direct link to Placing more checkpoints")
You can place as many checkpoints as you want in your region, but if you want the race to be more than two laps, make the race shorter by placing less checkpoints. Here is an example of a small lap race:

###### Racing Display[β](#racing-display "Direct link to Racing Display")
Once you have finished placing all of the checkpoints, you will want to add the Racing Display.

The racing display shows a list of the racers, their lap times and how many laps they have done. You can click on Laps to change the number of laps and click on 'Start' to start the race. You can click on 'Reset' after starting the race to reset the times and laps. You can change the race type on the display by clicking on the mode switch button:

The modes are lap mode and race mode. Keep this on race mode for a lap race. If you click on the magnifying glass on the top left of the racing display, this will focus your camera on it so you can read it clearly. You can also see the information on the display by clicking on the yellow arrow:

This will open up the UI on the screen so you can see it while racing.
That is how to set up the furniture as a lap race; Please note that at the moment these racing furniture items only work with modular vehicles. We are currently updating older cars to this new system.
---
### Shooter games FPS
#### Overview[β](#overview "Direct link to Overview")
The First Person Shooter system has been scripted by dotEnterprise, one of the Sinespace community developers, using the Sinespace SDK.
The First Person Shooter system has been scripted by dotEnterprise, one of the Sinespace community developers, using the Sinespace SDK.
You can take these components and build your own projects with them. You can collaborate with other artists and developers building content with these components on the public Sinespace servers. They also provide a useful frame of reference for developing your own unique games and game components using Sinespace and Unity.
The open source FPS components enable developers and artists to create a wide range of highly customisable mutli-player shooting games and maps on the Sinespace platform.
They were created by Ulli at DotEnterprise and can be downloaded here;
Demonstration templates are also found in the Shooter folder in the Sinespace editor pack.
This video provides an overview of the FPS system and how itβs core components can be used to build an FPS in such a way that players have unlimited options for building, customising and sharing their own unique playable maps;
[YouTube video player](https://www.youtube.com/embed/v4M56ovvFp8)
info
See the pages below for more information on the different components:
[The safe zone lobby](/sinespace-sdk/games/the-safe-zone-lobby.md)
[Player spawn points](/sinespace-sdk/games/player-spawn-points.md)
[Guns and gun givers](/sinespace-sdk/games/guns-and-gun-givers.md)
[Health and ammo givers](/sinespace-sdk/games/health-and-ammo-givers.md)
[Traps](/sinespace-sdk/games/traps.md)[King of the hill zone](/sinespace-sdk/games/king-of-the-hill-zone.md)
[Enemy NPCs and NPC spawners](/sinespace-sdk/components/enemy-npcs-and-npc-spawners.md)
---
### The safe zone lobby
#### Overview[β](#overview "Direct link to Overview")
FPS Components Shooter games FPS Player spawn points Guns and gun givers Health and ammo givers Traps King of the hill zone Enemy NPCs and NPC spawners The Safe Zone Lobby is a game lobby inside the region.
###### FPS Components[β](#fps-components "Direct link to FPS Components")
[Shooter games FPS](/sinespace-sdk/games/shooter-games-fps.md)
[Player spawn points](/sinespace-sdk/games/player-spawn-points.md)
[Guns and gun givers](/sinespace-sdk/games/guns-and-gun-givers.md)
[Health and ammo givers](/sinespace-sdk/games/health-and-ammo-givers.md)
[Traps](/sinespace-sdk/games/traps.md)
[King of the hill zone](/sinespace-sdk/games/king-of-the-hill-zone.md)
[Enemy NPCs and NPC spawners](/sinespace-sdk/components/enemy-npcs-and-npc-spawners.md)
The Safe Zone Lobby is a game lobby inside the region. It is where players are moved when they first arrive in the scene and it is where they respawn when they die.
Players cannot shoot or be take damage in the safe zone. Leaderboards, game instructions and other game options can be made available to players in the game lobby.
The core mechanics of the game are governed though the Combat Meter which is part of the Safe Zone Lobby.
The public variables on the Combat Meter allow developers and players to configure game settings including player health and max bullets.
This video tutorial shows how to wire up and publish your own Safe Zone Lobby as a spawnable item players can in place in their own customised multi-player maps in Sinespace;
[YouTube video player](https://www.youtube.com/embed/ZRmO57uyGdU)
##### Combat meter[β](#combat-meter "Direct link to Combat meter")
The core functions of the game are managed by the Combat Meter.
1. Public variables
The public variables can be made available inworld if you want to you can allow individual players to configure these in their regions.
If you want to expose the public variables inworld, when you upload to Sinespace, on the virtual goods component set the Customisation Capabilities to Full. If you want to hide the public variables set the Customisation Capabilities to Basic or Disallowed.
* PlayerSpawnMinRange and PlayerSpawnMaxRange\*\* defines a radius from the centre of the safe zone where players will spawn and respawn. It defaults to 5 meters.
* PlayerMaxHealth\*\* allows you to set the player max health.
* PlayerMaxBullets\*\* allows you to set the max bullets per gun. This is currently a universal value across guns.
* DeathSequenceDuration\*\* sets the time from dying to arriving back at the safe zone. It defaults to five seconds which is time to play a death animation and change camera angles during the player death event.
* TeleportEffectDuration\*\* This sets the amount of time for particles you can trigger when the player teleports from the safe zone to a spawn point in the game.
* PlayerStartHealth\*\* is the amount of health a player has when they spawn into the game.
* Channel.\*\* This is the channel the components communicate on. You should not need to alter this from the defaults.
1. Resources
There is one resource referenced on the Combat Meter; the gunBarIcon. This is a canvas element that sits behind the individual gun icons in the gun bar when players have one or more guns enabled during gameplay.
1. Events
There are seven events referenced on the Combat Meter;
* damage
* die
* teleportStart
* teleportEnd
* AmmoAdd
* hpUp
* showOwnerControl
* npcKill
* avatarKill
* The damage\*\* and **die** events trigger animation events in the Animation Controller attached to the Combat Meter. These events are both canvas based; a damage vignette when the player is hit and a message on screen when they die.
These canvas events occur in parallel with the animations triggered in the playerβs Animation Override, which is part of the gun the player has enabled during gameplay.
* teleportStart\*\* and **teleportEnd** can trigger particles or other events at the Safe Zone Lobby and at the spawn point when a player leaves the lobby and enters the playable map.
* AmmoAdd\*\* and **hpUp** events trigger when the player collects ammo or health from the Health or Ammo Givers.
* showOwnerControl\*\* exposes a canvas based toggle inworld that players can use to disable the game when in room edit mode.
* npcKill\*\* and **avatarKill** are events that can be triggered when NPCs or other players are killed by the player.
1. Object references
The 11 object references on the Combat Meter reference the various active canvas elements in the player HUD. The references do not require manual configuration.
##### Player HUD[β](#player-hud "Direct link to Player HUD")
The **PlayerHUD** presents the number of kills, the health bar, game points and ammo levels. You can move elements on the canvas around, change fonts, colour, etc. to bring the HUD in line with your art.
##### Nav mesh obstacle[β](#nav-mesh-obstacle "Direct link to Nav mesh obstacle")
The **Nav Mesh Obstacle** on the base of the Safe Zone ensures that when a player places the Safe Zone Lobby in their region, any NPCs in the region will not walk through it.
##### Proximity activator[β](#proximity-activator "Direct link to Proximity activator")
The **Proximity Activator** on the base of the safe zone is triggered when the player within a certain radius of it.
It switches the combat HUD off and disables gameplay when the player is inside the Safe Zone Lobby.
It should be set to **Client Only** β if unticked, whenever one player entered the safe zone the game would stop for everyone!
##### Bullet pool manager[β](#bullet-pool-manager "Direct link to Bullet pool manager")
The **Bullet Pool Manager** creates a pool of reused bullets in the viewer, as a more efficient method of managing bullets than creating and destroying individual game objects.
The pool defaults to a pool of 20 bullets. If you are creating a gun with a very high fire rate you might need to expand that pool but we limit network messages to 12 per second so you will hit performance issues if you go too high.
The **poolItemTtl** field is the lifetime of the bullet, in seconds.
##### Owner control panel[β](#owner-control-panel "Direct link to Owner control panel")
The Owner Control Panel allows the map owner to set the Safe Zone Lobby to be inactive while they move it around in the scene and spawn other game items.
---
### Traps
#### Overview[β](#overview "Direct link to Overview")
Traps can be anything in the scene that damages the player. The default template in the sample art package is a fire trap that players can place anywhere in their maps.
The trap system could also be used to create a wide range of other hazards, for instance bombs, or a roving laser cannon as shown in the tutorial video.
The public variables on the trap component include settings for damage amount and damage rate.
This video tutorial shows how to configure and publish your own traps as inventory items that players can place in their multi-player maps in Sinespace:
[Watch on YouTube](https://www.youtube.com/watch?v=PB_Q_jtEK10)
#### Public variables[β](#public-variables "Direct link to Public variables")
The trap has two public variables, **trapDamage** and **trapInterval**. These define the amount of damage the player will take and how often, for as long as the damage trigger is activated β in the case of the default art, by a trigger activator.

#### Events[β](#events "Direct link to Events")
There are four events:
* activateTrap
* deactivateTrap
* damage
* kill

These events allow you to add whatever cosmetic or animated events you want to the trap. In the sample art the activate and deactivate trap events swap between large and small flames, with the flames increasing as you come close to the damage collider.
#### References[β](#references "Direct link to References")
There is one object reference: the proximity activator. This switches the trap on β not to do damage, but to listen for the player. In the sample art this switches on when you get near the damage collider and the particles swap from small to large flames on activation. You do need to retain the proximity activator in the references field.

#### Related[β](#related "Direct link to Related")
* [Shooter Games FPS](/sinespace-sdk/games/shooter-games-fps.md)
---
### Quests
#### Overview[β](#overview "Direct link to Overview")
The quest system allows users to build narrative structures in space.
The quest system allows users to build narrative structures in space.
Usually driven by interactions with NPCs in your regions, quests can lead users through gameplay or learning and training modules, or through tours, stories or other step-based user engagements.
##### Understanding the Quest System[β](#understanding-the-quest-system "Direct link to Understanding the Quest System")
Quests are depicted by a blue exclamation mark above a Quest Giver which can be any type of clickable GameObject (with a collider component).
Clicking on the Quest Giver shows the first Quest Dialog Box (the first Step, numbered 0 in Unity) with a Start / Cancel option.
Quest Dialog Box shows the Name and the Description of the Step (see below).
As soon as the user accepts the quest, next steps are shown as a blue question mark.
On the left of the screen, below the radar, The Quest Name ([Quest Designer Component](/sinespace-sdk/quests/questdesigner.md)) appears with the number of steps and the hint to reach the next step.
Hints are related to a future step the user needs to reach (usually the next step). So the hint needs to be written on the Step the user needs to reach.
For that reason, there is no need to write a hint inside step 0 (the opening step), unless for some reason the quest brings the user back to the Quest Giver.
More to come ...
##### Setting up a quest[β](#setting-up-a-quest "Direct link to Setting up a quest")
The Quest Giver
All quests are started by the user clicking an object, the so called Quest NPC which presents the quest.
The user opts-in to the quest.
To turn any object in your scene into the Quest NPC, add the [Quest NPC component](/sinespace-sdk/components/quest-npc.md) to it.
You can use a humanoid NPC. Use the [Statue component](/sinespace-sdk/components/statue.md) object, rendering the NPC as a character. Then add the QuestNPC component to that.
You can add the [Quest NPC component](/sinespace-sdk/components/quest-npc.md) to any object with a collider on it. The user clicks on that object to start the quest.

Quest NPCs are placed into the *Destination NPC field* in any Step Inspector of your quest (see below).
Quest Manager

Create an empty game object in your scene, set it to location 0,0,0 and add the Quest Designer game component to it.
Give the quest a name and a description.
Quest type
* Daily : users can play it once every day.
* Main : users can play the quest only once.
* Side : can only be triggered by another quest.
* Activity : users can replay continually.
* Temporary : ?
Quest ID
Click the reserve ID button in the inspector to assign a unique id to your quest.
The quest ID is generated automatically when you click reserve.
Warning: DO NOT delete the Quest ID Inspector field. If you don't remember that number, you will need to reserve a new one. If this quest is a used in a dependency list, you will have to edit all the quests that depend on it...
Quest Dependency IDs
You can chain quests together using dependency IDs
Set the size to the number of quests that need to be completed before this quest is available. Hit 'enter' and that number of fields will appear.
To each field, add the individual quest ID of one of the quests that must already be completed by the user.
This allows you to have multiple quests initiated by the same quest NPC, in a series.
Reward ID
Add the curator ID for any virtual good item you have uploaded.
You can get this from the virtual goods component attached to the reward object (once it has been uploaded), or from the item list in your account at curator.sine.space.
The reward virtual good object must be live before it can be given by a live quest.
Open Canvas button
This button opens an Editor Window which allows you to build your quest, adding steps.
Add the first step and reference the Quest NPC object (place the object into the Quest NPC field).
##### Quest steps[β](#quest-steps "Direct link to Quest steps")
You can add quest steps one at a time, building your story.
Each time you add a step it will duplicate your last step.
###### Add a step[β](#add-a-step "Direct link to Add a step")
Open the Quest Designer Canvas. Clic Add Step button.

###### Delete a step[β](#delete-a-step "Direct link to Delete a step")
You can delete a step within a chain; its child will be reconnected to the parent step.
You cannot delete the first step.
###### Reorder a step[β](#reorder-a-step "Direct link to Reorder a step")
Click on the little arrow visible at the top left corner in the step inspector window.
You cannot reorder the first step.
If there are only 2 steps in your quest, you won't see the arrow from the second step.
##### Step Types[β](#step-types "Direct link to Step Types")
###### NPC[β](#npc "Direct link to NPC")
The NPC step type is mandatory for starting the quest. The step 0 will be of type "NPC" and you cannot edit it to make it a different type.
Other steps can be of type NPC: use a GameObject (or any object) and attach the [Quest NPC component](/sinespace-sdk/components/quest-npc.md) to it, placing it in the Destination NPC field.
###### Activity[β](#activity "Direct link to Activity")

The activity step is a general step which you can use to deploy a wide range of activities which the user must complete before the next step initiates.
Activity
You can drag any βStartableβ component into into the Activity field in this step.
The space quest system includes a range of standard startables you might want to use; for example, you might require a user to wear a particular clothing item or sit on a particular furniture item.
For more information on startables go [here](/sinespace-sdk/quests.md).
Scripting your own startables
You can also write your own startables, which can be full game rounds or learning modules; the user has to complete each one before moving on with the quest.
Autoplay
Tick autoplay if you want this step to start immediately as the prior step completes. If you leave autoplay unticked the user will need to click the quest NPC to start the step.
You may need to leave the Autoplay unticked if your prior step is one that is registered as complete at the start of the step and the user will still engaged in an unrecorded activity before needing to move on.
For instance if the prior step was an activity step using the StartableGestureRequirement, the quest system will register the user as having completed the step when they initiate a gesture but that gesture may take 30 seconds to play, during which you may not want the next step to initiate.
Replay Discussion NPC
The Replay Discussion NPC is the object in the scene the user needs to click if they have failed to complete the quest step. This may be because the quest step is a game component which can be failed; or a learning component with a passing grade. Or it may be because they logged out or were disconnected half way through the deployment of the startable.
The replay NPC can be your original Quest NPC but if that is geographically some distance from the relevant quest step you may chose to put another object near the quest step activity which the user can click to restart the step.
This can be any object with the Quest NPC component added to it, dragged into the Replay Discussion NPC field in the step.
Area Hint
If you are using a navmesh to guide your users around the quest, the area hint will tell them where to go. It might usually be the same object as the Replay Discussion NPC but it can be any game object you drag into the field.
###### Quest[β](#quest "Direct link to Quest")

The quest step allows you to embed one quest inside another. This is a great way to move users from one region to another. (You can also use the Quest Game Object component to spawn teleportation portals at the right moment in front of the user, leading them to the next region.)
Subquest ID
Paste the ID of the child quest here.
###### Visit Location[β](#visit-location "Direct link to Visit Location")

The visit location step requires the user to go to a specific place in your region to continue the quest.
Area to Visit
Drag any game object including any NPC into this field to require the user to visit this location before the quest continues.
This step can be used in conjunction with the navmesh to lead them there via a visible path.
For more information on setting up the navmesh in your region go here. (need link)
Proximity (meters)
Set the proximity in meters to the selected game objects.
###### Collection[β](#collection "Direct link to Collection")

The collection step requires the user to click on and collect a specific game object in the scene.
Collectible Item
Add the Quest NPC component to the object you want the user to click on and collect. Drag the object into the Collectible Item field in the quest step. Make sure it has a collider on it so the user can click it.
Area Hint
If you want the navmesh to lead the user to the collectible, you can drag it into the Area Hint field. If you want them to have to search without a hint leave it empty or add your original Quest NPC to guide users back to the quest area in the event they leave the region during this step.
Counter

The counter step requires users to collect a defined number of counters.
Use this step in conjunction with objects in the scene that have either the Quest Counter Clickable or Quest Counter Proximity component attached.
You may also want to use the Startable Timed Counter which offers similar functionality to this step, when added to the Activity step, but on a timed basis.
Number required
Specify the number of counters the user needs to collect. This can match the total number available in the scene or there can be far more in the scene than the required number, depending on the nature of your game.
Quick ID Picker/Token ID
Add whatever ID you have manually applied to the Counter ID field of the Quest Counter Clickable or Quest Counter Proximity component attached to your counters.
Area Hint
Use this in conjunction with the navmesh feature to guide people to an area, or drag your Quest giving NPC here to guide users back to the start of the step should they relog before completion.
###### Conversation[β](#conversation "Direct link to Conversation")

The conversation step allows you to build cut scenes in the quest, with successive combinations of dialogue, camera, audio and animation on the NPC and the player.
To edit the conversation step open the Quest Canvas (from the button at the bottom of the quest chain in the inspector window).
Conversation Actors

The conversation actors can be one or more NPCs and the play themselves.
Add an actor and drag any object with the Quest NPC component attached to it to the NPC Object field.
Actor Name
This will appear in dialogue panels during the conversation.
Is Player
Tick this to use the player as your actor. Add %PLAYER% to the Actor Name field to use the username in dialogue.
Move to location
Add an empty game object in the scene to this field to move your player to this location for the duration of the conversation.
This allows you to align the player with specific camera shots defined by you during the conversation.
Conversation dialogues

Once you have defined the actors in your conversation you can add as many steps to the conversation as you want.
Actor
Choose the actor narrating the dialogue step.
Text
Enter the text as it should appear in the dialogue panel.
Animations
You can add an animation to the NPC or the player during the step.
Wait for continue?
Tick this if you want the dialogue step to remain on the screen until the user clicks continue.
Wait timeout
Define a time in seconds if you want the dialogue to end and the next to start automatically without the user clicking continue.
Camera angle
Create an empty game object in your scene and position it so that it looks where you want the user's camera to look during the dialogue.
You can position your view in the scene view in the Unity editor and then highlight the game object and in the top menu go to GameObject / Align with view to move the position and rotation of the game object to your view.
Dialogue Audio
You can add audio clips to the dialogue by dragging an audio file from your project to this field.
Use Lip Sync
Tick this if you want the mouth of the actor to be animated by your audio file.
Cutscene Dialogue Canvas
To use the conversation step you need to drag the Cutscene Dialogue Canvas prefab into your scene.
This screenspace canvas displays the dialogue during cut scenes and offers the continue button to users if you are using that function in your dialogues.
Make sure the Panel, which is a child of the Canvas, is disabled (the tick box in the top of the Inspector).
This ensures the panel will only be visible to users during the conversation steps of a quest; left on it will be permanently applied to the screen of everyone in the region.
Avoid putting the Cutscene Dialogue Canvas into a parent object, or if you do ensure the parent object is located at 0,0,0 in your scene or the canvas will be offset or invisible to the players.
###### Branch NPC[β](#branch-npc "Direct link to Branch NPC")

Branch NPC allows the user to setup several option for player to choose. It will lead to different quest steps based on the user's choice.
##### Startables[β](#startables "Direct link to Startables")
Startables are components you can drag into the [Activity step](/sinespace-sdk/quests.md) of a quest.
You attach the startable component to the relevant game object; it some cases it might be an empty game object created just to house the startable; and then drag that object into the Activity field of an Activity type step in your quest.
Startable Components:
* [Components/StartableGestureRequirement](/sinespace-sdk/components/startable-gesture-requirement.md)
* [Components/StartableClothingRequirement](/sinespace-sdk/components/startable-clothing-requirement.md)
* [Components/StartableSitRequirement](/sinespace-sdk/components/startable-sit-requirement.md)
* [Components/StartableItemRequirement](/sinespace-sdk/components/startable-item-requirement.md)
* [Components/StartableRoomVisit](/sinespace-sdk/components/startable-room-visit.md)
* [Components/StartableSnapshot](/sinespace-sdk/components/startable-snapshot.md)
* [Components/StartableTeleport](/sinespace-sdk/components/startable-teleport.md)
* [Components/StartableTimedCounter](/sinespace-sdk/components/startable-timed-counter.md)
##### Other Components[β](#other-components "Direct link to Other Components")
###### Quest Counter Clickable[β](#quest-counter-clickable "Direct link to Quest Counter Clickable")

Add the Quest Counter Clickable component to counters the user must click on to collect.
Counter ID
Enter an ID of your own creation to the Counter ID field and add the same ID to the Counter ID field of the Counter quest step or the Startable Timed Counter component.
###### Quest Counter Proximity[β](#quest-counter-proximity "Direct link to Quest Counter Proximity")

Add the Quest Counter Proximity component to counters the user must be within a certain proximity of in order to collect.
Counter ID
Enter an ID of your own creation to the Counter ID field and add the same ID to the Counter ID field of the Counter quest step or the Startable Timed Counter component.
Trigger Distance
Specify the distance from the object that will trigger a successful collection.
###### QuestGameObject[β](#questgameobject "Direct link to QuestGameObject")
This allows you to rez and and derez items in your scene during specified quest steps.
Configurable parameters:
* QuestID
* MinStep
* MaxStep
Attach to other objects (preferably a parent group, if you're updating multiple in a single step)
It enables or disables the object it is on, based on whether the user is inclusively on any step between Min and Max.
Objects can only be seen by the player.
###### PlaceAtOrigin[β](#placeatorigin "Direct link to PlaceAtOrigin")
This will place an object at the origin of the avatar; 0,0,0 relative to that avatar, non-attached.
To offset, place empty parent object with PlaceAtOrigin script and then offset visible object from invisible parent.
###### %PLAYER%[β](#player "Direct link to %PLAYER%")
Use in quest text fields to add player name to dialogue.
###### Replay NPC[β](#replay-npc "Direct link to Replay NPC")
If it's possible to fail an activity step drag the quest NPC into the βReplay NPCβ field. It will show a "!" asking the user to repeat the step.
---
### QuestDesigner
#### Overview[β](#overview "Direct link to Overview")
Create an empty game object in your scene, set it to location 0,0,0 and add the quest designer game component to it.
Create an empty game object in your scene, set it to location 0,0,0 and add the quest designer game component to it.

Click the reserve ID button in the inspector to assign a unique id to your quest.
Click to add a step and give the quest a name.
Quest type
* Daily-users can play it once every day.
* Main-users can play the quest only once.
* Side-can only be triggered by another quest.
* Activity-users can replay continually.
Quest ID
The quest ID is generated automatically when you click reserve.
Quest Dependency IDs
You can chain quests using dependency ID-Set the size to the number of quests that need to be completed before this quest is available. Then add the individual quest ID of each quest that must already be completed by the user.
This allows you to have multiple quests initiated by the same quest NPC, in series.
Reward ID
Add the curator ID for any virtual good item you have uploaded. You can get this from the virtual goods component attached to the object once it has been submitted, or from the item list in your account at curator.sine.space
---
### Two Step Quests
#### Overview[β](#overview "Direct link to Overview")
Two step quests are usually used for creating quests which give out Silver, making item hunts or giving gifts.
Two step quests are usually used for creating quests which give out Silver, making item hunts or giving gifts. Here we will be showing how to set up the quest and how to place a quest like this is a region you upload and also how to make the quest into an item you can upload as a virtual good.
##### Setting up the quest clickable object[β](#setting-up-the-quest-clickable-object "Direct link to Setting up the quest clickable object")
The clickable object is the object the user will click on to receive the gift or silver. You can use any item you want for this.
You need to set up this object so it can be clicked on. The clickable object needs a collider on it, and a Box Collider is fine most of the time for this. Click on the object, and then click on Component, Physics and Box Collider if it isn't already on the object.
Next thing you need to do is add the Quest NPC script to the object. Make sure you have the object selected, and click on Add Component, then search for Quest NPC and add it. This will add the script to the object.

You can check Hide Dialogue for hunts and gift giving quests. Hide Quest Bang can make the quest a little harder as it won't show the quest '!' mark above the quest items.
Next thing to do is add the Quest Designer Script to the object. Make sure it is selected, click on Add Component and search for Quest Designer then add it. The quest designer script is where you can set the settings for the quest.

Quest Name - This is where you will add the name of the quest.
Description - This is where a small description of the quest can go.
Type - This is what type of quest it is. The options for type of quest are:
* Daily Quest - This is a quest which will be active daily, so users can complete this every day they log in.
* Main Quest - This is a quest which will only be available once for the user to complete.
* Side Quest - This is a side quest, which will only be available once.
* Activity Quest - This is a quest used for activities, such as an in-world game or a hunt quest and can be repeated.
* Temporary Quest - This is for a quest which will be temporarily available to users.
Quest ID - This is the ID of the quest. You need to click on Reserve to get the quest ID.
Quest Dependency IDs - You can ignore this for a two step quest.
Suppress reward and end dialogue - Again, we don't need this for this type of quest, but this just stops the reward from being granted.
Reward ID - This is the important thing to note: The reward ID is where you will enter the ID of the reward item. If you are making a repeatable quest, like an activity quest, leave the reward ID at 0, as this will give the user Silver. It will give Silver again after a cool-down period.
Fill in the quest name, description and type. If you want users to be able to get the reward only once, set the type to Main Quest. If you want the quest to be repeated, set it to Activity.
Click on the Reserve button next to the Quest ID to get the ID of the quest.
Click on the Open Canvas button. This will open the quest canvas, and this is where you will add all the details for the quest.
##### Quest Canvas[β](#quest-canvas "Direct link to Quest Canvas")
As said above, this is where you actually add the details for the quest.

As you can see, it has copied over the information from the Quest Designer. But, you still need to add steps to the quest.
Click on the Add Step button, to make the first step in the quest, and then click on the Add Step button again to add the second step. Move the second quest step box over so you can see both boxes.

In the first quest step box, copy the name over from the Quest Name box to the Name box.
In the Dialogue box, type out the dialogue you want the Quest UI to say, for example, if you have set it up to be a hunt quest, you might put something like 'You have found the Easter Egg!'
If you need to put a hint, you can, but this is usually used for longer stepped quests.
In the second quest step box, name it something like Give Prize, then go back to the first step box, and choose the Next Step to be the Give Prize step.
In the second quest step box, check the Supress Nav Line because the user does not need to go to a different location to finish the quest.
In both of the step boxes, set the Destination NPC to be the clickable object you made at the beginning.

You can do this by dragging the item from the hierarchy to the Destination NPC boxes.
Note: Leave the Reward item ID box at 0 if you want the user to get Silver. Leave it blank in both the Quest Designer and Quest Canvas for now if you want to reward the user with an item, as you need to get the ID first.
##### Reward IDs[β](#reward-ids "Direct link to Reward IDs")
If you are making a quest which only gives users Silver, in the Quest canvas and Quest Designer, leave the Reward Item ID at 0.
If you want to give the user an actual item as a reward, you will first need to upload this item. Upload it as you usually would, for example, if it is an item of clothing, upload it using the clothing item settings and the virtual good component. If it is furniture, upload it as a furniture item with the Room Furniture component added to it. If you want it to be spawnable, set it as a Generic upload in the virtual good component.
Once the item is uploaded, take note of the item ID. This is the ID you will need to put in the Reward item ID box.

You only need to put the item ID in the Quest Designer, as it will automatically copy it over to the quest canvas.
##### Uploading the quest as a virtual good[β](#uploading-the-quest-as-a-virtual-good "Direct link to Uploading the quest as a virtual good")
To upload the quest as a virtual good which can be placed anywhere, you need to set it up as a Furniture item. To do this, add the Room Furniture component to the quest object.

You can set the placement of the item to be placed on the floor, walls or ceiling. Under collider, you want to drag the Collider of the object into Main Collider.
Once this is set up, you can add the Virtual good component. Under basic, set the content type to furniture, then give it a furniture category. Usually Decoration is a good category for this.
Fill in the rest of the virtual good, and then upload the item to Sinespace.
##### Uploading the quest within a region[β](#uploading-the-quest-within-a-region "Direct link to Uploading the quest within a region")
To upload the quest within a region, you need to only add the Quest Designer component to the quest clickable object. The Quest NPC can then be any other object in the scene. You can upload the region as you normally would, and the quest will be uploaded in the region.
---
### Regions
#### Overview[β](#overview "Direct link to Overview")
There are different ways to build regions in Space. You can build region assets in other software packages and import them into Unity, you can use Unity's mesh shapes and terrain tools, and you can grab third-party assets from the Unity Asset Store. All of the pages linked here refer to the Scene Export Settings / Scene Save Settings component.


If you want to upload a region quickly, click **File > New Sinespace Scene** in Unity to instantly create a quick-start region.
#### Assemble your scene[β](#assemble-your-scene "Direct link to Assemble your scene")
You can upload any scene you create in Unity as a region in Space. Once your scene is assembled you have two housekeeping tasks.
#### Remove the main camera[β](#remove-the-main-camera "Direct link to Remove the main camera")
When you create a new scene in Unity it will by default have a light and a camera. You need to delete the camera by selecting it in the Hierarchy window and pressing delete.

#### Add a landing zone[β](#add-a-landing-zone "Direct link to Add a landing zone")
You need to define where users arrive when they log in to your region, and what direction they are facing. To do this, once your scene is set up, select **Game Object > Create Other > Landmark** from the top menu in Unity.
If your Scene Hierarchy menu does not include **Create Other > Landmark**, create an empty object, then in the Inspector add a **Landmark Behaviour** component.
This places a new landmark item in your scene. In the Inspector window, set the type to **Landing Zone** and tick **Spawn Point**. The in-scene object is a yellow-edged transparent plane which you can position anywhere in your scene. The yellow arrow points in the direction your visitors will face when they arrive. Be careful to position the landing zone slightly above the terrain; if a tall avatar's feet arrive below the terrain they may fall through.

#### Add a new scene to your region[β](#add-a-new-scene-to-your-region "Direct link to Add a new scene to your region")
This does not apply if you are using Multi-Scene Mode & Multi-Scene Editing. You can have more than one scene in your region.
1. Create a new scene in your current Sinespace project.
2. Double-click the new scene in your Assets to load it into the Hierarchy.
3. Design your scene, and be sure to save it.
4. When ready to upload to the server, click **Space > Scene Settings**.
5. Fill out the needed information and map pictures, then click **Automatic Submission**.
To teleport from one scene to another, see [Teleport World](/sinespace-sdk/components/teleport-world.md).
#### Create a home region or template[β](#create-a-home-region-or-template "Direct link to Create a home region or template")
If you want to make your region a home type, which could be edited by the users themselves, you need to attach a component called **Room Floor** to one of the items in the scene β usually the terrain or the object used as a field. With at least one Room Floor component, the region will show an **Edit Room** button when you are in it. You can add several Room Floor components to different objects; each floor can be shared with another user, giving them the authority to edit it.
In your inventory, you will also find an item with the same name as the region. This is a home template. You can use it in the **Edit Room > Design** function to change the whole set of a region. You can also set a price for it when you upload, so other users can buy it in the shop.
For more advanced settings, see the [post zones page](/sinespace-sdk/regions/post-fx.md) and the [lighting an interior page](/sinespace-sdk/regions/lighting-an-interior.md). You can also see how [Navigation Bake](/sinespace-sdk/regions/navigation-bake.md) works, and we have information on [Occlusion Bake and culling](/sinespace-sdk/regions/occlusion-bake.md). There are also some handy [lighting tips](/sinespace-sdk/regions/lighting.md).
---
### Creating a Scene
#### Overview[β](#overview "Direct link to Overview")
For creating anything in space, apart from clothing items, you will need to use the scene option in Unity.
For creating anything in space, apart from clothing items, you will need to use the scene option in Unity.
Scenes are where you place all of the game objects you are going to use for making regions, in world games or UI elements for space.
#### Starting a New Scene[β](#starting-a-new-scene "Direct link to Starting a New Scene")
To start a new scene, go to File, and choose New Scene. This will leave you with an empty scene apart from the main camera.
#### Building your Scene[β](#building-your-scene "Direct link to Building your Scene")
You will want to add items into your scene which you will need and want for the item you are making. For example, if you are building a new region, you will want to add in terrain and objects for your region such as furniture, or trees, or buildings.
#### Saving your Scene[β](#saving-your-scene "Direct link to Saving your Scene")
When you choose a New Scene, you will want to make sure you save the scene for later changes. To save your scene, go to File, and click on Save Scene, or Save Scene As. You can name your scene, and save it to your Unity Assets folder. When you save it to the Assets folder, this will mean that the scene is in your project window and is easily found whenever you open your Unity project.
#### Opening your Scene[β](#opening-your-scene "Direct link to Opening your Scene")
To open your saved scene, double click on it in your project window, and this will open the scene with all of the game objects you placed in the scene window.
---
### Creating Terrain
#### Overview[β](#overview "Direct link to Overview")
All About Terrains In Unity you can hand craft your terrain or use a terrain generation tool.
#### All About Terrains[β](#all-about-terrains "Direct link to All About Terrains")
In Unity you can hand craft your terrain or use a terrain generation tool. This article will offer learning resources for both methods and some terrain tips.
If you wish to handcraft your terrain or even if you're using a terrain generation tool itβs a good idea to have an overview of how Unityβs terrain engine works.
Unity Manual β Terrain: [Terrain Unity Manual](https://docs.unity3d.com/Manual/terrain-UsingTerrains.html)
Videos: Search for Unity3D 5 terrain tutorials. Recommended videos: Wicked Cat: [Terrain Wicked Cat Studios](http://youtube.com/watch?v=fuEoYM9BDDI) Check the dates of the videos view the newer ones.
#### Terrain Generation Tools[β](#terrain-generation-tools "Direct link to Terrain Generation Tools")
On the Unity Asset store there are several tools to generate your terrain automatically or with various degrees of control.
Gaia -
World Creator -
MapMagic World Generator -
GeNa -
Landscape Auto Material -
And if you like to sculpt your terrains out of mesh, here is a popular utility:
Please check the ratings and read the reviews, also look at when the package was last updated.
#### Terrain Optimization[β](#terrain-optimization "Direct link to Terrain Optimization")
Here are some articles on terrain optimization.
3D Ace:
Here are two articles on optimization, please note there are scripting portions that you can ignore unless you are going to be using the space SDK.
Last tip can be found on the Gaia website:
---
### Creating Web GL Friendly Regions
#### Overview[β](#overview "Direct link to Overview")
While making regions for Web GL, there are a few things you need to bear in mind.
While making regions for Web GL, there are a few things you need to bear in mind. Web GL is specifically made for running applications in browsers, so it has a lower standard for graphics than the actual sinespace client. This means the regions you create will need to stick to a few rules to make sure it runs smoothly in the browser.
1\. Regions need to be a light build. Anything up to 30MB is fine to run in a web browser.
2\. Test the region to make sure it can hold 10-12 avatars without crashing.
3\. Try to make objects plain, or add low resolution textures. Maximum resolution for normal textures needs to be 512x512. For billboards, this can go up to 1024x1024.
4\. Use the Unity Legacy shader instead of Unity Standard shader.
5\. Use baked lighting if you want to add shadows. These shadows will be static shadows, but this will stop lag in the region.
6\. Special effects and animations can be used in the region, but keep the count to 4-5 of them.
---
### Export Settings
#### Overview[β](#overview "Direct link to Overview")
Note: It is highly recommended to create a new region by Quickstart function.
Note: It is highly recommended to create a new region by Quickstart function. You can access the Region creation quickstart by accessing the menu sinespace -> About Editor Pack, then create a region. All the basic settings are include when you create a region by quickstart.
##### Overview[β](#overview-1 "Direct link to Overview")
Click the Scene Export Settings in the hierarchy, and in inspector, find the Scene Save Settings(Script) component.

You can set a splash image and an icon for the loading or preview screen, and also some other settings which affect the base environment of the region.
###### Restrictions & Features[β](#restrictions--features "Direct link to Restrictions & Features")

Here is some basic function settings which you can disable, like fly, run, and value like edge of bottom ,limit of vehicle speed. You can leave it as default if you don't have specific demands.
###### Region Mode[β](#region-mode "Direct link to Region Mode")
The Region Mode defines how your region content is received by your visitors; all at once before they log in, or progressively after they arrive.

*Please note that except Single scene option, all the other options are still experimental, they may have strict limits to make them working.*
**Single scene**
Single scene delivers the entire region to the user as a single file which downloads before their avatar spawns. For regions with download sizes up to 100 mb, Single scene is likely to be an acceptable download time for your visitors. Recommended sizes are around 30-50mb.
**Multi bundle**
Multi bundle is a form of dynamic loading control (content streaming). It splits your scene into smaller components that are streamed to the visitor progressively.
The multi bundle algorithm examines every root object in your scene and compares each with every other root object. It then bundles objects where there is more than 40 kbytes of overlap in shared data between them. These will be delivered to the client together.
How you group into root objects has a big factor on how we create bundles; for instance grouping all vegetation or grouping one particular building where users will arrive is a good practice.
Too many bundles (i.e. hundreds) will cause brief stuttering for the user while they are unpacking after loading. A reasonable target is 20 β 30 bundles. You can control this through the number of root objects in your scene when uploading.
*Note on inter-object links: Inter-object links between objects loaded at different times may break in this export mode - if objects are linked together (e.g. proximity components) make sure they have the same root object*
**Requiring elements before scene is entered**
When you are using Multi bundle mode you need to select one item in your scene, usually the terrain, and add a component to it called Manual Loading Control or Dynamic Loading Control. Then tick Required Download. This will ensure that the item is sent to the user before their avatar spawns. Without this there is a risk users will arrive and drop through space before your scene loads above their heads.

**Additive scenes**
Additive scenes is a Unity utility that allows you to organise a single region into multiple scenes. You can manually split content, creating a root scene containing occlusion, lightmap and navigation data, with additional scenes loading the content progressively. You will need Unity 5 multi scene tools to manually set this up. You should have your 'Scene Save Settings' in your root scene when packaging for upload - additionally the currently active scene at time of upload, is treated as the root scene.
For more information, see;
*Note: currently the Additive scenes only support 3 scenes at most.*
**Single Scene Streamed**
Currently still under testing. Closed to public by server side.
###### Suggested memory[β](#suggested-memory "Direct link to Suggested memory")
If your guest's device has less memory (RAM) than this, they will be given a performance warning when entering the region. This mostly affects clients logging in via WebGL or Mobile.
##### Loading Screen & Explore Window[β](#loading-screen--explore-window "Direct link to Loading Screen & Explore Window")
The world map allows users to search and browse regions. The Preview Image you supply will be used as a background to preview your region in the World Map. It will also be used as the background while the region itself is loading.
* Preview image
The image you provide should be a .jpeg file. A 2:1 aspect ratio is recommended. Because the image is stretched to fit different screens it will distort slightly for some users.

* Loading logo
The Loading Logo Image appears on top of the Preview Image and is not stretched, allowing you to present your brand logo or a region specific title without distortion.
The image you supply should be a .png file with 512x256 dimensions. When you import the .png file, ensure the Alpha is Transparency box is ticked;

##### Platform Settings[β](#platform-settings "Direct link to Platform Settings")

The platform settings are some performance related controls for different platforms. If you want to make your region has a better support of some low spec platform, like mobile and webGL, you may need to limit some options to improve the performance.
Check here for more info about platform settings: [Regions/Platform Settings](/sinespace-sdk/regions/platform-settings.md)
##### Tools and Reports[β](#tools-and-reports "Direct link to Tools and Reports")


The reports show some statistic info and script used in this region, and the tools offer some little functions to optimize or control the files needed to upload.
For more informations about these tools and reports, check this page: [Regions/Submission](/sinespace-sdk/regions/submission.md)
---
### Furniture Samples
#### Overview[β](#overview "Direct link to Overview")
Here are some furniture samples you can use for learning how to upload furniture, or you can use them to make variations of colors and styles!
Here are some furniture samples you can use for learning how to upload furniture, or you can use them to make variations of colors and styles!
[Furniture Samples](http://space-files.s3.amazonaws.com/wiki%20resources/SWE%20Room%20Furniture%20Samples.unitypackage)
These samples are collected as a Unity Package. To add them to your Project after downloading, open the Unity Project you have the Sinespace pack on. Right click in your Project Window, and choose 'Import Package>Custom Package'.
Choose the downloaded Furniture Samples package, and it will add it to your Project window. You should see this:
---
### Lighting
#### Overview[β](#overview "Direct link to Overview")
Sine.Spaces uses Deferred rendering. So you can use as many lights as you wish.
Sine.Spaces uses Deferred rendering. So you can use as many lights as you wish.
Space also implements dynamic environmental lighting and effects, using a [custom skybox shader](/sinespace-sdk/scene-authoring/custom-skybox-shader.md) and [day/night cycles](/sinespace-sdk/components/day-night-cycle.md).
Below is the Unity5 documentation for scene lighting. It's a bit long but worth the read.
\[[Lighting a Scene](https://unity3d.com/learn/tutorials/topics/graphics/unity-5-lighting-and-rendering?playlist=17102)]
Here is a video on the basics of light.
\[[Basic Lights](https://unity3d.com/learn/tutorials/topics/graphics/using-lights?playlist=17102)]
***
##### Baking Your Lighting[β](#baking-your-lighting "Direct link to Baking Your Lighting")
Baking your lighting will help with overall performance.
1. Make sure any objects that are not moving are set to static, you will find the tickbox upper right
corner of the inspector when you select an object.
2. If the object moves in any way leave it unchecked.
3. Go to Window > Lighting
Be sure the following are checked:
```text
Precomputed Realtime GI
Baked GI Setting
Select the Baked option under Ambient GI drop-down box.
Set your Baked Resolution between 8 - 15, the larger the scene the lower the number here.
```
To have lights show on moving objects and avatars you will need to use Light Probes.
1. Create and empty game objects.
2. Add the Probe Drop Plane component.
3. Move this grid with globes to the top of your scene, the object is to scale it so it covers
the overall area of your scene. So over buildings, larger objects.
4. Adjust the Density Setting in the Drop Plane so the globes are evenly covering your scene.
If its darker add a bit more then if a scene is well lit.
5. Click Update and the drop plane will expand.
Note: If you have additional dark corners, you may wish to add more manually
using an empty game object attach the component Light Probe Group moving one probe into
the dark area and one nearby in the lit area to reflect off each other.
When you have everything set up click 'Build' this can take quite awhile a suggestion is run it overnight.
---
### Lighting an Interior
#### Overview[β](#overview "Direct link to Overview")
The Sinespace platform provides virtual world creators with lighting tools that can create a wide variety of atmospheric spaces.
The Sinespace platform provides virtual world creators with lighting tools that can create a wide variety of atmospheric spaces. There is no single right way to light a region, and getting the right result can take a few attempts.
This guide uses the Mirage demo scene as an example of combining real-time and baked light types.
[Download the Mirage scene](http://space-files.s3.amazonaws.com/sample-art/Mirage-Region.unitypackage)
#### Baking and Lightmaps[β](#baking-and-lightmaps "Direct link to Baking and Lightmaps")
Each light in a scene is either baked or real-time. Most light types, with the exception of area lights, can be either.
Real-time lighting affects in-world performance. Baked lighting increases upload size. In the Mirage demo scene, the creator used a combination of real-time and baked lighting.

#### Ambient and Directional Light[β](#ambient-and-directional-light "Direct link to Ambient and Directional Light")
When you create a new scene in Unity, it has two light sources by default:
* Directional light
* Ambient light
##### Directional Light[β](#directional-light "Direct link to Directional Light")
A directional light is an object in the scene that you can rotate like any other object. It casts shadows in the direction you rotate it.
For the Mirage scene, the directional light has been deleted. Directional light is often used as sunlight in an exterior scene. In Mirage, shadows are cast by the point lights in each room.

##### Ambient Light[β](#ambient-light "Direct link to Ambient Light")
The ambient light has no source object in the scene. Modify it from **Window > Lighting** in Unity.
In this scene, the ambient source is the skybox. The skybox color range informs the ambient light in the scene. You can also use a flat color source or gradient options. The skybox option works well in Mirage, but it may not fit every region.

#### Adding Lights to a Scene[β](#adding-lights-to-a-scene "Direct link to Adding Lights to a Scene")
You can add lights and light probes from **Create > Light** in the scene hierarchy. Keeping "light" in the names of your light objects makes them easier to find in the hierarchy.

#### Area Lights[β](#area-lights "Direct link to Area Lights")
Area lights are used in this scene to project different tinted light from a plane into each room.
Area lights are efficient, but they do not cast shadows. They are baked only. The direction of the light from the plane is indicated by the yellow line.

#### Point Lights[β](#point-lights "Direct link to Point Lights")
The hanging lights in the Mirage scene are mesh lamps on the walls and ceilings, with point lights attached.
Point lights emit light in all directions over an area visible as a wireframe sphere. In this scene, the point lights are set to real-time and create dynamic shadows on avatars and other non-static objects. The hanging lights also have a halo component to provide a simple visual indication that they are light sources.
The Mirage scene also contains one baked point light, called `CenterLight`. The creator used a wide-area baked point light because an area light on the ceiling would have weakened the shadows cast by the other ceiling and wall lights.

#### Spot Lights[β](#spot-lights "Direct link to Spot Lights")
Spot lights project light from a cone point. In the Mirage scene, they illuminate the NPCs showcasing clothing items. They are set to real-time and project NPC shadows onto the back wall.

#### Emissive Surfaces[β](#emissive-surfaces "Direct link to Emissive Surfaces")
The light circle in the center of the main room uses meshes where the Standard Shader is set as emissive, making the mesh appear to radiate light.
If the emission value is between 0 and 1, the mesh surface appears to be a light source but does not actually emit light. If one or more color channels are set above 1, the mesh surface emits faint HDR light. This can work well for LEDs and small light piping, and can contribute to light bounce off shiny surfaces.
Emissive surfaces are only applied to static objects and only for baked lighting.
note
Emissive surfaces may generate artifacts on materials with detail maps when viewed in WebGL.

#### Light Probes[β](#light-probes "Direct link to Light Probes")
Light probes sample the combined lighting in the scene and let moving objects, especially visiting avatars, be lit by baked light sources that would otherwise only affect static scene components through lightmap textures.
Place as many or as few light probes as your scene needs. Aim to place them where different light sources overlap. In this scene, the creator focused on light probes at head height, especially around the intense lighting in the fashion studio.
note
You can toggle light probe visibility from the Gizmos menu above the Scene view.

#### Baking the Scene[β](#baking-the-scene "Direct link to Baking the Scene")
Once your light sources and light probes are laid out, and all static objects that form the fabric of the scene are in place, bake the scene before submitting it to the server.
Baking is triggered from the **Build** button at the bottom of the Lighting window. It may take a while to complete, and it takes longer when the baked resolution is higher. Unity defaults to 50 texels per unit; this scene used 20 and could probably have gone down to 10 without a significant visual change.
After the bake completes, Unity creates lightmaps for your scene. These are uploaded automatically when you submit the scene to the server. The lightmaps are then blended with the scene textures to create the final look.
When you bake the scene, Unity also applies light information to light probes and reflection probes. You can also bake ambient occlusion and reflection probes as part of the same process.

---
### Management
#### Overview[β](#overview "Direct link to Overview")
Preview and Live Servers When you upload a region, the region will go through the upload process.
##### Preview and Live Servers[β](#preview-and-live-servers "Direct link to Preview and Live Servers")
When you upload a region, the region will go through the upload process. You can check on it's progress on Curator. When it's uploaded, it will be on our preview server.
Regardless of your subscription level, you can upload as many regions as you want to the preview server.
Once on the preview server you can preview your region. If you are happy with it, you can 'Send it to Review' via curator and it will be reviewed by our review team. This review is to ensure the maturity ratings are appropriate and that nothing in the scene could crash the servers or severely impair performance for other users.
If you have a Level 5 subscription you can bypass this manual review and push directly to the live servers yourself.
Your subscription level determines the number of regions you can release concurrently on the live server.
##### Region Info Panel[β](#region-info-panel "Direct link to Region Info Panel")
When you are logged in to any region you can click the minimap in the top right corner to open the Region info panel for that region.

##### Region Access[β](#region-access "Direct link to Region Access")
If you are the region owner you can then modify the access permissions;

You can set the region to be public, limited to your friends or limited to specific individuals who you approve.
##### Approve Users for Region Access[β](#approve-users-for-region-access "Direct link to Approve Users for Region Access")
Any user can request access to one of your private regions;

You can approve or reject their application.
##### Members[β](#members "Direct link to Members")
In the members panel you can see who currently has access to the region and you can modify their permissions on an individual basis.

##### Multiple Region Management[β](#multiple-region-management "Direct link to Multiple Region Management")
Your subscription level sets the number of concurrent regions you can deploy on the live servers.

You can upload as many regions as you want to, and then enable or disable each region to set which ones are live at any time;

---
### Navigation
#### Overview[β](#overview "Direct link to Overview")
Navigation You can walk around Space by clicking the ground in front of you, or using arrow keys/WASD to move and rotate.
#### Navigation[β](#navigation "Direct link to Navigation")
You can walk around Space by clicking the ground in front of you, or using arrow keys/WASD to move and rotate.
If the region using default settings, you can fly by clicking F then use
E to hover up C to hover down
Or Page Up / Page Down
Then use arrow keys or WASD to fly around.
1. Camera Controls
Hold your right mouse button down and move your mouse to look around. Use your mouse wheel to zoom.
1. Run/Fly Fast
Hold down SHIFT to run instead of walk when you use WASD or arrow keys. You will also fly faster if you hold down SHIFT.
---
### Navigation bake
#### Overview[β](#overview "Direct link to Overview")
The NavMesh function in Unity can help you define your region where is walkable and where is not, so if you have an auto-walk function for player or NPC, it can automatically calculate the routes.
The NavMesh function in Unity can help you define your region where is walkable and where is not, so if you have an auto-walk function for player or NPC, it can automatically calculate the routes.
If you are interested in how to fully use the NavMesh function, please check [official tutorial of Unity](https://unity3d.com/cn/learn/tutorials/topics/navigation/navigation-overview?playlist=17105%7Cthe).
Here, we will only introduce some basic methods.
As an example, I created a region with some simple objects as obstacles.

##### Create a NavMesh Map[β](#create-a-navmesh-map "Direct link to Create a NavMesh Map")
First, Click the menu Window -> Navigation to call out the Navigation window(In Unity 2018, it's in Window -> AI -> Navigation). There are four tabs in Navigation Window: Agents, Areas, Bake and Objects.
The Agents tab is a place to record profiles for different parameters, when you attach Nav Mesh Agent component to a character, you can choose the agent profile you set in the agents tab.

The Areas tab is for define the layers of navigation. There is already 3 built-in layer: Walkable, Not Walkable and Jump. You can always add new layer if you need. The Cost defines whether the layer is hard to walk or not -- more cost, much harder. Normally, the Auto-walk will always choose a path with lower cost.

The Object tab is to set the navigation parameter for the objects in the scene. The 3 filters, All, Mesh Renderers, Terrains can help you to find the objects, and if we need to set an object walkable or not, pick the checkbox Navigation Static, then choose its layer. If you want set it jumpable, for example: jump across a gap between two platform, of jump down from somewhere high, you should also pick the Generate OffMeshLinks checkbox then choose the Jump layer for Navigation Area.

The Bake tab includes all detail settings here. The Agent Radius defines the width of character and how narrow the path it could pass. Agent Height stands for the height of character, so if there is a height limitation area, the character shall not pass. Max Slope defines the maximum angle the character can move on, and objects lower than the step height will not be considered as an obstacle. Drop Height is the maximum height which the character can jump off, and jump distance is a horizontal distance which the character can jump across.

When all the settings are done, you can click the Bake button to generate the NavMesh Map. When it's complete, the Scene window will display the Navmesh map.

The NavMesh jumpable with off-Mesh links will have an arrow and circle like this:

##### Create a NPC moves in control of NavMesh[β](#create-a-npc-moves-in-control-of-navmesh "Direct link to Create a NPC moves in control of NavMesh")
You will need a lua script to set an object moving through the NavMesh. Here, I'll show you a simple example.
First, create a capsule as the character we want to move in the baked scene, then add the component "Nav Mesh Agent" to it.

Choose the profile you set in the Navigation window, and set other parameters as you want or just leave it as default -- if you wonder each parameter is for, check the link of tutorial above.
Create an empty object and move it to the destination you want to set for the move. Change the object's name to something easy to find in script, like here, I name it as "dist".

Now add the lua script to the capsule. Add the "Scripting Runtime" component to it, then write the code like the image below:

*The line "Space.log(agent);" isn't necessary, it's only a log to make sure the script is working.*
You can add an clickable activator to active this script when click the capsule, or it will start moving automatically.

Here is a GIF which shows you the result of NavMesh move.
---
### Occlusion bake
#### Overview[β](#overview "Direct link to Overview")
Occlusion Culling is a Unity function which can disable rendering of objects when they are not currently seen by the camera if they are occluded by other objects, which can save time from rendering.
Occlusion Culling is a Unity function which can disable rendering of objects when they are not currently seen by the camera if they are occluded by other objects, which can save time from rendering.
You can get the details of advanced operation from the [Documentation](https://docs.unity3d.com/Manual/OcclusionCulling.html%7CUnity).
Here we only use a simple example to show you how to use this function in Sinespace.

This is the overview of a new created region. You can see there is a big cuboid and a small cube, where the small cube is occluded by the big cuboid from the view of camera, and the big cuboid is combined by 3 big cubes.
Now in menu, click Window -> Occlusion Culling to open the Occlusion window(In Unity 2018, it's Window -> Rendering -> Occlusion Culling).
There are 3 tabs in this window, object, bake and visualization.
In Object tab, you can set objects Occluder static and Occludee static. Occluder static means this object can occlude other smaller objects which has occludee static parameter checked.

You can also use the option "static" in the right-top of the Inspector window. Set the objects Occluder static and Occludee static here:

It's same as the operation above. Choose the method which you prefer.
When you finished setting the objects occluder or occludee, you can bake the scene to calculate the occlusion data.

The default settings here normally is enough for most situations. If you want to adjust them, check the Unity documentation(link mentioned above) for the details of each parameter.
The occlusion volume will show after bake.

Then you can test the result in Visualization tab, if every thing is correct, when you focus on the camera, the small cube behind the big one will be invisible.

A region with occlusion culling is complete. Remember delete the camera for test before uploading your region.
Does it really work in Sinespace?
Yes, the occlusion culling in your region will be the same as the result you tested in Unity. It may be hard for normal user to find it out, so here I present some images from the developper:


The image above is the game view of the client. And switch to the scene view(image below), you can see the small cube is invisible in visualization mode, proving the occulision culling does work with Sinespace.
If we move around, to the side of one big cube, where we can see the small one, like in the image below:

As you can see, the small cube can be seen now, but 2 other big cubes are invisible because of occluded by the one close to the Avatar.
As a conclusion, if you want to make your region more friendly to low-end PC or webGL, mobile platform, use occlusion culling to your region -- just set the static objects occluder and occludee, bake it with default settings, that's all.
---
### Pets
#### Overview[β](#overview "Direct link to Overview")
\== IMPORTANT!!! == THIS IS A QUEST FOR WILDLANDS REGION ONLY - PETS ARE ONLY AVAILABLE TO USE WHILE IN WILDLANDS REGION Obtaining a Pet You can obtain a pet by completing Joen's qu
#### Obtaining a Pet[β](#obtaining-a-pet "Direct link to Obtaining a Pet")
You can obtain a pet by completing Joen's quest in Wildlands, buying eggs from vendors in Wildlands and you can also buy rare species in Neon. After you have obtained a pet, you can see all of their details under the PETS button at the bottom of the screen. Please note pets are only active while in the Wildlands region.
#### Feeding your Pet[β](#feeding-your-pet "Direct link to Feeding your Pet")
Pets will get hungry and need feeding. You can feed your pet by finding food for them, or buying the food from vendors. Click on the PETS button, click the pet you want to feed and click the FEED button to give them food. Each species of pet will eat different types of food, for example, Parricans eat berries.
#### Aging your Pet[β](#aging-your-pet "Direct link to Aging your Pet")
Your pet can be aged from an egg into an adult by using a Maturation Potion. Under the PETS button, click on the egg you want to age, click on USE ITEM and click on Maturation Potion. The potions can be bought at a potion vendor in Wildlands.
#### Mutagems[β](#mutagems "Direct link to Mutagems")
Mutagems can be bought at a Mutagem vendor in Wildlands.Mutagems are used to change the base genetics of your pet. Mutagems can be used by clicking on the PETS button, clicking on the pet you want to change, and clicking on USE ITEM and then clicking on Mutagem. There are different types of Mutagems:
Coloured- These gems can change your pets appearance, for example, buying a Huge Pink Mutagem gives a higher chance of changing your pets colour to pink.
Colourless - Colourless mutagems will remove a colour from your pet and return it to its original base colour. Different types of colourless mutagems affect different parts of your pet.
Shaped - Shaped mutagems can help change the size or weight of your pet. Rare special shaped Mutagems can change certain pet traits, such as wing length or eyebrow length.
#### Habitats[β](#habitats "Direct link to Habitats")
Your pets will need a place to live and breed. These are called Habitats, and you can buy these from a Habitat vendor in Wildlands. You can place your pet in the Habitat by clicking on the PETS button, clicking on the creature you want to move to the habitat, and clicking on PLACE INTO HABITAT. If you have a higher end habitat, your pets will be automatically fed whilst in the habitat using the inbuilt autofeeder. Habitats also serve as a place for breeding; If you place an adult female and male of the same species into your habitat, they will breed and give you new eggs!
#### Breeding[β](#breeding "Direct link to Breeding")
Your pets are breedable! If you want to breed your pets to give you new eggs, you need to first click on the PETS button, and find a male and female pet you want to breed. They must be the same species to breed. Click on the male, and add him to a habitat by clicking PLACE INTO HABITAT. Do the same for the female. Make sure they are both adults, otherwise they cannot breed, and also make sure they are fed. Give it a little while, and you will have a new egg under the CREATURES button in your pet libary!
#### Equipping your pet[β](#equipping-your-pet "Direct link to Equipping your pet")
You can equip your pet by clicking on the PETS button, clicking on the pet you want to equip and click the EQUIP button. This will allow your pet to visible in world right next to you, and follow you around! If you want to unequip your pet, click on the PETS button, click on the pet you have equipped, then click on UNEQUIP.
#### Releasing your pet[β](#releasing-your-pet "Direct link to Releasing your pet")
If you don't want to keep a particular pet anymore, you can release your pet into the wild. To do so, click on the PETS button, find the pet you want to release, click on them and then click on the RELEASE CREATURE button. A window will appear to ask you whether you want to release pet or keep pet, just in case you change your mind.
#### Pet Battle[β](#pet-battle "Direct link to Pet Battle")
Your pet can be placed into combat! Find an arena (These are marked by vendors with crossed swords above their heads; One is in Wildlands and one is in Sol) and click on the vendor. They will ask you if you want your pet to fight. Once in combat, you can choose different types of attacks by clicking the attack buttons on the left hand side of the screen. Your pets health and stamina will be displayed underneath the attack buttons, and the opponents health and stamina will be displayed on the right hand side of the screen. You will gain XP from the fight if you win or lose.
---
### Platform Settings
#### Overview[β](#overview "Direct link to Overview")
Attention: This is now listed under the Scene Settings in Unity Supported platforms The platform settings allow you to fine tune your region for each platform you want to publish to.
Attention: This is now listed under the Scene Settings in Unity
##### Supported platforms[β](#supported-platforms "Direct link to Supported platforms")
The platform settings allow you to fine tune your region for each platform you want to publish to.
Space currently supports;
* Standalone - Desktop application, PC or Mac
* Mobile / tablet - Android or iOS
* WebGL - Chrome, Explorer, Firefox and Edge
* Console - Sine Wave Entertainment is an accredited developer for Xbox and Playstation. The company is planning to release on these platforms later in 2017 after building a user interface for game controllers.
\\
##### Settings[β](#settings "Direct link to Settings")
The default settings are designed to work for most regions.
Scene adjustment
* Remove lightmaps / light probes / reflection probes
Removing lightmaps and probes can significantly reduce download speed but will also impact on the runtime performance.
More information;
Lightmaps Light probes Reflection probes
* Static bake meshes / colliders
Ticking these boxes will prebake data before export. This improves loading performance but the region download will be bigger.
More information;
Static bake meshes Static bake colliders
* Strip occlusion / navigation data
Occlusion data holds information about what areas are visible from other areas; it allows the viewer to make intelligent decisions about optimising a scene, however it can add several mb of size to both runtime memory use; and download size. Keeping it improves performance but can result in higher memory use in big scenes.
Navigation data is used for showing waypoints, and moving NPCs around in a scene; it uses a little bit of extra memory, and can be stripped out if you are under severe memory pressure.
Texture size reduction
* Max texture resolution
All textures will be reduced to a maximum of the defined size for each build.
* Texture reduction levels
Reduces textures all by a multiple of the original, in line with Max texture reduction above.
So; if your scene contains large textures at 1024x1024 and you set the max texture reduction to 512 those large textures will be reduced by a factor of 4.
If you then set Texture reduction levels to 1, smaller textures in your scene will also be reduced by a factor of 4; so a 512x512 texture, which otherwise would have been unchanged by the Max texture reduction, would also be reduced by 4, to 256x256.
If you set the Texture reduction level to 2 it will multiply the Max texture reduction scale by 2; so in the case above reducing the smaller 512x512 texture by a factor of 8, to 64x64.
* Normal reduction levels
This will apply a further multiplicative reduction on normal maps on top of the reduction already applied by the Texture reduction level above.
Texture compression
* Allow crunch / Crunch level
Allows JPEG compression to be added to all textures in addition to DXT compression. This will degrade the quality of your images as the compression is lossy; but significantly reduces download filesize. It does not improve runtime memory size except during loading. Crunch level runs from 0 (very lossy) to 100 (lossless).
* Compress textures
This applies a further quality reduction, comparable to the quality slider in Photoshop when saving a jpeg file.
* True color As 16
Interprets images stored as 'True Color' to 16-bit colors. This applies compression to the colors, without introducing the blurriness / artefacts that DXT compression can introduce; at the expense of being slightly larger. With this ticked, any image with 'True Color' compression, will be packed at 16 instead of 32-bit on this platform.
Audio settings
* Force audio to mono
Converts stereo files to mono for that platform.
* Audio bitrate
This is a percentage field. So whatever the bitrate of your original files, you can reduce by X% for each of the different platforms you publish to. For instance a set of 128 bitrate original files, left at 100% in the Standalone build can be reduced to 64 in Mobile and WebGL builds by setting this field to 50.
---
### Portal
#### Overview[β](#overview "Direct link to Overview")
Made of light foam or fibers stitched to the underside of the ticking, it provides a tender surface texture to the mattress and could be found in various degrees of firmness.
Made of light foam or fibers stitched to the underside of the ticking, it provides a tender surface texture to the mattress and could be found in various degrees of firmness.
When you love some extra consolation, this is able to be a wonderful choice for you as an extra layer of upholstery is added to your mattress for a comfortable and cushiony feel.
For an opulent, restful sleep, you need a excessive-quality and supportive mattress from a brand you can belief.
And though it could trap warmth for some, the mattress sleeps comparatively cool in comparison with other all-foam beds.
Sam's Club presents you a [Learn This..](http://wuguu.com.tw/comment/html/?0.html) variety of choices when it comes to the size of mattresses.
---
### Post FX
#### Overview[β](#overview "Direct link to Overview")
You can use PostZone(Post Processing)Component to add/change postFX in your region.
You can use PostZone(Post Processing)Component to add/change postFX in your region. PostZone can be applied to a part of the region or the entire region.
##### Adding PostZone[β](#adding-postzone "Direct link to Adding PostZone")
To create a PostZone, create an empty object in your scene, then click on add component, search and select PostZone.
If you want part of a region to have different postFX, then add a box collider to the EmptyObject with PostZone and size according to the area needed.
For example you can have different postFX for interior and exterior areas of a region by adding different postZone and sizing the collider to the size of the area.
##### PostZone Technical Details[β](#postzone-technical-details "Direct link to PostZone Technical Details")
You can learn more technical Details on Post Processing [here](/sinespace-sdk/scene-authoring/post-processing.md).
---
### OpenSimImport
#### Overview[β](#overview "Direct link to Overview")
This workflow imports regions created and archived with Open Simulator into a Space project. It is intended for advanced Unity, Space, and Open Simulator users.
#### Before you begin[β](#before-you-begin "Direct link to Before you begin")
**Level:** Advanced Unity/Space, advanced Open Simulator operations.
**Goals:** Import regions created and archived with Open Simulator into a Space project.
**Requirements:** The utility this workflow is based on is a Windows-only program at this time, so a reasonably resourceful Windows desktop is required. You will also need a region archive created with an Open Simulator instance to import into your Space region.
warning
The import utility software described here was not produced by the Sine Space team, and is not officially supported. Your mileage with this software may vary β use at your own risk. This workflow description is provided for guidance only. Obtain any support required for the utility from its authors.
There are two primary steps to this workflow.
#### Opening the archive[β](#opening-the-archive "Direct link to Opening the archive")
First visit the site for [OARConv](http://www.nsl.tuis.ac.jp/xoops/modules/xpwiki/?OAR%20Converter), download the software, and prepare it for use on your Windows desktop.
Run the executable and browse to your archive file. Be aware that simply browsing to the OAR file starts the conversion by unpacking the Open Simulator archive. You will be guided through the appropriate modal interfaces to select or create folders for this operation; the defaults are reasonable. Wait for this operation to complete. You now have the dataset from the Open Simulator archive in a format ready for conversion to DAE.
You do not have to import the entire region β there is an archive browser and object previewer in the OARConv interface. Lastly for this step, select all the content you wish to convert and begin the conversion. This produces DAE files suitable for import to Space, in the target folder prepared earlier.
Once that process is complete, you are ready to proceed to the next step: importing the DAE to Unity/Space.
#### Importing the archive[β](#importing-the-archive "Direct link to Importing the archive")
OARConv produces two folders of assets as its output. One contains all the objects that were collideable in the original simulator; the other contains all the objects that were phantom. It is recommended that these be imported separately, as follows:
* Create two empty game objects in your hierarchy; name one `phantom` and one `nonphantom`.
* Drop the folder contents from each of the OARConv folders into these empty game objects accordingly.
* Select the contents of the non-phantom folder in your project hierarchy, and in the Inspector click **Generate Colliders**.
This will leave the two sets of objects distinct in your hierarchy (though not in the scene).
Unity will grind a while β depending on the size of the import and the capabilities of your hardware, it might be a *while*. In the meantime, here are a few things you should know about the completed import operation.
Unity/Space is not Open Simulator and vice versa, so it is to be expected that there is not a 1:1 correspondence between the objects in the respective regions. There will be some cleanup work that needs to be done, and some things to watch out for. Some of these will be fairly painless while others will require attention to individual objects by hand.
A lot of the cleanup will be graphic, and some of it will be structural. Most of the graphic settings will involve the adjustment of textures. There is also the issue of naming: the OARConv tool does not use the names of the Open Simulator assets in many cases, and will use UUIDs instead.
One thing to look out for is large or duplicated files. Even similarly presented objects will not share materials, so the roughly converted region produced by the OARConv process will tend towards bloat. Additionally, terrains are imported oddly, and the meshes and materials produced for them can balloon considerably.
Explore the interface of the OARConv tool and become familiar with it. While it is not a perfect tool, it can be useful and effective at getting content moved from one platform to another.
---
### Troubleshooting
#### Overview[β](#overview "Direct link to Overview")
\=Troubleshooting= Materials An item is bright pink \* This implies a problem with your material; check: \*\* The material has a shader, selecting the material may show !!MISSING SHADER!!
\=Troubleshooting=
#### Materials[β](#materials "Direct link to Materials")
##### An item is bright pink[β](#an-item-is-bright-pink "Direct link to An item is bright pink")
* This implies a problem with your material; check: \*\* The material has a shader, selecting the material may show !!MISSING SHADER!! where the shader should be. \*\* The shader works on all our destination platforms, if you're using a custom shader, check for warnings - for space, all shaders need to work with all destination platforms. (If your shader does not work on a particular platform, we recommend using the 'Fallback' statement to fall back to a standard shader, or use Fallback Off, and the item will simply not render.)
##### The item is pure black and unaffected by lighting[β](#the-item-is-pure-black-and-unaffected-by-lighting "Direct link to The item is pure black and unaffected by lighting")
* This usually implies a shader bug (NaN and Infinity values are often rendered as pure black by most GPUs) =Uploads=
#### My Region Fails Always[β](#my-region-fails-always "Direct link to My Region Fails Always")
* This may be a bug with the processor, we'll be looking into it anyway
* Large regions may hit a maximum processing time limitation (currently set to 90 minutes.)
---
### Room Floor System
#### Overview[β](#overview "Direct link to Overview")
You can use the room floor system to create a region you can edit from inside Sinespace.
You can use the room floor system to create a region you can edit from inside Sinespace. This is mostly used for making home regions where users will want to decorate.
1. Have your region set up in Unity. Click on GameObject at the top of Unity and then click 'Create Empty'.
2. Change the transform of the empty object to the position of 0,0,0 if it is not already set to that. You can also rename the empty to something like 'Room Floor' to make it easier to find in the hierarchy.
3. In the hierarchy, click on the empty object you just created, and in the Inspector window on the right, click on Add Component. Search for 'Room Floor' and add it. You will see this in your Inspector window.
4. Add a name into the Name box. This name will be visible to users buying your template if you decide to sell it in the Shop.
5. Add a description into the Description box. This description will be visible to users buying the template if you decide to sell it in the Shop.
6. In the Furniture Quick placement, change the size to the number of floor areas you want in your region. For one area such as one room, change the size to 1. If you are making a house or anything else with levels, you will need to change the size accordingly. The collider to put here will usually be on the 3D object you used as the floor; You can simply drag the whole 3D object from the hierarchy to this box, and it will automatically add the collider.
7. Create another empty object and name it camera target. If you see a dropdown arrow next to room floor in the hierarchy, the camera target object is parented to it. You need make this a single object by dragging it down.
8. Once this is unparented, make sure in the Transfrom under the Inspector window that the camera target is set to the position of 0,0,0. This is used so that the bird eye camera can look down on this object, making it easier for users to edit from top view.
9. Drag the camera target object into the Focus box under Camera and Focus.
You can leave the Default Zoom from Focus as it is.
10. The Constrain Focus to Area is an optional setting. If you want to constrain the camera to an area, you will need to add a box collider above the ground collider. To add a box collider, make a new empty object and name it Constrain. Drag this collider into the
Make sure it is above the ground collider and not intercepting it. This collider will go around the area, as shown in this example.
If you have multiple levels or multiple buildings, you can add more Room floor components to define different areas.
These steps are also covered in our [Private Room Template](https://www.youtube.com/watch?v=RYEmB-6o1XE\&t=226s) tutorial video.
11. Subletting allows you to share the space with other users. This will be a feature in the near future.
12. Placement Restrictions allow you to restrict placement of items in certain places. If you check this box, and then enter a number in the Size box, this will give you element box with a Collider. For example, if you have built a house with a roof on it, and you don't want users to be able to place items on the roof, you can drag in the roofs' main collider here, and this will disallow placement of items. You can set up multiple areas for restricted placement by changing the Size (e.g from 1 to 5).
###### Configurable Buttons[β](#configurable-buttons "Direct link to Configurable Buttons")
There is an additional (optional) setting for use within the Room Floor system which allows you to set up configurable buttons. These configurable buttons allow you change certain aspects of the room, such as allowing you to open and close curtains, change from night to day and other settings. As this is a complex setting, you can see our video tutorial for the configurable buttons [here](https://youtu.be/klEaPKcBoOk?t=118).
###### Lighting Controls[β](#lighting-controls "Direct link to Lighting Controls")
The lighting controls are another optional setting you can use in your room template. The lighting controls will add a button under the Options menu in Edit room, so that the user can change the color and intensity of lights if they want to. For this to work, you need to have set up your lighting model (e.g. standing lamp or table lamp) with a point light or another sort of light. You can do this buy adding the light as a child object to the light model.
The Lights size is the number of sets of lights you want to affect. If you have standing lamps for example in one area, you can have these as one group of lights, and change the Lighting size to 1. If you want to change another group of lights in a different area such as outside as well as the lights in the other area, set this to 2. Make sure you click on New next to the Network ID box. This can be changed manually at another point if need be. The Affected Lights is where you will need to drag in the lights from the hierarchy. For example, if you have set the Light size to 1, and in this light group you have two candles, you will need to drag the light source from each of these candles into the slots. The light source is the Spotlight, Point Light or Directional Light.
The Colour setting allows you to set the lights as colourable, so users can change the color of the lights in their home region. To make the lights colourable, check the box. If you don't want to make the lights colourable, the light color will stay locked to the colour under the Light Source settings. You can see this default color by clicking on the Spotlight, Directional Light or Point Light.
If you are making them colourable, set the Default Colour on the Room Floor component to something close to the light source default. Once in-world, users can change this colour to whatever they want. If you want the user to be able to change the Intensity of the lights, you can check the Show Dimmer box. This will add a Brightness slider to the Lights option in-world.
The Default Intensity will be the Default Intensity number on your light source. You can then add a Minimum Intensity and a Maximum Intensity to the lights which the users will be able to toggle between using the Brightness Slider. The Day/Night cycle option allows you to have the lights turn off during the day and turn on at night when checked.
###### Material Controls[β](#material-controls "Direct link to Material Controls")
The Material Controls will add a button under the Options menu in the Edit room system to allow users to change materials on the walls or floors of their home region. They will only be able to change the material if they own material packs bought from the in-world Shop. You can make your own material packs as well to sell in the Shop.
To make the material interchangeable, add in a new Network ID. If you are making it so the material on the floor can be changed, name this as Floor so it's easily recognizable in-world on the Options menu in the Edit Room system. If you are setting it up so the material on the walls can be changed, name this as walls. If you are doing both, change the Size to 2, and name one Floor and one Walls. The Associated Materials is where you drag in the mesh for the floor or wall. If you have multiple walls or floors you want to make the material interchangeable on, set the Size to however many you have, such as 2 for 2 walls e.t.c
###### Built-in Objects[β](#built-in-objects "Direct link to Built-in Objects")
This option allows you to have furniture already in the Room Inventory when you upload it and sell the home template in the Shop. These furniture items can then be placed in the region, but can't be put back in the inventory. Note: This is an upcoming feature which will be released soon
Set the Size to how many pieces of furniture you are placing in the region. For example, if you are uploading the region with a bed and sofa already placed, change the Size to 2. These furniture items will In the Element box, drag in the furniture item which contains a room furniture component and a virtual good component. When you upload the whole room template, these items will show in the Edit Room inventory.
##### Uploading the Room[β](#uploading-the-room "Direct link to Uploading the Room")
To upload the room template to the Shop, add the Scene Settings component by clicking on Sinespace at the top of Unity, and choose Scene Settings. Once they are added, you will see a Virtual Good component and the Scene Settings component in the Inspector window.
Fill in the Virtual Good component Basics tab with the Type set to Region, then the Category set to which ever category is appropriate. Fill in the rest of the virtual good with all of the information, but don't submit the region yet as you will need to fill in the Scene Settings. For more information on how to fill the Scene settings, please visit this [page](/sinespace-sdk/regions/export-settings.md). Once it is all filled in, you can then Submit your region. You can check on the upload process at curator.sine.space.
---
### Room System
#### Overview[β](#overview "Direct link to Overview")
Under a revision and will be up shortly. The room system allows the editing of a region while logged in-world.
Under a revision and will be up shortly.
The room system allows the editing of a region while logged in-world.
#### Editing your Room[β](#editing-your-room "Direct link to Editing your Room")
To edit your room, go to your room by clicking on the 'Home' button at the bottom of the screen. Once in your room, click on the 'Edit Room' button. This will bring up the Edit Room UI.
The Edit Room UI has a ton of different tools.
1. Inventory
This is where all of the furniture items you have are stored. You can click on a item in the inventory, and this will be spawned in the room.
1. Select
This will select the furniture item you click on in the room.
1. Rotate (2D)
This is the first rotate tool along the top, it'll rotate easier to grab handles focusing more on overhead rotation, allowing for stuff like furniture placement to be rotated, without necessarily grabbing the object in 3D and rotating all over the place randomly.
1. 3D Move
This is your standard translate tool, you can hold CTRL while moving to move along a 1m grid.
1. Rotate 3D
The 3D rotate tool lets you rotate both in the 3D space, using the X,Y and Z handles, and also lets you rotate in screen space. If you hold CTRL while rotating, it will look changes to a 15 degree angle.
1. Scale
Scale sizes items up and down if you scale using the middle white box on the gizmo, or, you can grab the other handles individually to scale along the X,Y and Z axis. If you hold CTRL while scaling, you can lock the scaling to multiples of 100.
1. Camera
There are three camera settings:
* Ceiling - This will lock the camera to the overhead ceiling that is built into the room by the room designer. If you use the arrow keys, you can pan the camera, or you can move the mouse cursor to the edge of the screen.
* Fly Thru - This is a free moving camera. Hold right click, and use the W,A,S,D,E and C keys to move the camera about manually. For building scenes this is often the best mode to use.
* Avatar - This will use the normal camera view behind the avatar.
1. Snap
Snap controls how the object will be moved underneath you - this is a on/off toggle. When there is a blue tick, this indicates that snap is on.
1. Node
If the furniture has 'snap nodes' built in, the object will lock together as the designer intended.
* Align\*\*
Align is defaulted to be switched off, but if you turn it on, when you're dragging or placing furniture, this will try to align objects to their nearest other object (or scenery component). This is useful if you want to place a sofa in line with a wall.
1. Coordinate Space
if this is set to global, the widgets on the movement/rotation/scale tools, will be aligned towards the scene; so the 'Y' axis will always point upwards vertically off the ground. If you turn it to local mode, it'll be pointing towards the rotated upwards on that model, so if you rotate the model, the widgets will point in different directions.
1. Coordinate Origin
This will mean that the gizmos will be emitted from the center of the mesh. The alternative mode, Pivot, which is the pivot point defined in the object, will set the gizmos to the objects pivot point.
1. Design'
This is where you can switch to a different template for your room. You can buy new templates in the Shop under the Room tab. Note, when you swap storefront, it will erase the contents of your room You may instead, want to make a new region (from the main UI, click 'Home', then 'Create new region'), and edit in there - additional regions are free.
1. 'Material
This is where you will see a list of all the material you have purchased from the Shop. Material can be bought from the Shop under the Furniture tab. You can click on the Material you want to use, and it will show on the floor or ceiling, depending on which one the material was made for.
1. Lights
The lights button lets you control lights embedded in the region - set their colour or change their brightness.
1. Options
the options button is a free-form area for creators to embed configurable options; such as 'shutters down' or 'door open/closed', etc. What the items are here here for example shutters, is defined by the creator.
1. Switch
This allows you to switch from one area in a region to another, so you can place furniture in different parts of the region.
1. All Objs
This will show you a list of all the objects you have in the region.
1. Save
We don't save by default, so this is worth noting (we'll add a popup in a future viewer if it isn't in there already). The save button is used to save your changes, but if you don't like what you've done, you can logout and come back, and it'll return to how the region looked before you edited the room.
1. Undo
This will undo the last change you made.
1. Redo
Redo will redo the last change you undid.
1. Duplicate
This will duplicate the object you have selected.
1. Delete
This will delete the object you have selected.
1. Deselect
This will deselect the object you have selected.
#### Placing Furniture[β](#placing-furniture "Direct link to Placing Furniture")
To place furniture, all you have to do is click on the furniture object in the inventory, and it will spawn in the region. You can choose to use the 'Switch' button if you want to place the furniture in a different area of your region. Once the furniture has spawned in the region, you can move it around with the above mentioned tools, and decorate as much as you want!
There are a couple of shortkeys to use whilst placing furniture;First up - the alt key:
if you're holding the alt key, the furniture will place on the closest surface below the cursor, if you do not have the alt key pressed, it'll place it on the floor instead.
By default, every room has a list of placable surfaces in it, defined by the template creator.
This may not be optimal - if you're placing something on top of a table for example, then you want to hold the alt key so they align.
If you hold down Shift while placing, it'll also ignore the Snap and Align modes, as if they're switched off.
#### Shortcut Keys[β](#shortcut-keys "Direct link to Shortcut Keys")
Here is a list of all of the shortcut keys for the edit room tool:
* W\*\*: Pressing the W key will switch the mode to Move.
* E\*\*: Pressing E will switch the mode to Rotate.
* R\*\*: Pressing R will switch the mode to Scale.
* CTRL+LMB\*\* (Left mouse button): This will snap the selected object to grid.
* CTRL+Z\*\*: This will undo the last action.
* Shift+Delete\*\*: This will delete the selected object.
---
### Scenes
#### Overview[β](#overview "Direct link to Overview")
In Unity, Scenes are where you put all of the objects of your game.
In Unity, Scenes are where you put all of the objects of your game. They can be used to create a main menu, individual levels, and anything else. Think of each unique Scene file as a unique level. In each Scene, you will place your environments, obstacles, and decorations, essentially designing and building your game in pieces.
When you create a new Unity project, your scene view will show a new Scene. This is an untitled and unsaved scene. The scene will be empty except for default objects; A main camera and light.
#### Saving Scenes[β](#saving-scenes "Direct link to Saving Scenes")
To save your scene, go to File>Save Scene from the top menu. Your scene will be saved as an Asset in your Assets folder and appear in the project window.
#### Open A Scene[β](#open-a-scene "Direct link to Open A Scene")
To open a scene, double click the scene asset in the project window.
---
### SceneSaveSettings
#### Overview[β](#overview "Direct link to Overview")
Scene save setting lets you upload your scene to Sine Space.
Scene save setting lets you upload your scene to Sine Space. Once you have saved remember to remove Main camera from the scene as the region will be using 3rd person camera, which you do not need to add. Not removing main camera will cause region to be stuck at one view.
##### Add Landing Zone[β](#add-landing-zone "Direct link to Add Landing Zone")
You need to define where users arrive when they log in to your region; and what direction they are facing. To do this, once your scene is set up, from the top menu in Unity select Game Object / Create Other / Landmark
This will place a new landmark item in your scene. In the Inspector window, set the type to Landing Zone and tick Spawn Point.
The in scene object is a yellow edged transparent plane which you can position anywhere in your scene. The yellow arrow points in the direction your visitors will face when they arrive.
Be careful to position the landing zone slightly above the terrain; if a tall avatar's feet arrive below the terrain they may fall through.

##### Add scene settings component[β](#add-scene-settings-component "Direct link to Add scene settings component")
In the top menu in Unity go to Space / Scene Settings.
This will add a Virtual Goods component to your scene. You will see a set of fields in the Inspector.
You can return to this component any time via Space / Scene Settings.

In the Inspector set the Content Type to Region.

##### Primary descrition[β](#primary-descrition "Direct link to Primary descrition")
Add the name, description and brand identity of your region as you want it to appear in the explore and discovery panels of the Space platform.


##### Localisation[β](#localisation "Direct link to Localisation")
You can add slots for as many different languages as you want to.

##### Images And Icons[β](#images-and-icons "Direct link to Images And Icons")
If you are uploading items that will be sold as virtual goods to other Space users, add the store icons and imagery here and set the prices for Gold and Silver credits.

If you are uploading a region or item that is not for sale, tick the not for sale box. You do not need to add any images or icons if the item is not for sale.

##### Dual Currencies[β](#dual-currencies "Direct link to Dual Currencies")
If your region is going to be for sale, allowing other users to buy it as a template they can then customise as a private region for themselves, set it for sale and set your gold and silver prices.
For more infomation on gold and silver currencies;
[Currencies - Gold and Silver](/curator-dashboard/items/currencies.md)
##### Content Maturity[β](#content-maturity "Direct link to Content Maturity")
Choose an appropriate content maturity level;

##### Creator Information[β](#creator-information "Direct link to Creator Information")
The creator information should show the details of the legal entity holding the account; whether that is an individual or a company.

##### Export Mode[β](#export-mode "Direct link to Export Mode")
The Export Mode defines how your region content is received by your visitors; all at once before they log in, or progressively after they arrive.

* Single scene
Single scene delivers the entire region to the user as a single file which downloads before their avatar spawns. For regions with download sizes up to 100 mb, Single scene is likely to be an acceptable download time for your visitors.
* Multi bundle
Multi bundle is a form of dynamic loading control. It splits your scene into smaller components that are streamed to the visitor progressively.
The multi bundle algorithm examine every root object in your scene and compares each with every other root object. It then bundles objects where there is more than 40 kbytes of overlap in shared data between them.
You group into root objects has a big factor on how we create bundles; for instance grouping all vegetation or grouping one particular building where users will arrive.
Too many bundles will cause stuttering for the user while they are progressively loading. A reasonable target is 20 β 30 bundles.
* Additive scenes
Additive scenes is a Unity utility that allows you to organise a single region into multiple scenes. You can manually split content, creating a root scene containing occlusion, lightmap and navigation data, with additional scenes loading mesh and other content progressively. You will need Unity 5 multi scene tools to manually set this up.
For more information, see;
* Required download
When you are using Multi bundle mode you need to select one item in your scene, usually the terrain, and add a component to it called Manual Loading Control or Dynamic Loading Control. Then tick Required Download. This will ensure that the item is sent to the user before their avatar spawns. Without this there is a risk users will arrive and drop through space before your scene loads above their heads.

* Suggested memory
If your guest's device has less memory than this, they will be given a performance warning when entering the region.
##### World Map[β](#world-map "Direct link to World Map")
The world map allows users to search and browse regions. The Preview Image you supply will be used as a background to preview your region in the World Map. It will also be used as the background while the region itself is loading.
* Preview image
The image you provide should be a .jpeg file. A 2:1 aspect ratio is recommended. Because the image is stretched to fit different screens it will distort slightly for some users.

* Loading logo
The Loading Logo Image appears on top of the Preview Image and is not stretched, allowing you to present your brand logo or a region specific title without distortion.
The image you supply should be a .png file with 512x256 dimensions. When you import the .png file, ensure the Alpha is Transparency box is ticked;

##### Region URL[β](#region-url "Direct link to Region URL")
You can assign a unique sub domain for each of your regions, which you can share with guests who can walk directly into your space from their browser.
In the editor you can reserve your region name.
Once the region is published you can then teleport directly to the staging server version (Creator) or the live public server version (Live).

##### Supported platforms[β](#supported-platforms "Direct link to Supported platforms")
The platform settings allow you to fine tune your region for each platform you want to publish to.
Space currently supports;
* Standalone - Desktop application, PC or Mac
* Mobile / tablet - Android or iOS
* WebGL - Chrome, Explorer, Firefox and Edge
* Console - Sine Wave Entertainment is an accredited developer for Xbox and Playstation. The company is planning to release on these platforms later in 2016 after building a user interface for game controllers.

##### Settings[β](#settings "Direct link to Settings")
The default settings are designed to work for most regions.
Scene adjustment
* Remove lightmaps / light probes / reflection probes
Removing lightmaps and probes can significantly reduce download speed but will also impact on the runtime performance.
More information;
Lightmaps Light probes Reflection probes
* Static bake meshes / colliders
Ticking these boxes will prebake data before export. This improves loading performance but the region download will be bigger.
More information;
Static bake meshes Static bake colliders
* Strip occlusion / navigation data
Occlusion data holds information about what areas are visible from other areas; it allows the viewer to make intelligent decisions about optimising a scene, however it can add several mb of size to both runtime memory use; and download size. Keeping it improves performance but can result in higher memory use in big scenes.
Navigation data is used for showing waypoints, and moving NPCs around in a scene; it uses a little bit of extra memory, and can be stripped out if you are under severe memory pressure.
Texture size reduction
* Max texture resolution
All textures will be reduced to a maximum of the defined size for each build.
* Texture reduction levels
Reduces textures all by a multiple of the original, in line with Max texture reduction above.
So; if your scene contains large textures at 1024x1024 and you set the max texture reduction to 512 those large textures will be reduced by a factor of 4.
If you then set Texture reduction levels to 1, smaller textures in your scene will also be reduced by a factor of 4; so a 512x512 texture, which otherwise would have been unchanged by the Max texture reduction, would also be reduced by 4, to 256x256.
If you set the Texture reduction level to 2 it will multiply the Max texture reduction scale by 2; so in the case above reducing the smaller 512x512 texture by a factor of 8, to 64x64.
* Normal reduction levels
This will apply a further multiplicative reduction on normal maps on top of the reduction already applied by the Texture reduction level above.
Texture compression
* Allow crunch / Crunch level
Allows JPEG compression to be added to all textures in addition to DXT compression. This will degrade the quality of your images as the compression is lossy; but significantly reduces download filesize. It does not improve runtime memory size except during loading. Crunch level runs from 0 (very lossy) to 100 (lossless).
* Compress textures
This applies a further quality reduction, comparable to the quality slider in Photoshop when saving a jpeg file.
* True color As 16
Interprets images stored as 'True Color' to 16-bit colors. This applies compression to the colors, without introducing the blurriness / artefacts that DXT compression can introduce; at the expense of being slightly larger. With this ticked, any image with 'True Color' compression, will be packed at 16 instead of 32-bit on this platform.
Audio settings
* Force audio to mono
Converts stereo files to mono for that platform.
* Audio bitrate
This is a percentage field. So whatever the bitrate of your original files, you can reduce by X% for each of the different platforms you publish to. For instance a set of 128 bitrate original files, left at 100% in the Standalone build can be reduced to 64 in Mobile and WebGL builds by setting this field to 50.
##### Report[β](#report "Direct link to Report")
A summary of the objects and scripts in your scene which will notify you of potential issues.
* Info
This shows how many objects, root objects and colliders your scene has. It will flag potential performance issues.

* Script List
Space currently has a white list of approximately 120 scripts you can deploy in your regions. The script list shows all the scripts in your project, flagging the ones not currently white listed, which will be stripped out when submitted.
You can submit scripts to your account manager for inclusion in the white list. When the platform's SDK is released (scheduled for September 2016) the white list will be maintained in parallel.

##### Apply compression settings[β](#apply-compression-settings "Direct link to Apply compression settings")
Click this button to apply the [Region - Platform Settings](/sinespace-sdk/regions/platform-settings.md) to the assets in your scene.
Once the automated compression has run you can manually adjust individual files before publishing. You might, for instance, apply 512 as a maximum image size for the WebGL version of your region but then revert one or more specific important textures back to a higher resolution.

##### Sort into layers[β](#sort-into-layers "Direct link to Sort into layers")
Click this button to automatically assign every asset in the scene to one of four draw distance layers, according to their size; larger objects are set to be visible at greater distances.
The draw distance for each user is determined by the quality settings they select inworld;

Default = 20 to 75m Important = 80 to 320m VImportant = 240m to 900m NotImport = Max 30m (60m in Beautiful/Ultra) NotImportLandmark = Max 60m (120m in Beautiful/Ultra)
If you do not apply Sort into layers button everything will be left in default layer.
After applying you can manually review and modify;

##### Automatic submission[β](#automatic-submission "Direct link to Automatic submission")
Once your scene is ready to submit, click Automatic submission. This will create a zip file containing the region and will send it to the Space servers.
Here the assets will be unpacked and compiled for each of the different platforms you have specified. You will receive three automated emails; confirming the content has been received, has started processing and has been released for you to log in and review.
---
### Submission
#### Overview[β](#overview "Direct link to Overview")
Submitting your region uploads it to - a preview server where content can be reviewed online before going to the live servers.
Submitting your region uploads it to - a preview server where content can be reviewed online before going to the live servers.
##### Report[β](#report "Direct link to Report")
A summary of the objects and scripts in your scene which will notify you of potential issues.
* Info
This shows how many objects, root objects and colliders your scene has. It will flag potential performance issues.

* Script List
Space currently has a white list of approximately 120 scripts you can deploy in your regions. The script list shows all the scripts in your project, flagging the ones not currently white listed, which will be stripped out when submitted.
You can submit scripts to your account manager for inclusion in the white list. When the platform's SDK is released (scheduled for September 2016) the white list will be maintained in parallel.

##### Apply compression settings[β](#apply-compression-settings "Direct link to Apply compression settings")
Click this button to apply the [Region - Platform Settings](/sinespace-sdk/regions/platform-settings.md) to the assets in your scene.
Once the automated compression has run you can manually adjust individual files before publishing. You might, for instance, apply 512 as a maximum image size for the WebGL version of your region but then revert one or more specific important textures back to a higher resolution.

##### Sort into layers[β](#sort-into-layers "Direct link to Sort into layers")
Click this button to automatically assign every asset in the scene to one of four draw distance layers, according to their size; larger objects are set to be visible at greater distances.
The draw distance for each user is determined by the quality settings they select inworld;

(Performance setting range: Fastest < Fast < Simple < Good < Beautiful < Fantastic < Ultra)
Default = 20 to 75m
Important = 80 to 320m
VImportant = 240m to 900m
NotImport = Max 30m (60m in Beautiful~Ultra)
NotImportLandmark = Max 60m (120m in Beautiful~Ultra)
If you do not apply Sort into layers button everything will be left in default layer.
After applying you can manually review and modify;

##### Automatic submission[β](#automatic-submission "Direct link to Automatic submission")
Once your scene is ready to submit, click Automatic submission. This will create a zip file containing the region and will send it to the Space servers.
Here the assets will be unpacked and compiled for each of the different platforms you have specified. You will receive three automated emails; confirming the content has been received, has started processing and has been released for you to log in and review.
---
### Upload Settings
#### Overview[β](#overview "Direct link to Overview")
Add scene settings component In the top menu in Unity go to Space / Scene Settings.
##### Add scene settings component[β](#add-scene-settings-component "Direct link to Add scene settings component")
In the top menu in Unity go to Space / Scene Settings.
This will add a Virtual Goods component to your scene. You will see a set of fields in the Inspector.
You can return to this component any time via Sinespace / Scene Settings.

In the Inspector set the Content Type to Region.

##### Primary description[β](#primary-description "Direct link to Primary description")
Add the name, description and brand identity of your region as you want it to appear in the explore and discovery panels of the Space platform.


##### Localisation[β](#localisation "Direct link to Localisation")
You can add slots for as many different languages as you want to.

##### Images And Icons[β](#images-and-icons "Direct link to Images And Icons")
If you are uploading items that will be sold as virtual goods to other Space users, add the store icons and imagery here. It is not necessary if you make the region not for sale.

Tick the "Not for sale" checkbox will not put the region in the shop and you can set an amount of the maximum one player could own. 0 by default sets the amount unlimited.

Otherwise, leave it unchecked and you can set the price of the region. You can also make it enalbe for promotion, so you can offer a discount easily instead of modify the price then reupload.

##### Dual Currencies[β](#dual-currencies "Direct link to Dual Currencies")
If your region is going to be for sale, allowing other users to buy it as a template they can then customise as a private region for themselves, set it for sale and set your gold and silver prices.
For more infomation on gold and silver currencies;
##### Content Maturity[β](#content-maturity "Direct link to Content Maturity")
Choose an appropriate content maturity level;

##### Creator Information[β](#creator-information "Direct link to Creator Information")
The creator information should show the details of the legal entity holding the account; whether that is an individual or a company.

---
### Scene & Assets
#### [ποΈVolumetric Lighting](/sinespace-sdk/scene-authoring/volumetric-lighting.md)
[Volumetric Lighting documentation for Sinespace.](/sinespace-sdk/scene-authoring/volumetric-lighting.md)
---
### Animating textures, for users of that other platform
#### Overview[β](#overview "Direct link to Overview")
1. Level: - Beginner Unity/Space, experienced with texture animation in Second Life (tm) 1.
1. Level:
* Beginner Unity/Space, experienced with texture animation in Second Life (tm)
1. Goals:
* Discover the difference between animating textures in SL and materials in Unity
* Learn about the animation system
* Produce your own animated materials
##### A brief examination of the two systems[β](#a-brief-examination-of-the-two-systems "Direct link to A brief examination of the two systems")
* **Core construction elements**
Second Life is a fairly old platform, and as such it faced many challenges with respect to embracing a variety of hardware, most of it less than capable when it comes to graphics performance. Consequently, many choices were made that optimized for both low performance requirements (relatively speaking), and simplicity in the toolset, which was entirely self-containted in it's original form.
Unity, in contrast, exposes the full spectrum of hardware capabilites to the creator in the editor interface. Additionally, every opportunity has been made to keep Unity highly performant at the 'point of sale'.
There are consequences in each of these platform design choices. Like the differences in platforms, the differences in consequences are significant.
For Second Life, keeping things very simple and spreading the resources around the application was paramount. The success of this model is obvious; it's a horse many of us get on and ride with satisfaction and utility to this day. Unity, however, is a stealth jet. Piloting skills are required.
So what does all this have to do with texture animation? Well, only a lot. The objects produced by and for Second Life users are made up in-situ, out of object components that are mathmatical abstractions of models. As such, they have some fairly unique properties. As with anything unique, it sets all else apart. Unity, however, directly employs modelled assets freely available to the video gaming marketplace; or that are produced using the same industry standard tools as these models. It is a gaming engine, not a modelling/animation suite. 3DSMax, Maya, Cheetah3D, Blender, the list goes on; all of these, with notable exceptions, focus on being modelling or animation tools. Chances are, if it can export an FBX or OBJ filetype, it can be used to produce models for Unity. This leaves Unity with substantially more resources to bring to bear upon delivering a strong game engine.
Let's cut to the chase: can we animate the faces of objects with textures in Unity, as we do in Second Life? The short answer is no. Not even a little. That doesn't mean the same effect can't be achieved; it simply means that the method by which it is acheived may seem quite foreign when first encountered.
Just remember, when in Rome, do stuff like the Romans do.
*One quick note:* It has become possible in the past few years to upload fully modelled mesh content to Second Life. We're not going to worry about that too much, except to say that making content for Unity is lagely identical to making mesh content for SL, so if you know anything about that, you have an idea of the nature and scope of the task.
* **Materials vs. Textures**
It is perhaps useful to imagine that there is a *nature* about all this. *natural* in this context means that there are certain operations performed by modern graphics hardware; these operations being performed by special programs called 'shaders'. Without getting too over the top, shaders do some very specific things in some highly optimized ways. This nature is exposed directly in the Unity editor interface. In this way of thinking, SL is a bit *unnatural*. It provides some very limited functionality using shaders that it keeps quietly hidden away. This is because shaders are made to work on models, and Second Life content is not modelled as such; it's built up of a variation, an arithmetic shortcut called 'primitives'. Beyond that I wont waste time on a discussion of that technology; we're acutely aware of how that all works.
In SL there is (potentially) a texture per face. In Unity, there are objects, and they are skinned with materials. Pay close attention: the material is applied *per object*, not per face. If you wish to have an object that has different textures exposed on a per-face basis, then it needs to be a complex object, with child objects that provide the illusion of distinct faces. This does not mean a simple object cant have multiple faces; it does mean however, that all the faces in a simple atomic object will share the same material.
* **Script API vs. Scene Graphs**
In SL too the approach to animating the textures on the faces of *prims* is quite different. Via one or two functions, certain pre-supposed effects are exposed in their calling parameters for setting the scale, rotation, and position, and various 'effects' like loop, pingpong, direction, and speed.
With Unity, as mentioned before, materials are used. A Unity material is one or more textures, used in various ways by a shader and some parameters based on the operation performed by the shader. The shader runs right on the graphics hardware, and does what shaders do (render a pixel). Like just about everything else in Unity, materials can be animated. Every property exposed in the inspector (and often some that arent thusly exposed) can be animated with the animator. The animator produces 'animation clips', which are collections of *scene graphs*. A *scene graph* is the set of all datapoints for a given parameter over the course of a period of time. If a lit pixel is moved across the screen horizontally, it's scene graph is the increasing value over time of it's 'X' screen coordinate. That value for 'X' can be plotted on a graph vs. elapsed time, hence the name *scene graph*. In Unity, a collection of such scene graphs is collected into a little proprietary bundle per-object called an *animation clip*.
You can get into the animation editor for an object in at least two ways. One, select the object either in the scene or in the hierarchy, and press **CTRL 6**. The other is from the main menu, 'Window->Animator'.
You should see something like this:
* *Fig. 1: Ready to work on some water flowing over a stone* The first thing to do is create a new material. Select your assets folder in your Projects window/tab. Then from the main menu, 'Assets->Create->Material'. Give the new material a new name, like 'FlowingWater'. Next you're going to need a nice image of some water, evenly lit. Import that from the main menu, 'Assets->Import New Asset' and pick your file. For the purposes of this tutorial, I just snagged one off google images. Seamless is pretty important if you want it to look right ;)
Make certain the new material is selected in your project window/tab, and scroll down to the material in the inspector. Note the dropdown picker for 'Shader'. Find the one that is called 'Standard (Specular setup)', and below that set Render Mode to 'Transparent'. Skipping down to 'Main Maps', Find the little sqaure with the little circle beside it labelled 'Albedo'. Click the little circle, and pick your recently imported water surface asset (2DTexture). Set it's tint to a pleasant shade of green, preferably one close to something presnt in your water image. Set a specular color too. Adjust the smoothness slider to get that ideal balance between shininess and transparency. If you have one, use a water normal map asset (2DTexture). It doesn't much matter whether it matches the water texture you're using, though it should be tileable. I used a normal map that I had laying around from another project. It will improve the appearance of my water, but it would work fine without it, and might not be at all appropriate if you *aren't* animating water. We wont be introducing a specular map in this little assembly.
Scrolling down beyond Global Illumination, find 'Tiling' and 'Offset'. If these sound familiar to you, you are correct, and they do much what you would expect them to do. These are also what we'll be animating.
It should be noted at this point that while it doesn't impact this workflow, there is no parameter exposed for doing rotation in this material. This is because this shader does not do rotation. There are shaders that do, and it is likely that when one such is used, it's rotation properties would be exposed in a similar material parameters inspector window.
If you are playing along in the editor, you should have something more or less like this:
* *Fig. 2: Stone shaped mesh object skinned with flowing water material (yet to be animated)* Now it's time for the animation. Click the 'Create' button in the center of the animator window and create a new animation file. Give the animation a good name like 'FlowingWater' or something ;) Now it's time to get our properties on the graph. In the inspector, change the value of 'Tiling', both X and Y. Note that there are now new properties in the animation window. Opening their dropdowns, you'll see each of x,y,z,and w. The numbers associated with these can be clicked on and edited just like any other constant supplied to a Unity interface.
Repeat the process for Offset. It doesn't much matter what values you change them to; rather, it's important to trigger the insertion of the properties in the animator's interface. These are not displayed directly in 'Add Property' picker in the animator interface as their specific name may vary from one shader to the next. Once you have the two sets of properties showing up in your animator window, set the values back to their defaults of 1,1 0,0 for each of Tiling X,Y and Offset X,Y.
Next right-click on the dark grey rectangle to the left of the upper scrolling arrow where it intersects the red line. Click the 'Add Key' Selection in the popup. Next, click right on the timeline at 1:00. This should move your scene graph cursor (the red line). Repeat the addition of the keys at the end of the clip:
* *Fig. 3: Setting up the material animation* Now click the diamond at the topmost of the column on the right, under the scene graph cursor. Drag it to the right, expanding the animation timeframe; take it out to 5:00. Now we are ready to set the ending keyframe. In my piece, I set the Tiling to 3 in both directions, and Offset I started at 0 and then set to 10 at the end. You can preview the animation by clicking the 'Play' button on the animator controls.
Here's mine running in scene preview:
* [Animated water over stone](https://youtu.be/FeXxEgT70r0)
* *Fig. 3: The completed animated material* A huge thanks and a shout out to Adam Frisby for detailing this functionality sufficiently well that I could get it done and make a wiki entry about it ;)
---
### Custom skybox shader
#### Overview[β](#overview "Direct link to Overview")
The Custom Skybox shader introduced in Space Editor Pack 08 produces a realistic night sky and procedural two dimensional clouds.
The Custom Skybox shader introduced in Space Editor Pack 08 produces a realistic night sky and procedural two dimensional clouds. It is very effective, and very easily employed, thanks to the provided example procedural skybox. Simply slot the skybox (found in Assets/Sample Art/Adam-CloudSkybox) titled 'Sample Cloud Skybox' in the 'SkyBox' slot of your 'Lighting' window.
It should be pretty much good to go, though there are settings that one might wish to explore.
Additionally, the shader code for the shader used in this skybox is available in the assets for the sake of review or modification.
---
### Embedded Video
#### Overview[β](#overview "Direct link to Overview")
Creating a video player Sinespace allows for creators to embed Youtube videos onto objects they create in Unity with The Editor Pack.
#### Creating a video player[β](#creating-a-video-player "Direct link to Creating a video player")
Sinespace allows for creators to embed Youtube videos onto objects they create in Unity with The Editor Pack.
The Embedded Video (Script) component allows for the creator to embed Youtube and other video content into Unity Materials.
To successfully work with the Embedded Video (Script) component in sinespace you will need to have the following components added to your object
For this walk through, I am using a standard cube prefab.
#### Adding required components[β](#adding-required-components "Direct link to Adding required components")
##### Unity & video components[β](#unity--video-components "Direct link to Unity & video components")
β’ Video Player
β’ Audio Source
β’ Embedded Video (Script)
β’ A New Material
##### The required sinespace components[β](#the-required-sinespace-components "Direct link to The required sinespace components")
β’ Virtual Good
β’ Room Furniture
* Note:\*\*These are not necessary if you are adding the video player to an existing region
#### Tutorial: Building a simple video player[β](#tutorial-building-a-simple-video-player "Direct link to Tutorial: Building a simple video player")
##### Video Player[β](#video-player "Direct link to Video Player")
Select the preferences you desire
* Render mode:\*\* Material Override
* Material Property:\*\* \_MainTex
##### Audio Source[β](#audio-source "Direct link to Audio Source")
Basically, leave as is or configure to your own preferences
##### Embedded Video[β](#embedded-video "Direct link to Embedded Video")
* Auto Play:\*\* Select if you desire, otherwise it will play on click, but be sure to make the **Box Collider** a trigger
* URL:\*\* Enter the URL of the video you wish to play
##### New Material[β](#new-material "Direct link to New Material")
Create a new blank Material and add it to the object
Attach the Material to the Mesh Renderer component
Attach the Material to the Embedded Material component under **Target Material**
##### Virtual Good[β](#virtual-good "Direct link to Virtual Good")
Select the preferences you desire here
For this example, weβre using the Furniture/TV category
Complete the rest of the Virtual Good component in preparation for upload
##### Furniture[β](#furniture "Direct link to Furniture")
Select the furniture preferences you desire
* Please note: \*\*You can theoretically attach video playback to any object type you wish
##### Finalisation[β](#finalisation "Direct link to Finalisation")
Convert your object to a Prefab and prepare it for uploaded into sinespace
You can now upload your Embedded Video object, be sure to test it in the preview environment
---
### GameObjects
#### Overview[β](#overview "Direct link to Overview")
Category:Tutorials GameObjects are essentially every different item you put into your scene.
GameObjects are essentially every different item you put into your scene. If you have placed a teddy bear in your scene, this is a GameObject, or if you have a car, this is a GameObject too.
These GameObjects are like having an empty mug, but it only becomes useful when it has something to drink in it. GameObjects need **Components** to change them from a plain teddy bear, into a dancing, smiling teddy bear, or changing a shell of a car into a car you can actually drive with physics.
Lights in your scene work the same too; They are just a GameObject, which needs a component to make it a light.
So, anything you can dream up and create or add to your scene, is a GameObject. This Cube in scene is a GameObject as well.
---
### Gimp (8-bit)
#### Overview[β](#overview "Direct link to Overview")
Without additional plugins, Gimp is limited to 8-bit accuracy.
Without additional plugins, Gimp is limited to 8-bit accuracy. Depending on the desired altitude differences you may need to smooth the surface in Unity after import.
First, the dimension of the heightmap must be decided: the more detailed the more memory and processing power used. A reasonable choice could be roughly 1 point per 2 meters. The terrain size can be chosen freely, but the heightmap size must be one of the following: 33x33, 65x65, 129x129, 257x257, 513x513 1025x1025, 2049x2049 or 4097x4097.
1. In Gimp you create a new image with the chosen heightmap size, for example 513x513. In the extended adjustments choose gray scale instead of RGB colours.
2. Now, paint some structure and smooth it, or alternative you can import images from elsewhere. OpenSim for example can export terrain to .png graphics, which are understood by Gimp.
3. If a terrain heightmap is designed, you can export the result do the .data format. Gimp will show a dialog, in which you must switch from Standard (R,G,B) to Planar (RRR,GGG,BBB). The second selection remains on R,G,B (normal).
4. Unity understands only .raw images, so you must rename the .data output file into .raw file ending.
5. Now the import to unity follows. To reach the import dialog, enlarge the terrain section. In the right of the symbol bar a gear-wheel is shown. After selecting this, in the bottom of the shown details you find the button "Import Raw". That's near the place, where you surely already have chosen other region details like Terrain With, Length, Height, Detail resolution and so on. You select the file created by gimp, and after that a dialog box is shown. Here you can check if Unity has recognized the 8-bit data format and the dimensions of the heightmap. If not, here is the option to adjust it manually. Now, a checkmark must be set at "Flip vertically"! This is necessary, because the Y axis of Gimp points from up to down (into south direction), but in Unity the corresponding Z axis points into north direction.
That's it, after pressing the "Import" button the terrain should appear in the new structure.
---
### Gizmos
#### Overview[β](#overview "Direct link to Overview")
Gizmos are a tool used in Unity which accompany each component as a visual aid.
Gizmos are a tool used in Unity which accompany each component as a visual aid.
For building in a scene, you will be using these tools:
* Pan
* Move
* Rotate
* Scale
* Rect Tool
Apart from Pan, all of these tools use gizmos to make it easier for you to transform your objects.
#### Move Gizmo[β](#move-gizmo "Direct link to Move Gizmo")
You can freely move your object around with the square inside the gizmo by grabbing it, or you can constrict the movement to up, down, left or right by using the arrows attached to the gizmo.
#### Rotate Gizmo[β](#rotate-gizmo "Direct link to Rotate Gizmo")
Using the green rotate line will rotate the object either clockwise or anti-clockwise on a 180 degree angle. If you use the red rotate line, this will tip the object upwards or downwards. If you use the blue rotate line, this will rotate the object on a 90 degree angle.
#### Scale Gizmo[β](#scale-gizmo "Direct link to Scale Gizmo")
You can use the white square on the scale gizmo to scale the object across all three axis simultaneously. You can use the green square to scale the object on the Y axis, use the blue square to scale the object on the Z axis and use the red square to scale on the X axis.
#### Rect Tool Gizmo[β](#rect-tool-gizmo "Direct link to Rect Tool Gizmo")
The Rect Tool can be used to move, resize and rotate objects. You can move an object by clicking inside the rectangle and drag it anywhere. You can resize it by clicking on the edges or corners and dragging. An object can be rotated by hovering the cursor slightly away from the corners until the mouse cursor looks like a rotation symbol. You can then click and drag in either direction to rotate.
#### Gizmo Settings[β](#gizmo-settings "Direct link to Gizmo Settings")
There is a gizmo dropdown menu on the top of the scene and game windows.
When this menu is opened, it will show options to Show Grid and change the size of the gizmo/3D icon, and also show a list of the components in Unity with a check box next to them. If you uncheck the boxes, this will disable the gizmo for the chosen component.
For example, if you want to turn off the gizmo for lights in the scene, uncheck the Light from the components list. This will hide the icon for Light.
---
### Importing 3D Models
#### Overview[β](#overview "Direct link to Overview")
You can import 3D models you have made or downloaded from 3D model sites into Unity.
You can import 3D models you have made or downloaded from 3D model sites into Unity.
The recommended formats are FBX or OBJ; if you are importing skinning (weighting) information, we recommend using .FBX, however .Blend and .DAE will import skinning data as well.
The simplest and easiest way to import your 3D file is to simply drag and drop the file into your unity project assets directory.
The directory will be where you saved the project after creating one initially during the installation of the Editor Pack.
When you open Unity, the file will be in your Assets folder. You can create a new folder for the item by right clicking in the Assets folder, and choosing **Create>Folder**.
You can then follow the guides and tutorials on the wiki to build regions or upload your clothing items to space.
---
### Importing Assets from the Asset Store
#### Overview[β](#overview "Direct link to Overview")
To import assets from the asset store, first go to the Asset Store either directly from within Unity program, or from the website Asset Store You can find the Asset Store within Un
To import assets from the asset store, first go to the Asset Store either directly from within Unity program, or from the website [Asset Store](https://www.assetstore.unity3d.com/en/) You can find the Asset Store within Unity here:
You can search for an item using the search bar or by using the categories on the right hand side of the Asset Store page to find an item.
If you are using the Asset Store website, the item you have chosen will have a **Open in Unity** button next to its' image.
Click on the button, and the browser you are using will ask for permission to launch Unity. Accept this and Unity will open.
Your chosen item will now appear in the Asset Store within Unity, and the button next to the item will now say **Download**.
If you are using the Asset Store from within Unity, the item will already say **Download**.
Click on **Download**. Read and accept the Terms and Conditions. This will start the download of your item.
Once the download has finished, an Import Unity Package window will pop up. Make sure all of the items are selected for the import, other wise your item might not work correctly.
Click on the **Import** button.
This will import the item to its' own folder inside of your project.
---
### Morph Shapes
#### Overview[β](#overview "Direct link to Overview")
MORPH SHAPES TUTORIAL Prequisites You are expected to have installed Unity and a valid Editor Pack installed correctly ( called SDK on Unity's Asset Store).
###### MORPH SHAPES TUTORIAL[β](#morph-shapes-tutorial "Direct link to MORPH SHAPES TUTORIAL")
#### Prequisites[β](#prequisites "Direct link to Prequisites")
You are expected to have installed Unity and a valid Editor Pack installed correctly ( called SDK on Unity's Asset Store).
#### Creating the Morph Shape[β](#creating-the-morph-shape "Direct link to Creating the Morph Shape")
You will be using our avatar model in your 3D modelling tool of choice. You will find it included in our Editor Pack.
Here we use Blender which is free to use. This is the default start scene in Blender.
Delete cube, lights and cameras - we don't need those.
Go to File and Import, then pick FBX.
Here is the import window.
You should see this. Click off and on the model and click the Collections icon here:
Now delete the existing Morph Keys.
We now add two morph keys - clicking the plus sign. The first will be our 'Basis' and the second our new morph.
While on that new morph, double click to rename
Now ensure the value is set to 1.
Now switch to Sculpting mode.
After my changes here is our face morph.
That's it for the Blender part. Now we export to FBX.
#### Export FBX From Blender[β](#export-fbx-from-blender "Direct link to Export FBX From Blender")
Go to File then Export then FBX.
Make sure your export settings are the same as this. Do ensure !Expermintal! Apply Transform is checked and Bake Animation is unchecked.
Then click Export.
#### Import FBX into Unity[β](#import-fbx-into-unity "Direct link to Import FBX into Unity")
Now we switch to Unity. Here we have an empty scene ready and a work folder created called "Morph Tutorial Folder".
You of course, should use your own recognisable name.
With this folder selected, right click in the empty right hand pane of your project and select Import Asset.
Locate your folder where you exported the modified 2017 Male into. First go to Assets.
Then go to your work folder and import the model.
Here our model is now imported into the project.
#### Checking Our Morph Has Imported[β](#checking-our-morph-has-imported "Direct link to Checking Our Morph Has Imported")
Drag the model into the scene/hierarchy and expand the model to see its child objects. Check the mesh has a skinned renderer and that you
can see your morph name.
Dialling this to 100 will reveal your morph. Leave it set at 100.
#### Creating the Vertex Displacement Map[β](#creating-the-vertex-displacement-map "Direct link to Creating the Vertex Displacement Map")
Open the menu item: Sinespace->Tools->Custom Shapes->Create Body Morph Texture
Now click into the Assets folder and then into your work folder.
You will now see the Create Morph Map dialog box.
Drag the mesh (from the project) into the top slot.
Put a checkmark into Preview and Overwrite Silently then click Bake Map.
Type the name of your morph into the "Original Blendshape" field.
Uncheck Incorporate Normal.
Set preview options.
In your project search box, type 2017 and drag the 2017 Male file into the Alternative Avatar slot.
The reason we do not use the Base Avatar for preview is that this defaults to the Male version and cannot be used for
a Female morph. Therefore it's better to get into the habit of locating the individual 2017 Male/Female avi's manually.

Click on your work folder in the project and then click Bake Map.
A preview of your morph will show in the scene. Move the original out of the way to compare that they are the same.
Now click on the new displacement map in your project work folder. Ensure sRGB is off, Read/Write is enabled, Generate Mipmaps off, Wrap Mode is Clamp,
Filter Mode is Point. No compression.
Then click Apply.
You might see some very subtle pastel RGB shadings but Unity cannot show the preview properly for the morph map generated.
Here's what it looks like in Krita.
#### Creating The Virtual Good[β](#creating-the-virtual-good "Direct link to Creating The Virtual Good")
Now we get to the final step - creating the virtual good. Right click an empty part of the hierarchy and create an empty game object.
Rename your game object to something recognisable. Add a Clothing Item Settings component.
Tick and expand Body Slider. Then drag the generated morph texture into the Vertex Displacement Map slot. Ensure the skeleton is set to Base Male.
Add a virtual good component.
Set the type to Clothing and the category to Clothes / Body / Morphs.
After completing that, drag your item from the hierarchy to your project. Right clik it then select Upload to Sinespace.
#### The Result[β](#the-result "Direct link to The Result")
Here's the finished item in world, called "Morph Tutorial" and is available free in the shop.
---
### Post Processing
#### Overview[β](#overview "Direct link to Overview")
Post Processing allows different effects and lighting to be added to your scene or region.
Post Processing allows different effects and lighting to be added to your scene or region. There are number of different settings, which we will explain here, and also show you how to create a Post Processing Profile in your scene in Unity, including how to enable real time editing of the settings. Space Post Processing profiles also adds volumetric lighting to these settings.
When you have your scene open in Unity with your region layout, you can add a Post Processing Profile. This is the profile which includes all of the different effects and the effect settings.
To add this profile, right click in your project window and go to Create>Space Post-Processing Profile. Click on the profile in the project window, and under the inspector window, you will see this:
These are all the different effects included in the post processing profile. You can toggle the settings on and off by clicking on the small circle next to the effect name.
For more information on what all of these effects are, you can go to the [Unity Post Processing Stack](https://docs.unity3d.com/Manual/PostProcessing-Stack.html) page and see each effect and their settings individually.
#### Real time editing of post fx[β](#real-time-editing-of-post-fx "Direct link to Real time editing of post fx")
To see real time edits of post fx settings in your region, first add a player character in to your scene. You can add a player character by typing in the project window search bar, and select the 'player character.'
Once the player character is in your scene, you can move it around until it is in the right place for you. Make sure you have deleted the main camera from your scene as well, as you will use the player characters' camera for the real time edit preview, and not the main camera.
Click on the drop-down arrow next to the player character in the Inspector window. Click on Main Camera in the list.
Under the Inspector window, there will be a lot of different scripts, but scroll down on the Inspector window until you get to a script called Post Processing Behavior. Drag the Post Processing Profile you just made from your Project window into this script.
Once this is done, click on 'Play' at the top of Unity. Once it has started to play the scene, drag the Post Processing Profile into the Post Processing Behavior script again.
Switch to the Game window, then click on your Post Processing Profile. Here you can toggle the post fx on and off, and play around with the settings, and in the Game window, you will see the changes happening in your scene!
#### Uploading a scene with post fx[β](#uploading-a-scene-with-post-fx "Direct link to Uploading a scene with post fx")
To make sure that the post fx stay in your scene/region during upload, you need to add an empty game object into your scene. To add the empty game object, right click in the hierarchy and choose Create Empty. With the empty game object selected in the hierarchy, go to the Inspector window, and click on 'Add Component' and search for PostZone script.
Drag the Post Processing Profile into the Post Profile box, as shown highlighted in the image above. Once this is done, you can upload the region as normal.
---
### Volumetric Lighting
#### Overview[β](#overview "Direct link to Overview")
Volumetric Lighting documentation for Sinespace.
[YouTube video player](https://www.youtube.com/embed/52uMeVJ2ePo)
---
### Scripting
#### [ποΈScripting Data](/sinespace-sdk/scripting/scripting-data.md)
[The Scripting Data components allow you to attach properties to an object without having the full Scripting Runtime.](/sinespace-sdk/scripting/scripting-data.md)
---
### Scripting Data
#### Overview[β](#overview "Direct link to Overview")
.png>) The Scripting Data components allow you to attach properties to an object without having the full Scripting Runtime.

The Scripting Data components allow you to attach properties to an object without having the full Scripting Runtime. This can be useful when objects are created dynamically at runtime or meant to be interchangeable. Together with the Scripting Resources and Scripting Events components, you can effectively emulate the ability to create custom Unity components on an object with unique behaviors, properties, and resources attached to them.
#### Fields[β](#fields "Direct link to Fields")
###### Data Variables[β](#data-variables "Direct link to Data Variables")
add variables here.
###### Component Name[β](#component-name "Direct link to Component Name")
the unique name field.
---
### Scripting Events
#### Overview[β](#overview "Direct link to Overview")
The Scripting Events components allow you to attach events to an object without having the full Scripting Runtime.

The Scripting Events components allow you to attach events to an object without having the full Scripting Runtime. This can be useful when objects are created dynamically at runtime or meant to be interchangeable. Together with the Scripting Resources and Scripting Events components, you can effectively emulate the ability to create custom Unity components on an object with unique behaviors, properties, and resources attached to them.
#### Fields[β](#fields "Direct link to Fields")
##### Events[β](#events "Direct link to Events")
The number of event elements
##### Element[β](#element "Direct link to Element")
###### Name[β](#name "Direct link to Name")
The name of the element that can be used to call the element via code.
###### Event ()[β](#event- "Direct link to Event ()")
The event
##### Usage[β](#usage "Direct link to Usage")
Drag a object into the Object field and select a function for that object or a component attached to the object
---
### Scripting Resources
#### Overview[β](#overview "Direct link to Overview")
The Scripting Resourse components allow you to attach resources to an object without having the full Scripting Runtime.
![]()
The Scripting Resourse components allow you to attach resources to an object without having the full Scripting Runtime. This can be useful when objects are created dynamically at runtime or meant to be interchangeable. Together with the Scripting Resources and Scripting Events components, you can effectively emulate the ability to create custom Unity components on an object with unique behaviors, properties, and resources attached to them.
#### Fields[β](#fields "Direct link to Fields")
##### Component Name[β](#component-name "Direct link to Component Name")
The component name
##### Resources[β](#resources "Direct link to Resources")
The number of event elements
##### Element Name[β](#element-name "Direct link to Element Name")
The name of the element that can be used to call the element via code.
##### Element Object[β](#element-object "Direct link to Element Object")
The resource itself
#### Usage[β](#usage "Direct link to Usage")
Drag a resource object into the Object field
---
### Scripting Runtime
#### Overview[β](#overview "Direct link to Overview")
Fields Public Exposed Variables These are variables you want to be exposed to edit in edit room.

#### Fields[β](#fields "Direct link to Fields")
Public Exposed Variables These are variables you want to be exposed to edit in edit room.
Component Name The reference name of your script
#### Source Code[β](#source-code "Direct link to Source Code")
Script Contents Your code.
Script Your code as a LUA file.
Script Libraries Your code functions in a text file.
Script Libraries 2 Your code functions in an LUA file.
#### Execution Options[β](#execution-options "Direct link to Execution Options")
Default Events Should be named functions such as OnUpdate, OnFixedUpdate, etc be handled implicitly?
Reset Behaviour: Whether to reset on scene change or not
Allow Runtime Script Editing: Allows the user to edit this script at runtime. Be aware runtime modified scripts are subject to additional sandboxing on the live environment.
Debugger Attaches the VS Code Debugger, not usable on the live server. Will work in uploads. Beware, allowing debugging will allow \_any\_user to debug your script. Enabling the debugger will disable infinite loop protection, and maximum execution length aborts.
Await the debugger: Wait for the debugger
Wait for Player: This script will hold execution until the player has arrived in the scene. Scripts which do setup (i.e. procedural content) may want to execute straight away.
Wait For Network: This script will hold execution until the payer has arrived and the scene is connected to the network server.
Max Script Executions Per Tick: The maximum number of script calls that can occur per frame. Use coroutines to run something across multiple frames
Index Indicates how arrays should be indexed. Defaults to Lua Standard (Index from 1).
Load Libraries Sequentially Loads libraries one at a time, which is faster and gives better debug messages, if you use local variables that span across libraries, you cannot use this method.
#### Unity Interfaces[β](#unity-interfaces "Direct link to Unity Interfaces")
Resources Here you add resources used by your script (e.i. Materials, audio files, textures, etc)
Events Here you create events that can be accessed (initialised) by your code.
Object References Here you add objects that exist in the scene that you need to access using code.
---
### Extensions
#### Overview[β](#overview "Direct link to Overview")
List of 3rd party whitelisted extensions (such as Unity Asset Store items) | **Extension Name** | **Summary** | **Link** | **Works?** | **Officially supported?** | **Notes** | | --
List of 3rd party whitelisted extensions (such as Unity Asset Store items)
| **Extension Name** | **Summary** | **Link** | **Works?** | **Officially supported?** | **Notes** |
| --------------------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ---------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| AltTrees System | Terrain/Tree Placement | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/76657) | **Yes** | **No** | Requires editor pack 9.8 onwards |
| Amplify Shader Editor | Node-based Shader Tools | [Asset Store](https://assetstore.unity.com/packages/tools/visual-scripting/amplify-shader-editor-68570) | **Yes** | **No** | Appears to work |
| Archimatix Pro | Procedural/Parametric Building Tools | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/59733) | **Yes** | **Yes** | Works - and can be used to create objects that can be edited in-world! |
| AQUAS Lite | Water System | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/53519) | **Yes** | **Yes** | Gaia compatible |
| AQUAS | Water/River System | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/52103) | **Yes** | **Yes** | Gaia compatible |
| Bird Flock Bundle | Bird Flock Simulator | [Asset Store](https://assetstore.unity.com/packages/3d/characters/animals/bird-flock-bundle-25576) | **Yes** | **No** | Appears to work |
| Bird Flock Bundle 2 | Bird Flock Simulator | [Asset Store](https://assetstore.unity.com/packages/3d/characters/animals/bird-flock-bundle-2-71740) | **Yes** | **No** | Appears to work, tropical bird collection *(seen in Welcome Center)* |
| CTS (Complete Terrain Shader | Terrain Shaders | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/cts-complete-terrain-shader-91938) | **Yes** | **No** | Gaia compatible |
| Erosion Brush | Terrain tools | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/27389) | **Yes** | **No** | Appears to work |
| FBX Exporter | File Export Utility | [Asset Store](https://assetstore.unity.com/packages/essentials/fbx-exporter-101408) | **Yes** | **No** | Appears to work |
| Fish School Bundle | Fish School Simulator | [Asset Store](https://assetstore.unity.com/packages/3d/characters/animals/fish-school-bundle-31110) | **Yes** | **No** | Appears to work |
| Fog Volume | Fog/Cloud Effects | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/81802) | **Yes** | **Yes** | Works, see [this thread](https://forum.sine.space/threads/fog-volume-3-asset-how-to-setup-camera-for-sinespace.17281/) on the Sinespace forum for more info. |
| Gaia | Procedural terrain tools | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/42618) | **Yes** | **No** | Appears to work |
| Gem Shader | Shader | [Asset Store](https://assetstore.unity.com/packages/vfx/shaders/gem-shader-3) | **Yes** | **No** | Appears to work |
| HerdSim | Animal Roaming Simulator | [Asset Store](https://assetstore.unity.com/packages/3d/characters/animals/herdsim-26648) | **Yes** | **No** | Appears to work |
| Landscape Auto Material | High quality terrain shaders | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/64132) | **Yes** | **Yes** | Works on Desktop class platforms only |
| LVE - Lava & Volcanic Environment | Flowing Lava/Volcanic Environment Assets | [Asset Store](https://assetstore.unity.com/packages/3d/environments/l-v-e-lava-volcano-environment-112703) | **Yes** | **No** | Appears to work |
| MapMagic World Generator | Procedural Terrain System | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/56762) | **Yes** | **No** | Make sure to uncheck infinite terrain, and pin the terrain tiles you want to appear in Sinespace. |
| MicroSplat Core | Terrain Shaders | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/microsplat-96478) | **No** | **No** | Approved, but support has not yet been added. Does not support the rivers/streams module. Supported version is 2.4+. Other versions likely work. |
| MicroSplat Tessellation Module | Terrain Shaders | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/microsplat-tessellation-and-parallax-96484) | **Yes** | **No** | Appears to work |
| MicroSplat Anti-tiling Module | Terrain Shaders | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/microsplat-anti-tiling-module-96480) | **Yes** | **No** | Appears to work |
| MicroSplat Global Texture Module | Terrain Shaders | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/microsplat-global-texturing-96482) | **Yes** | **No** | Appears to work |
| MicroSplat Snow | Terrain Shaders | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/microsplat-dynamic-snow-96486) | **Yes** | **No** | Appears to work except footsteps |
| MicroSplat Terrain Holes Module | Terrain Shaders | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/microsplat-terrain-holes-97495) | **Yes** | **No** | use our own "Terrain Hole Punch" script instead of the AlphaHolePhysics one supplied |
| MicroSplat TriPlanar UVs | Terrain Shaders | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/microsplat-triplanar-uvs-96777) | **Yes** | **No** | Appears to work |
| MicroSplat Texture Cluster | Terrain Shaders | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/microsplat-texture-clusters-104223) | **Yes** | **No** | Appears to work |
| MicroSplat Wind and Glitter | Terrain Shaders | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/microsplat-wind-and-glitter-105627) | **Yes** | **No** | Partial support, no support for Glitter Light script |
| Multiple Terrain Brush | Terrain tools | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/44037) | **Yes** | **No** | Appears to work |
| Noise Brush | Terrain tools | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/28672) | **Yes** | **No** | Appears to work |
| Octave3D | Prefab Management/Placement Tool | [Asset Store](https://assetstore.unity.com/packages/tools/level-design/octave3d-level-design-45021) | **Yes** | **No** | Appears to work |
| PA Particle Field | Volumetric particle fields | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/33271) | **Yes** | **Yes** | Desktop & Console platforms only |
| Path Painter | Terrain Tools | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/path-painter-127506) | **Yes** | **No** | Gaia compatible, Appears to work |
| PolyBrush | In-Editor 3D Modelling | [Asset Store](https://assetstore.unity.com/packages/3d/polybrush-beta-111427) | **Yes** | **No** | Free! Recently acquired by Unity, will be integrated into Unity Editor in future releases but currently must be purchased as free asset. |
| ProBuilder | In-Editor 3D Modelling | [Asset Store](https://assetstore.unity.com/packages/tools/modeling/probuilder-111418) | **Yes** | **No** | Free! Recently acquired by Unity, will be integrated into Unity Editor in future releases but currently must be purchased as free asset. |
| ProGrids | In-Editor 3D Modelling | [Asset Store](https://assetstore.unity.com/packages/3d/progrids-111425) | **Yes** | **No** | Free! Recently acquired by Unity, will eventually be integrated into Unity Editor but currently must be purchased as free asset. |
| RAM (River Auto Material) | River/Water Solution | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/r-a-m-river-auto-material-101205) | **Yes** | **No** | Gaia compatible |
| Real Ivy | Procedural Ivy Tool | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/86134) | **Yes** | **No** | Appears to work |
| Relief Terrain Pack | Terrain Shaders | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/5664) | **Yes** | **No** | Appears to work |
| SpeedTree | Tree & Plant Modeller (external program) | [Website](http://www.speedtree.com/) | **Yes** | **No** | Modeler allows you to create your own trees, as well as edit existing SpeedTrees. Note, the trees themselves (SpeedTrees files) work natively in Unity. |
| Suimono | Interactive Water Solution | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/4387) | **Yes** | **Yes** | Works but has a number of unresolved issues, see [this thread](https://forum.sine.space/threads/suimono-and-sinespace.17184/#post-18172) on the Sinespace forum for more info. |
| Super Pivot FREE | Editor Utility | [Asset Store](https://assetstore.unity.com/packages/tools/utilities/super-pivot-free-modifier-104882) | **Yes** | **No** | Free! basic pivot point adjustment tool, Appears to work |
| Super Pivot PRO | Editor Utility | [Asset Store](https://assetstore.unity.com/packages/tools/utilities/super-pivot-pro-modifier-74211) | **Yes** | **No** | Full-featured pivot point adjustment tool, Appears to work |
| TerrainComposer 2 | Procedural terrain tools | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/65563) | **Yes** | **No** | Appears to work |
| UModeler Trial Version | In-Editor 3D Modelling | [Asset Store](https://assetstore.unity.com/packages/tools/modeling/umodeler-2-0-free-trial-111465) | **Yes** | **No** | Limited version in-editor 3D modeling tool. |
| UModeler | In-Editor 3D Modelling | [Asset Store](https://assetstore.unity.com/packages/tools/modeling/umodeler-2-0-80868?aid=1011l36n8) | **Yes** | **No** | Powerful in-editor 3D modeling and prototyping software with 90 tools to help make creating, transforming and editing your model a breeze in Unity. |
| UMotion Community | Animation Editor | [Asset Store](https://assetstore.unity.com/packages/tools/animation/umotion-community-animation-editor-95986) | **Yes** | **No** | Animation Editor, appears to work. |
| UMotion Pro | Animation Editor | [Asset Store](https://assetstore.unity.com/packages/tools/animation/umotion-pro-animation-editor-95991) | **Yes** | **No** | Animation Editor, appears to work. |
| USequencer | Powerful cutscene editing | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/3666) | **Yes** | **Yes** | Supported until 2018. Some items (e.g. Load Level) unsupported. |
| Vegetation Studio | Tree/Vegetation Shaders | [Asset Store](https://assetstore.unity.com/packages/tools/terrain/vegetation-studio-103389) | **Yes** | **No** | Approved, but support has not yet been added. |
| Vertex Paint | Vertex Editing Tool | [Github](https://github.com/slipster216/VertexPaint) | **Yes** | **No** | Appears to work |
| Visualizer Studio | Audio visualization | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/1761) | **Yes** | **Yes** | Officially supported, can use built-in space equivalents as well. |
| Volumetric Crystal Materials Pack | Gem Shaders | [Asset Store](https://assetstore.unity.com/packages/vfx/shaders/substances/volumetric-crystal-materials-pack-105951) | **Yes** | **No** | Appears to work |
| Voxeland | Volumetric terrain tools | [Asset Store](https://www.assetstore.unity3d.com/en/#!/content/9180) | **Yes** | **No** | Works for non-infinite terrains. Make sure to use 'Save data to .asset' before uploading. |
| World Machine | Procedural terrain tools (external program) | [Website](http://www.world-machine.com/) | **Yes** | **No** | Appears to work |
---
### Setup
#### [ποΈLink Space and Unity](/sinespace-sdk/setup/link-space-and-unity.md)
[Link Space and Unity Get API Key Log in with your Space account at https://curator.sine.space/ Go to Settings / API keys.](/sinespace-sdk/setup/link-space-and-unity.md)
---
### Creating a New Folder inside Project
#### Overview[β](#overview "Direct link to Overview")
In the Project window, there will be a list of folders.
In the Project window, there will be a list of folders.
To create a new folder within this project, simply click on the **Create** button and choose Folder from the menu, OR right click the main folder, and choose **Create** then Folder.
If you have the Editor Pack as your project, always make sure you make a new folder within the **Assets** folder for anything you are modelling.
---
### Creating a Project
#### Overview[β](#overview "Direct link to Overview")
When Unity is started on your PC, a pop up window will appear.
When Unity is started on your PC, a pop up window will appear.
This is where you create a new project. To create a new project, click on the **New** button. Put in a project name and choose a location for the project files to go. **Choose 3D** for the assets. Click **Create Project**.

---
### Creator signup through SDK
#### Overview[β](#overview "Direct link to Overview")
If you are ready to upload content from Unity and "have not" created your avatar account yet you can do so within Unity If you have already made a creator account, you do not need
If you are ready to upload content from Unity and "have not" created your avatar account yet you can do so within Unity
If you have already made a creator account, you do not need to make one, you can just sign in with our editor pack you installed in Unity.
Once it is installed, to make your Creator account, click on the 'Sinespace' button on the Unity top bar then 'Sign In'.

In the Inspector, you will see the Sinespace Login Information, along with a button 'Create an account'. Click on this button.

It will take you to the Creator signup page. Here you can choose a default avatar and enter a username, your email address and password. Once you have clicked on the 'Join now' button, it will take you to the viewer download page. Once here, click on the 'Become a Creator'. Fill in all the information under the 'Join our creator program' section. Because you have already made an account, it will auto-fill your email address. Once this is filled in, click on the Join Creator Program button, and you're now a Creator!
You can go back to the Sign in option in Unity and use your username and password to log in. This will generate a unique API key which enables uploading to Sinespace.
---
### Creator signup through web
#### Overview[β](#overview "Direct link to Overview")
If you already have an avatar account skip to Step2 Step 1.Make a creator account To become a creator, visit our Creator Signup page.
#### If you already have an avatar account skip to Step2[β](#if-you-already-have-an-avatar-account-skip-to-step2 "Direct link to If you already have an avatar account skip to Step2")
#### Step 1.Make a creator account[β](#step-1make-a-creator-account "Direct link to Step 1.Make a creator account")
To become a creator, visit our [Creator Signup](https://sine.space/creator/) page.
Scroll down until you see this box, and click on the button highlighted in red:
This will take you to the signup page. On here, choose your avatar from the left hand side (you can scroll through the choices with the arrows) and on the right hand side you can enter a username, email address and password. Please make sure you use an active email address as we will send you a verification email here. Click the Join now button when you have entered the information.
This will take you to the Download page. You can download the viewer from here, but you will also need to click on the 'Become a Creator' button:
This will take you to the Creator page. Once here, you can fill in all the information under the 'Join our creator program' section. Because you have already made an account, it will auto-fill your email address. Once this is filled in, click on the Join Creator Program button, and you're now a Creator!
#### Step 2.Install Unity Editor[β](#step-2install-unity-editor "Direct link to Step 2.Install Unity Editor")
See [Unity Installation](/quickstart-sinespace-viewer/get-started-sdk/sdk-setup.md) for the current version and installation walk through. **Please note: we use a specific version (or range of versions) of the Unity editor, see the [Unity Installation](/quickstart-sinespace-viewer/get-started-sdk/sdk-setup.md) page for more details. Other versions may not work.**
#### Step 3.Download and install the Space Editor Pack[β](#step-3download-and-install-the-space-editor-pack "Direct link to Step 3.Download and install the Space Editor Pack")
The Space Editor Pack is an add-on for Unity which allows you to upload your content to Sinespace and contains all of the necessary components you will need for various content. You can find the Editor Pack versions and installation guide on our [Editor Pack](/sinespace-sdk/setup/download-editor-pack.md) page.
#### Step 4.Enable Editor Pack Settings[β](#step-4enable-editor-pack-settings "Direct link to Step 4.Enable Editor Pack Settings")
With the editor pack now installed, you will see a new button called 'space' in the top menu.
click on Space / Install Editor Pack Settings to enable the editor pack settings.
#### Step 5.Sign in to space in your Unity project[β](#step-5sign-in-to-space-in-your-unity-project "Direct link to Step 5.Sign in to space in your Unity project")
In the top menu, click Sinespace -> Sign in...
Then in the Inspector window on the right log in with the username and password you created at sine.space (above). You might have to switch from the Services window to the Inspector window.
In the next screen Add your real name, a business name if you have one, review and accept the EULA for content creators.
[End User License Agreement](/policies/end-user-license-agreement.md)
1. Accepting the EULA will allow you to access the creator server. Until you complete this step you will only have access to the live server.
#### Step 6. Upload a sandbox region[β](#step-6-upload-a-sandbox-region "Direct link to Step 6. Upload a sandbox region")
[Watch on YouTube](https://youtube.com/watch?v=Lmh5VWBsJB8)
Follow the video tutorial on how to set up a basic region to use as a sandbox region.
1. Congratulations! You are now ready to create and upload content to Sinespace!
#### Getting Help[β](#getting-help "Direct link to Getting Help")
We're happy to assist , just grab us in our [Discord Channel](http://discord.gg/sinespace). We have various channels that both staff and fellow creators can help you with questions.
---
### Download Editor Pack
#### Overview[β](#overview "Direct link to Overview")
Installing the editor pack 1. To install the editor pack you will need to have installed the Unity editor.
#### Installing the editor pack[β](#installing-the-editor-pack "Direct link to Installing the editor pack")
1. To install the editor pack you will need to have installed the Unity editor. Please see [SDK Setup](/quickstart-sinespace-viewer/get-started-sdk/sdk-setup.md) to check information on Unity versions
To access the SDK/Editor pack you will need to [create an account](https://id.unity.com/en/conversations/70ea6f07-b73b-4b6e-b1a2-80e02aa2777f002f) with Unity to access the Unity Asset Store.
You can download directly from the [Asset Store](https://assetstore.unity.com/packages/templates/systems/sinespace-137731) and add to your list of available assets or in your open unity project.
When you have an asset in your available list you will see an import button in the asset store tab within Unity instead of a download and then import.
To download from your open Unity project, click on the Asset store tab, you will need to be logged into your Unity account, search for Sinespace and download the SDK package. Press the download button, when it has downloaded, click on the Import button.
When the Import Unity Package window comes up, **leave everything ticked **and click on the Import button. When it is ready to import it will ask if you want to install the Editor Pack. Click on the Install Editor pack button when it asks.
It will ask again to Import, click on the Import button. It will import all of the files needed. You may have to press the restart button if promoted to. You could be asked to restart a few times to fully install the Editor Pack, this is normal.
When it has imported fully, click on the Sinespace button at the top of Unity. Click on 'Install editor pack settings'. Once this is done, you can click on Sinespace again and click on 'Sign in'. Use the username and password you used to sign up for Sinespace creator here as this will allow you to upload your content to Sinespace.
#### Editor pack versions[β](#editor-pack-versions "Direct link to Editor pack versions")
* Please do bear in mind that the SDK/Editor Pack does include Unity version 2018.3 however the relevant editor pack is experimental\*\*.
#### Attention Mac users[β](#attention-mac-users "Direct link to Attention Mac users")
After the Editor Pack has been installed, you will either need to install the Native Mac Uploader *(recommended)* or the legacy mono framework version 4.8.0.382 *(click [here](https://download.mono-project.com/archive/4.8.0/macos-10-universal/MonoFramework-MDK-4.8.0.382.macos10.xamarin.universal.pkg) to download).* Installing the Native Mac Uploader is easy, simply click on the **\_SineSpace --> Tools --> Install --> Native Mac Uploader**\_ menu option. This process will take a little time, but should be completely automated and you will receive a message once the uploader has been successfully installed.
---
### Link Space and Unity
#### Overview[β](#overview "Direct link to Overview")
Get API Key Log in with your Space account at Go to Settings / API keys.
#### Get API Key[β](#get-api-key "Direct link to Get API Key")
Log in with your Space account at
Go to Settings / API keys.
Generate and API key and copy it.

#### Paste API Key[β](#paste-api-key "Direct link to Paste API Key")
Go to your Unity project and in the top bar menu select Space / Upload Settings.

This will open a field in the Inspector (usually on the right in Unity)

Paste your API here and click check to verify.
This links your Unity project to your account; everything you upload from the project will now go to the same account; that can be multiple scenes and other virtual goods.
---
### Re-importing the Editor Pack
#### Overview[β](#overview "Direct link to Overview")
You will need to re-import the Editor Pack if you have installed a newer version of Unity or if you have have upgraded to a newer version of the Space Editor Pack.
You will need to re-import the Editor Pack if you have installed a newer version of Unity or if you have have upgraded to a newer version of the Space Editor Pack.
To re-import the editor pack, first, navigate to the folder in which you have downloaded the Editor Pack.
Double click on the Editor Pack in this folder. This will open Unity, and a **Create Project** window will appear. Name the project, choose where it will be saved, *and choose 3D* (important!).
Click on **Create Project**.
Clicking on Create Project will open Unity, and Unity will start to prepare the Editor Pack package for import. Once this is done, you will have the Editor Pack installed again in Unity.
You can also open Unity, go to the top menu, choose Assets>Import Package>Custom Package and choose the Editor Pack from where it is saved after downloading.
This will start the prepare and import the same as the above way of re-importing, but an **Import Package** pop up will show, asking you to import items. Choose all of the items to re-import.
---
### Vehicles
#### Overview[β](#overview "Direct link to Overview")
Please notice there are two versions of script for Vehicles: the old ones are the scripts like "car physics", "car vehicle", which are obsolete; the new vesion is one script called
Please notice there are two versions of script for Vehicles: the old ones are the scripts like "car physics", "car vehicle", which are obsolete; the new vesion is one script called "Modular Vehicle", it combines all kinds of vehicle together(land, hover, boats) so you can adjust this one script for all types of vehicle settings. The new version resolved many bugs of the old version, so we recommand to use the new one. We will still keep the tutorial of old version in other pages, you can always check them if you need.
Note: This page is still updating so there may be some place incomplete during this moment.
##### Simple guide for a land vehicle[β](#simple-guide-for-a-land-vehicle "Direct link to Simple guide for a land vehicle")
To start create a land vehicle, you should find yourself a vehicle model.
To prepare a model for vehicle, whether you want create one using MAYA or 3DMAX or Blender, or find a model from Unity asset store, there are somethings you should pay attention to:
*Make sure the wheels are splited from the vehicle body. Some vehicle in asset store has a single FBX file combined all the things together, which makes the next steps quite impossible if we don't do something to the model.*
As an example, we choose a simple low-poly car in the asset store(which the server can proceed faster) like this:\\

You can always choose a vehicle more realistic and complex, but there may be more details need to adjust on your own.

Preparation:
Create and organise the objects for the vehicle like this:\\
Carbody is the body of the car, not including the wheels.
Seat is an empty object here, and it defines where your avatar sits in the car.
The wheel group contains the 4 wheels, and the wheel collider group contains the wheel colliders for each wheel.
*The positions of the wheel colliders need to adjust individually, so they should be created separately from the wheels. You can do it by creating an empty gameobject then adding a wheel collider component, duplicating 3 more, and renaming them.*
***
Choose the parent object of the whole car, then add a script named "Modular Vehicle". A rigidbody component will be added automatically as well.
As a simple guide, it will only show you how to make a car which can be driven in the game. There are a few more stuffs in the script settings but we will ignore them here.

Set the "Seat Root" with the seat gameobject, and Ride Animation you can get it from [Mixamo](https://www.mixamo.com/) freely.
The Mass will be the weight of your car, the value here only shows an example.
*Note: there is also a Mass property in Rigidbody component, change it to the same value.*
The Center of gravity concerns the stability of the vehicle. If you want to create a big truck, making it a little lower may be better(like (0, -1.25, 0)), otherwise just leave it to default.\\
These are the 'core forces' settings. They configure the vehicle 'overall'. Everything else is pretty much 'per wheel'.

Our example is a regular 4-wheel car, so we set the number of wheels as 4. If you are creating a vehicle with a different number of wheels, just enter the wheel number here -- and make the same number of wheel colliders.

This is a representative front wheel. The other uses the same values with its own transform and collider.

This is a representative rear wheel. Same for the values, it's just on the other side.

In this example, the front and rear wheel is in different size(it's a race car, somehow), so the mass and radius are different. For a normal car, they might be the same value.
This is the collider for the rear wheel. It will be the same on the other side. Differences are in the name and position on the model. This applies generally to all the wheel elements.

This is the collider for the front wheel.

After set the values, you should adjust its position and size manually. Make the radius match the size of wheel then modify the collider's postion to the center of the tire. Like this:
 
\\
If you want to add tire track, here's a image from the old version, but it's always the same way.

Finally, add a box collider in the parent object, make sure it doesn't have conflict with the wheel colliders.

Forget this will make your vehicle cannot trigger the clickable events(which equals cannot drive it).
Now you can add a virtual good component to the parent object to upload and test it.
***
*The hover points and boat forces are for hover type and boat type, which is still under testing now.*
##### Hover[β](#hover "Direct link to Hover")
*The example below is only a prototype, it can float and move, but the performance is not very satisfied. The value settings may be complex here, which may need you to adjust by yourself. Feel free to update this part if you find a more simple way to create a hover car.*\\
Same as the land type, we found another model from asset store, and just turn the tires 90 degree, like this:

There won't be other collider, so a box collider covers the whole car body is enough.
Its parts could be organized like this:

The four wheels here will be the 4 hover points, which will be defined later.\\
Like create a land type vehicle, just add a modular vehicle to the parent object.

*It seems there is a little bug that the mass in modular vehicle doesn't override the mass of rigidbody, so we use the mass value in rigidbody instead.*
These basic settings are same as the land type.
Core force settings:
   
*These values are experimental. Feel free to update it if you find a better example.*
Hover points:

Here need some physical tricks and calculations. The Unity physic system defines the Gravitational acceleration is 9.81 m/sΒ², we set the rigidbody mass is 100(the unit is kg, normally), so the weight is 9.81 \* 100 = 981 N. We have 4 hover points, so we seprate a up force of 981N to these 4 hover points, that is, each hover point take a 245.25N in up direction. This should keep the hover car float in the air. Of course, if you want to increase or decrease the number of hover points, you shoud modify the force each hover point too.\\
Add the virtual good component and upload it, now you can test it on the preview server.\\

***
##### Boat[β](#boat "Direct link to Boat")
PENDING
***
##### Events[β](#events "Direct link to Events")
If you want to add some additional functions to your vehicle, like the speed meter and rear-view camera which introduced below, please make sure that you've add the events control for them. For example if you want the function only active when the player drive the car and deactivate them when the player leave, you need to add events in the On Player Activate/Deactivate function block, like the image below:\\

***
##### Speed meter[β](#speed-meter "Direct link to Speed meter")
There is already a script called "speedometer" in the Editor Pack, all you need is create a UI Text Component under your vehicle object, and another empty game object with this speedometer component. Attach the rigidbody of the vehicle and the UI Text component to the slots of the speedometer, you can leave the rest option as it was, or fill it on your own request. Change the position and style of the UI Text as a normal UI element as you wish. And, remember, disabled the Canvas object at the beginning, and activate it by the events function as I present above.
A simple example here, is a meter with blue text in the right-bottom corner:\\

***
##### Custom Camera[β](#custom-camera "Direct link to Custom Camera")
Sometimes you may want set the camera for vehicle by yourself, or have several cameras to switch(you may need add custom script by using scripting runtime for the switch function though), like far view behind, close view behind, driver view, etc. To do this, you need to use the plug-in which is already contained in the Editor pack: Cinemachine Virtual Camera.
Simply create an empty game object in the vehicle object, and add the component Cinemachine Virtual Camera to it. Drag it to the Primary camera slot in Modular Vehicle, just like this:

If you want to add a second or more camera, just set the number of the Secondary cameras then drag the cameras to each slot, like the example above.
Don't forget to adjust the parameter of your virtual camera or it won't work, here is an example:

For the details of how to adjust the virtual camera and how to set those values here, check this [*tutorial video*](https://youtu.be/Sd7SmwF_X8U?t=1954).
And you also need to disable all of the Cinemachine Virtual Camera at the beginning, or it will bind your camera to them as soon as your vehicle is spawned.
***
##### Rear View[β](#rear-view "Direct link to Rear View")
You may also want add a rear view to your vehicle, so the driver can take a clear look of his behind. The method is simple:
First, in your assets folder, right click the mouse and create a new render texture.

Leave the settings as its default if you don't have any other request.
Second, create a new camera in the prefab. The normal camera, not the virtual one we used above.
Then rotate it horizontally, make it face to the behind of the vehicle, and move it to the end of the car, make sure there is nothing block the camera.
Drag the render texture we create to the Target texture slot. And disable the camera component.

Now in the canvas we used to show the speed meter, add a raw Image and attach that render texture into the slot:

And Finally in-game, we can get a simple rear view of the behind:\\

You can use image mask to add a form of rear mirror to make it look beautiful, for more information, take a look at this [*Unity Beginner Tutorial*](https://unity3d.com/learn/tutorials/topics/user-interface-ui/ui-mask).
***
##### Tutorial for obsolete vehicle script[β](#tutorial-for-obsolete-vehicle-script "Direct link to Tutorial for obsolete vehicle script")
[Land vehicles](/sinespace-sdk/vehicles.md)
[Aircraft and Gliders](/sinespace-sdk/vehicles.md)
[Hover Vehicles](/sinespace-sdk/vehicles.md)
[Watercraft and Boats](/sinespace-sdk/vehicles.md)
---
## Sinespace Viewer
### Sinespace Viewer
#### [πOutfits](/sinespace-viewer/outfits.md)
[1 item](/sinespace-viewer/outfits.md)
---
### Account
#### Overview[β](#overview "Direct link to Overview")
To become a Space creator you need to; 1.
To become a Space creator you need to;
1. Register at
2. Log in to the creator portal;
3. Download and install the Unity3D game engine;
4. Download and import the Space Editor Pack;
#### Sine.space[β](#sinespace "Direct link to Sine.space")
The Space virtual world has a live server;
This is where the Space community comes together. The live server has a real economy and is widely promoted to new users.
Space also has a preview server, where creator content can be reviewed before pushing to the live servers;
#### Creator portal[β](#creator-portal "Direct link to Creator portal")
The creator portal allows creators to buy regions in Space and to manage their income from the sale of virtual goods;
#### Unity3D[β](#unity3d "Direct link to Unity3D")
Creators can use the Unity3D game engine to upload their work; regions, clothing, gestures and numerous other types of virtual goods.
Unity is a powerful game engine that allows creators to build regions and virtual goods to the same quality standard as contemporary AAA game titles.
#### Space Editor Pack[β](#space-editor-pack "Direct link to Space Editor Pack")
The Space Editor Pack must be imported into Unity3D.
This will link the Unity project on the creator's desktop to their Space account. And it provides a wide range of tools to enable creators to build, productise and publish, share and sell their work.
---
### Auctions
#### Overview[β](#overview "Direct link to Overview")
Auctions Click the AUCTION button in the bottom menu to open the auction window.
#### Auctions[β](#auctions "Direct link to Auctions")
Click the AUCTION button in the bottom menu to open the auction window.
1. All Auctions
See everything being offered for auction and bid on items you like.
1. My Bids
Track items you are bidding for and raise your bids here.
1. My Auctions
Put any item from your inventory up for auction; perfect for unique items you have crafted inworld, including custom pets and customized clothing items.
---
### Audio Streaming
#### Overview[β](#overview "Direct link to Overview")
Audio Source - What audio can be streamed and where from?
##### Audio Source - What audio can be streamed and where from?[β](#audio-source---what-audio-can-be-streamed-and-where-from "Direct link to Audio Source - What audio can be streamed and where from?")
This could be some software on your PC or tablet or phone. It could also be an external music player such as an iPod or a record player with it's output going to your PC's Line-In socket. So long as Windows is playing it then that's what will be streamed.
Typically a DJ would use [VirtualDJ](https://www.virtualdj.com/download/) software. This is free for non-commercial use.
That's covered briefly how to play the audio.
##### The Streaming Software - So, we currently have our songs playing but what else do we need?[β](#the-streaming-software---so-we-currently-have-our-songs-playing-but-what-else-do-we-need "Direct link to The Streaming Software - So, we currently have our songs playing but what else do we need?")
Something needs to convert it to a true MP3 radio stream and then send it up to the internet. This is where software such as [WinAmp](https://download.nullsoft.com/winamp/client/winamp58_3660_beta_full_en-us.exe) comes in. WinAmp should be set to "Soundcard Input".
The other software needed is a DSP Shoutcast plugin, that converts the audio to be shoutcast compatible.
The DSP Plugin runs inside WinAmp, so install both - they are both free to use.
##### The Radio Stream Host.[β](#the-radio-stream-host "Direct link to The Radio Stream Host.")
So we're sending sound up to the internet, but where do we send it?
For this you will need to either use a free service (not recommended) or a paid service for a shoutcast radio stream. There are a few pieces of configuration information that you will get from here. This info will need to be entered into the DSP plugin above.
Crucially this will be login information to connect from your audio source (your PC's sound) to your stream and the settings you need to play your stream in Sinespace.
##### The Radio Stream Player - How do I get it to play in Sinespace?[β](#the-radio-stream-player---how-do-i-get-it-to-play-in-sinespace "Direct link to The Radio Stream Player - How do I get it to play in Sinespace?")
There are a number of ways. Firstly the ability to set your own region to a specific stream is now built into the viewer. Secondly, you might elect to just buy a furniture prop from the in-world shop that is a radio stream player. Third option would be to actually script your own radio player inside Unity using our SDK and making your own. Format of MP3 stream URL. The general rule is:-
Stream ip address : port number such as 203.432.32.345:7589
203.432.32.345 is the IP address and
7589 is the port number
Separated by a single colon. (:).
Sometimes the url supplied by the radio streaming company might not always conform with our players but we can usually find a way around that by restructuring the URL.
---
### Communication
#### Overview[β](#overview "Direct link to Overview")
Chat The chat system allows you to communicate with the entire virtual world, just people in your region or specific people.
#### Chat[β](#chat "Direct link to Chat")
The chat system allows you to communicate with the entire virtual world, just people in your region or specific people.
The world and region channels are always visible in your chat window. To open a chat with a specific individual, go to their PROFILE and click the CHAT button at the top.
#### Mail[β](#mail "Direct link to Mail")
You can send inworld email messages to anyone in Space, via the MAIL button in their PROFILE.
You can see notifications in the top right bar when you receive email messages.
#### Email attachments[β](#email-attachments "Direct link to Email attachments")
You can send attachments via email; this is a great way to share content; and you can add an offer price to an attachment so you can trade inworld.
#### Voice Chat[β](#voice-chat "Direct link to Voice Chat")
Voice Chat is only supported the Windows and Mac version now. The support for WebGL is still on developping, and Linux is not supported.
Click the sound source icon in the bottom left to enable voice chat. You will see a green icon above the heads of everyone in the region using chat.
You can click the head button in the avatar inspector to easily focus on the faces of people talking.
---
### Explore
#### Overview[β](#overview "Direct link to Overview")
Explore Click the EXPLORE button in the bottom tab to open the explore window.
#### Explore[β](#explore "Direct link to Explore")
Click the EXPLORE button in the bottom tab to open the explore window.
There are three categories for regions; 'Featured', 'Popular' and 'Friends'. The Featured list shows mostly Sinespace owned regions, but it does show some of the most popular creator regions as well. Popular is where you will find the most visited regions, and Friends will show all of your friends' homes and regions.
To enter one of these regions, click on the 'Enter' button next to the region image. To get back to the Welcome Center, you can click on 'Explore' again, find the Welcome Center and click on 'enter'. If you are wanting to find and visit a specific region, you can use the 'search bar' above the Featured, Popular and Friends tabs.
#### Friends' Regions[β](#friends-regions "Direct link to Friends' Regions")
You can also see a list of each of your friend's active regions by clicking the HOME button in their PROFILE.
Or by clicking EXPLORE (bottom menu) and then clicking the FRIENDS tab.
#### Region Info[β](#region-info "Direct link to Region Info")
---
### Friends
#### Overview[β](#overview "Direct link to Overview")
Making Friends You can friend someone via the ADD FRIEND button on their PROFILE.
#### Making Friends[β](#making-friends "Direct link to Making Friends")
You can friend someone via the ADD FRIEND button on their PROFILE.
You can open their PROFILE by clicking on them if you are both in the same region, and clicking MORE expanding the mini PROFILE in the top right corner of the screen.
#### Unfriending[β](#unfriending "Direct link to Unfriending")
Use the same button in any user's PROFILE to unfriend them.
#### Friends list[β](#friends-list "Direct link to Friends list")
The FRIENDS LIST shows all your friends and everyone in the same region as you.
FRIENDS LIST shows who is online and who is offline.
It also allows you to open the PROFILE of any friend.
You can also click from the friends list to go directly to the AVATAR INSPECTOR of anyone in the same region as you.
#### Friends' Regions[β](#friends-regions "Direct link to Friends' Regions")
You can see a list of each of your friend's regions by clicking the HOME button in their PROFILE.
Or by clicking EXPLORE (bottom menu) and then clicking the FRIENDS tab.
#### Teleporting Friends[β](#teleporting-friends "Direct link to Teleporting Friends")
Teleport friends to you via the TELEPORT button in their PROFILE.
---
### Hot Bar
#### Overview[β](#overview "Direct link to Overview")
Hot Bar You can drag any item from your inventory into the hotbar on your interface screen.
#### Hot Bar[β](#hot-bar "Direct link to Hot Bar")
You can drag any item from your inventory into the hotbar on your interface screen. You can also drag other items over existing ones on the hot bar to replace them.
This allows you to then launch that item instantly from the hotbar. This is great for gestures and dances, or for quick changes of clothing items such as attachments. (clothing items will need to be removed through the outfit tab)
***
---
### Inventory
#### Overview[β](#overview "Direct link to Overview")
Inventory Click inventory to review and use everything you own.
#### Inventory[β](#inventory "Direct link to Inventory")
Click inventory to review and use everything you own. You can click items to discard or to deploy them inworld; add clothing items to your avatar, launch gestures or spawn vehicles and other scene objects.
Some regions are set to prevent objects from spawning but you can launch gestures, including multi-person gestures, anywhere.
If you have just bought an item and you cannot immediately see it in inventory try clicking the refresh button in the top of the inventory window.
You will see all the clothing items you own in inventory; including items that are for skeletons or genders other than the one you are currently using.
---
### Keybindings
#### Overview[β](#overview "Direct link to Overview")
Here are few short cut keys that you can use in Space in Desktop build.
Here are few short cut keys that you can use in Space in Desktop build.
* Note\*\*: we will be adding more short cut keys and update here.
#### Flying[β](#flying "Direct link to Flying")
To start flying you can press "**R**" key.
Once your character is hovering press "**E**" Key to go higher, or "**C**" to go Lower.
You can hold **Shift** key while flying to fly faster; same key can be used while walking to run.
#### Show Performance of a region[β](#show-performance-of-a-region "Direct link to Show Performance of a region")
This is a hidden key which shows a profiler showing the performance of a region.
To toggle this window Hold "**Shift**" Key and press **\`** Key.
#### Toggle Full screen[β](#toggle-full-screen "Direct link to Toggle Full screen")
To toggle Space between fullscreen and windowed mode press **F11** Key(Windows), Command(Γ’ΕΛ) + F(Mac OS).
#### Toggle UI[β](#toggle-ui "Direct link to Toggle UI")
Press the F9 key or Alt+U to toggle the user interface on/off.
#### Additional Short Cut Keys[β](#additional-short-cut-keys "Direct link to Additional Short Cut Keys")
F1: Help Ctrl+T: Toggle Chat Ctrl+F: Toggle Friends Ctrl+E: Toggle Explore Ctrl+H: Go Home Ctrl+Q: Toggle Quests (nb: this shortcut may change) Ctrl+I: Toggle Inventory Ctrl+O: Toggle Outfit Ctrl+S: Toggle Shop Ctrl+U: Toggle Auction Ctrl+\`: Toggle Snapshot Mode Ctrl+/: Toggle Settings Alt+Left/Right Arrow: Move Chat Tab F12: Show avatar profile Ctrl+M: Toggle Mail Ctrl+Space: Start a search
---
### Outfits
#### Overview[β](#overview "Direct link to Overview")
The Outfit window is where you can create new outfits, edit an outfit or delete an outfit.
The Outfit window is where you can create new outfits, edit an outfit or delete an outfit. You can open the Outfit window by clicking on the Outfit button at the bottom of the screen.
info
When you sign up, you can choose a default avatar; don't worry, you can customise or make a new one when you log in!
##### Creating new outfits[β](#creating-new-outfits "Direct link to Creating new outfits")
To create a new outfit, first go into the Outfit window by clicking on Outfit at the bottom of the screen, then at the top of the Outfit window, click on Create New Male or Female.

When you click on one of these, a pop up will appear asking you to name the outfit. Once you have named it, click on OK to create the outfit. This will give you a default avatar which is customisble. You can see which outfit is active by opening the Outfit List (the active outfit will be in grey).

The Copy ID button can be ignored; this is generally used for developers who want to use their live outfits to make NPCs.
##### Outfit Options[β](#outfit-options "Direct link to Outfit Options")
Other than creating new outfits, there are a few more options along the top of the Outfit window.

* **Save As -** You can have any outfit active, and after customising it, you can then choose to Save As to save it as a separate outfit with a different name.
* **Delete -** This will delete the current active outfit. Only click this if you are really sure you want to delete the outfit, as you won't be able to restore it.
* **Outfit List -** This is where you can see a full list of all the outfits you have made.
* **Refresh List -** If you make a new outfit and it doesn't show up on the list, you can click on refresh to refresh the list and it should show the new outfit listed.
##### Customising an outfit[β](#customising-an-outfit "Direct link to Customising an outfit")
There are a lot of customise options for avatars in the Outfit window; You can change what clothing your avatar is wearing, choose a preset, customise the head and body, change the skin or use morphs. You can find all these options down the left-hand side of the Outfit window.

---
### Outfit IDs
#### Overview[β](#overview "Direct link to Overview")
If you want to set up NPCs to show off your clothing brand in Sinespace, find the Outfit ID and attach it to an NPC statue.
If you want to set up NPCs to show off your clothing brand in Sinespace, find the Outfit ID and attach it to an [NPC statue](/sinespace-sdk/components/statue.md).
The outfit ID is the number at the end of the outfit name in the Outfit window β

Note the outfit ID number down for the outfit you want on your NPC. In Unity, add this to the Player Outfit ID box on the NPC statue component, then upload the NPC like you normally would.

---
### Regions
#### [ποΈRegions In Sinespace](/sinespace-viewer/regions/regions-in-sinespace.md)
[Learn what Sinespace regions can provide, from free home regions and private access controls to custom Unity-built spaces.](/sinespace-viewer/regions/regions-in-sinespace.md)
---
### Regions In Sinespace
#### Overview[β](#overview "Direct link to Overview")
Your first home region is completely free with 128MB of space. Regions can be public, private, customised, and built for larger events or collaborative work.
##### First region free[β](#first-region-free "Direct link to First region free")

Your first home region is completely free with 128MB of space. Click on the Home button in-world! You can add more regions with region subscriptions.
* [Region Subscriptions](https://sine.space/user/subscription)
##### Build vast open worlds[β](#build-vast-open-worlds "Direct link to Build vast open worlds")

No geographical limitations means you can create a large exterior region or a small interior, the choice is up to you.
##### Private and public spaces[β](#private-and-public-spaces "Direct link to Private and public spaces")

With region management, you can control who has access to your region. You can also have a completely private version of Sinespace on a white label grid for added privacy.
* [Region Management](/sinespace-sdk/regions/management.md)
##### Customisable regions[β](#customisable-regions "Direct link to Customisable regions")

Regions are fully customisable thanks to our in-world Inspector. The in-world inspector lets you change almost everything in the region, including light colors, textures and the shape and layout of buildings.
* [Uploading Items as Furniture](/sinespace-sdk/furniture/how-to-upload-items-as-furniture.md)
* [Adding Poses to Furniture](/sinespace-sdk/furniture/adding-poses-to-furniture.md)
##### Build regions of AAA standards[β](#build-regions-of-aaa-standards "Direct link to Build regions of AAA standards")
With Unity as our game engine, and access to environmental scripts in our editor pack, creators are able to make beautiful and realistic regions built to AAA game standards.
* [Regions Overview](/sinespace-sdk/regions.md)
* [Region Set-up](/sinespace-sdk/avatars/gestures/set-up.md)
* [Region Upload Settings](/sinespace-sdk/regions/upload-settings.md)
* [Region Export Settings](/sinespace-sdk/regions/export-settings.md)
* [Platform Settings](/sinespace-sdk/regions/platform-settings.md)
* [Region Submission](/sinespace-sdk/regions/submission.md)
* [Region Lighting](/sinespace-sdk/regions/lighting.md)
* [Navigation Bake](/sinespace-sdk/regions/navigation-bake.md)
* [Occlusion Bake](/sinespace-sdk/regions/occlusion-bake.md)
* [Post Processing](/sinespace-sdk/regions/post-fx.md)
##### Collaborate and build together[β](#collaborate-and-build-together "Direct link to Collaborate and build together")

The 'Edit Room' system allows you to collaborate with other creators to design a perfect region!
##### Scale easily[β](#scale-easily "Direct link to Scale easily")

You can hold a large event due to being able to shard regions. Also, depending on subscription level, you can have up to 100 avatars in one region.
* [Region Subscriptions](https://sine.space/user/subscription)
If you need any guidance on how to upload your creations to Sinespace or want to chat with other creators, check out our [Discord Channel!](https://discord.gg/sinespace)
---
### Your Regions
#### Overview[β](#overview "Direct link to Overview")
Click the Home button at the bottom of the client to teleport to your own private space, or to see the list of regions you own if you are a subscriber with multiple regions.
#### Access your Regions[β](#access-your-regions "Direct link to Access your Regions")
Click the Home button at the bottom of the client to teleport to your own private space, or to see the list of regions you own if you are a subscriber with multiple regions.
You can teleport to any of your regions from here.

#### Region Slot Management[β](#region-slot-management "Direct link to Region Slot Management")
If you have uploaded more regions than you have available slots for you can swap around which are enabled and which are disabled.
#### Region Management[β](#region-management "Direct link to Region Management")
Click EDIT in the INFO tab of the REGION MANAGEMENT window (which you can open from the minimap in a region, or from the room list if you want to change settings of a region you own but are not currently standing in.)
1. Open the Region Management window

2. Click on Edit to change settings for this region.

#### Room Access[β](#room-access "Direct link to Room Access")
Your room will be set to public; open to anyone; by default. You can set it to friends only, or approved only.

Room access permissions are tied to each region; you can have lots of different regions with different public and private access groups.
To approve specific people to access an approved only region, invite them to teleport in; they will be prompted to request access and you can grant it. They will then appear as a member in the MEMBERS tab of the REGION MANAGEMENT window.
They can attempt to teleport in, prompting the access request, by finding your region in the EXPLORE panel, or via your profile. They can use the region url. Or you can offer a teleport direct to you via the TELEPORT button on their PROFILE window.
#### Members[β](#members "Direct link to Members")
If your region is set to friends only or approved only you will see a list of everyone with access in the MEMBERS tab of the REGION MANAGEMENT window.

You can modify this, barring, removing or giving admin permissions on an individual basis.
#### Spawn Rules[β](#spawn-rules "Direct link to Spawn Rules")
Spawnable items, including all generic virtual goods, can be deployed on a timed basis in a region.

You can set each of your regions to no spawned items (default) or you can allow only admin (including yourself) to spawn items. Or you can let anyone who has access to the region spawn items and limit their duration. Spawned items will also disappear automatically when the owner logs out of the region.
#### VOIP Rules[β](#voip-rules "Direct link to VOIP Rules")
Here you can change the settings for VOIP (voice chat) in your region. You can set it so it is disabled, so it's only enabled for the owner or so it's enabled for everyone.

#### Multiple Regions[β](#multiple-regions "Direct link to Multiple Regions")
Everyone in Space automatically gets one free region. If you want to upload your own unique region content to your region, go to curator.sine.space and sign up as a creator, for free, and follow the tutorials on how to create your own region content.
If you want to own multiple regions in Sinespace, please see our [Subscriptions](https://sine.space/user/subscription) page for more information.
---
### Settings
#### Overview[β](#overview "Direct link to Overview")
There are quite a few settings you can change on the viewer; You can change Graphics, UI, Controls, Sound, Misc and VR.
There are quite a few settings you can change on the viewer; You can change Graphics, UI, Controls, Sound, Misc and VR. You can access the Settings from the Settings button on the login screen or from in-world via the Settings icon in the bottom right.
##### Graphics[β](#graphics "Direct link to Graphics")
Under the Graphics settings you can choose from our graphics presets; Fastest, Fast, Medium or Quality. These are fast ways to adjust the overall graphics quality to suit your system.

We have also included Advanced Options, so you can adjust certain graphical components individually, such as Bloom, Depth of Field and Quality lighting. Disabling these can improve your framerate but at the cost of visual quality.
##### UI[β](#ui "Direct link to UI")
The UI settings allow you to change the size of the interface. You will need to restart the viewer for the scaling to take effect.

info
If you get stuck while resizing the interface, hold the left shift key at viewer startup to revert to default scale!
##### Controls[β](#controls "Direct link to Controls")
The control settings allow you to change certain control aspects like 'Click to walk' or 'Use Gamepad'.

You can also change the mouse sensitivity with the slider to change the look speed in-world.
##### Sound[β](#sound "Direct link to Sound")
Here you can change the volume for music, sound effects, voice volume and also change default devices like microphone, playback and webcam as well as the mic sensitivity.

##### Misc[β](#misc "Direct link to Misc")
Here you can clear cache, change the cache location and disable/enabled other options.

You can also change the framerate and toggle vSync on/off from here.
##### VR[β](#vr "Direct link to VR")
This is where you can enable VR, choose your preferred VR device, choose your dominant VR hand and change other options for VR.

warning
Enabling or changing the VR device will require a viewer restart
---
### Shop
#### Overview[β](#overview "Direct link to Overview")
Click the Shop button in the bottom menu to search or browse the entire inventory of virtual goods in Space.
#### Shop[β](#shop "Direct link to Shop")
Click the Shop button in the bottom menu to search or browse the entire inventory of virtual goods in Space.

You are able preview clothing, full avatars in addition to attachments prior to purchasing.

***
---
### Viewer Basics
#### Overview[β](#overview "Direct link to Overview")
System Requirements Please see our system requirements for desktop and VR here.
##### System Requirements[β](#system-requirements "Direct link to System Requirements")
Please see our system requirements for desktop and VR [here](/quickstart-sinespace-viewer/get-started-viewer/system-requirements.md).
##### Settings[β](#settings "Direct link to Settings")
To see all of our setting options see [Settings](/sinespace-viewer/settings.md).
##### UI[β](#ui "Direct link to UI")
Here is an overview of our UI:
(image)
To edit your profile, change to full-screen or exit the viewer, click on the three lines in the top right of the viewer. For more info on each UI tab along the bottom of the screen, please see the following:
Home
[outfits](/sinespace-viewer/outfits.md)
Socialising
[Shopping](/sinespace-viewer/shop.md)
##### Moving Around[β](#moving-around "Direct link to Moving Around")
To move your avatar around, you will need to use these keys:
* W = Walk forward
* A= Walk Left
* S= Walk backward
* D= Walk right
You can fly using R to start flying and to fly higher, and use C to land, or use Pg Up and Pg Down and WASD to change direction. You can also enable the option to 'Click to Walk' under Settings.
##### Shortcut Keys[β](#shortcut-keys "Direct link to Shortcut Keys")
* F1: Help
* F9: Toggle UI
* Ctrl+T: Toggle Chat
* Ctrl+F: Toggle Friends
* Ctrl+E: Toggle Explore
* Ctrl+H: Go Home
* Ctrl+Q: Toggle Quests (This shortcut may change)
* Ctrl+I: Toggle Inventory
* Ctrl+O: Toggle Outfit
* Ctrl+S: Toggle Shop
* Ctrl+U: Toggle Auction
* Ctrl+\`: Toggle Snapshot Mode
* Ctrl+/: Toggle Settings
* Alt+Left/Right Arrow: Move Chat Tab
* F11: Toggle fullscreen
* F12: Show avatar profile
* Ctrl+M: Toggle Mail
* Ctrl+Space: Start a search
---
### XMPP Chat Client
#### Overview[β](#overview "Direct link to Overview")
One of spaces' new features is the ability to use XMPP clients in conjunction with the normal space chat.
One of spaces' new features is the ability to use XMPP clients in conjunction with the normal space chat.
You can use XMPP clients to chat to other users through the in world space chat window, and they can reply back either using a XMPP client or using the normal space chat.
#### XMPP Clients[β](#xmpp-clients "Direct link to XMPP Clients")
Any XMPP client is fine to use, but for this walkthrough, I'm using Pidgin.
Download and install the client you want to use, and then follow the next steps to get it set up for use with space.
#### XMPP Client ID[β](#xmpp-client-id "Direct link to XMPP Client ID")
To use the xmpp client, you will need a specific ID which is linked to your space account.
To find this ID, you will need to go to [sine.space](http://sine.space/) and log in using your details.
After you have logged in, click on 'Account' at the top of the page. On this page, you will see your information, and also see the XMPP client ID.
Make sure to note this ID somewhere.
#### Using your ID in the XMPP Client[β](#using-your-id-in-the-xmpp-client "Direct link to Using your ID in the XMPP Client")
Open your XMPP client, and you will see something similar to this.
You will need to change a couple of settings and add your ID.
Here I have changed the settings to the right ones and added in my xmpp ID.
Click on 'Add' and your xmpp account will be set up!
---
## Support
### Support
#### [ποΈBug Reporting](/support/bug-reporting.md)
[Bug Reporting If you have found a bug on our viewer and want to report it, you will need to report it to us through our issue tracker.](/support/bug-reporting.md)
---
### Bug Reporting
#### Overview[β](#overview "Direct link to Overview")
If you have found a bug on our viewer and want to report it, you will need to report it to us through our issue tracker.
If you have found a bug on our viewer and want to report it, you will need to report it to us through our [issue tracker](https://issues.sine.space/login_page.php). You will need to login with your Sinespace username and password before you can report an issue.
##### **Issue tracker interface β How to report**[β](#issue-tracker-interface--how-to-report "Direct link to issue-tracker-interface--how-to-report")
When you have logged in, you can either click on the Report Issue button in the top right corner of the screen, or on the left-hand side. When you have clicked on that button, you will see a Enter Issues Details screen with the following:
* **Category**: The category is a necessary field to fill in. The category is which OS you are using our viewer on.
* **Reproducible**: This is optional to fill in, but it does help us test for the bug quicker.
* **Severity**: This is optional, but if the severity is marked, it will help us prioritize bugs which are more important to fix such as major, crashing or blocking bugs.
* **Select Profile**: The profile is the version of OS you are using such as 32 or 64-bit Windows. You do not need to fill this in if you do not know the information.
* **Product Version**: This is the internal product release number, if you do not know this then it is fine to leave this blank.
* **Summary**: This is a necessary field to fill in; it is the general heading for the issue, such as βLive viewer crashingβ
* **Description**: This is a necessary field to fill in; you will need to add a description of the bug here. The more information you add in the description allows us to find and fix the bug quicker.
* **Additional Information**: This is for any additional information you might add which could be useful in fixing the bug.
* **Tags**: You can add your own tag here, but it is recommended to use the tags under Existing tags to help us find your report.
* **Upload files**: You can use this to upload your logs or crash reports, or upload images of the bug if possible.
* **View Status**: This is to change the viewing status of the bug to private or public. We recommend setting this to public so our engineering team can see your report as soon as it is posted.
* **Report Stay**: Please check this if you need to make more reports.
When you have filled in all the relevant information, you can then click on the Submit Issue button to submit it to us. If you click on the My View button on the left-hand side, you will be able to see all of the bug reports you have made and see their status; they will have a green colored box if the issue has been resolved.
##### **Steps to reproducing issues**[β](#steps-to-reproducing-issues "Direct link to steps-to-reproducing-issues")
The Sinespace Development team need as much detail as possible to recreate issues, be concise and give step by step details of how the issue can be reproduced. Please make sure that bug reports include the following:
* The viewer/editor pack version being used.
* Is it the Windows or Mac version?
* Tell us what happened, be as detailed as possible include screenshots, output logs or console errors where necessary.
* Tell us how to recreate the issue, be as detailed as possible with step by step instructions.
An example for this is:
* You change your Outfit in the Outfit window, and when you save and close, your avatar is stuck in T-pose.
* You try to fix it by changing your Outfit and saving again, but it does not fix.
* You try to move your avatar around, but the animation is still stuck in T-pose.
These are the steps we would follow to reproduce the bug and see what is causing the issue.
##### **Retrieving viewer output logs**[β](#retrieving-viewer-output-logs "Direct link to retrieving-viewer-output-logs")
If support asks you to recover a log file for us - usually if something has gone wrong, and we need more information. The following steps will allow you to return it to us.
**Windows**
For Windows, log files are located in the "Application Data" folder, to open this - hold down the Windows Key on your keyboard, and press the 'R' key (you can also use "Run..." from the Start Menu)
Paste the following text:
**%appdata%\\..\LocalLow\Sine Wave Entertainment Ltd\sinespace**
And press enter, this will open a Windows Explorer window - look for a file named **output\_log** - this is the log file, please return this via email to us or through Support.
**MacOS**
For macOS, log files are in the user Library folder - to access this, open Finder, and press **Shift** **β+G** to open the "Go to Folder" option - in the textbox, enter:
**~Library/Logs/Unity**
You are looking for a file named Player.log - this is the log file, please return this via email to us or through Support.
**Linux**
For Linux, the file you are looking for is:
**~/.config/unity3d/Sine Wave Entertainment Ltd/sinespace/Player.log**
Please return to us via email or through Support.
---
### FAQ
#### Overview[β](#overview "Direct link to Overview")
Navigation How do I move around? **Walking:** You can walk around the virtual world by using the arrow keys on your keyboard.
##### Navigation[β](#navigation "Direct link to Navigation")
###### How do I move around?[β](#how-do-i-move-around "Direct link to How do I move around?")
**Walking:** You can walk around the virtual world by using the arrow keys on your keyboard. If you're familiar with playing video games on a computer, you can also make use of the inverted-T cluster, or WASD keys.
**Running:** To run, simply hold down the Shift key while walking.
**Jumping:** To jump, press the space bar.
**Optional mouse control:** You can also move around by left-clicking at a spot on the ground. Your avatar will then walk to the specified point and stop. This is called the "click to walk" setting, and you can turn it off in the Settings menu if you like.
###### Can I fly?[β](#can-i-fly "Direct link to Can I fly?")
Yes. To start flying, first press the F key. This will lift your avatar into the air, where you'll hover. You can then use the arrow keys or WASD keys to soar about. Press the E key (or Pg Up) to fly higher, and the C key (or Pg Down) to fly lower. Press the F key again to land.
###### How can I change my camera angle?[β](#how-can-i-change-my-camera-angle "Direct link to How can I change my camera angle?")
You can change your camera angle by holding the right mouse button down as you move your mouse. If you want to focus on a certain point, hold down the Alt key and click the right mouse button, then use your mouse scroll wheel to zoom in and out.
Pressing the F4 key on your keyboard will turn on Fly Cam, which is another useful way to explore your surroundings. Once enabled, use the A and D keys to pan from side, and the W and S keys to zoom in and out. If you want to rotate the camera in Fly Cam mode, hold down the right mouse button and move the mouse.
###### Do I need a mouse to use Sinespace?[β](#do-i-need-a-mouse-to-use-sinespace "Direct link to Do I need a mouse to use Sinespace?")
Yes, you will need a mouse or a touchpad.
###### How can I visit different places?[β](#how-can-i-visit-different-places "Direct link to How can I visit different places?")
Each region contains different locations that you can visit. You can travel to the locations within a region by clicking on the "Explore" button at the bottom of your screen, and then clicking on one of the landmarks.
If you want to travel to a completely different region, click on the "World Map" button. This will call up a list of places you can visit. Mouse over them, and click on the "Enter" button when you've found one you want to see. Once you've successfully traveled to the new region, you can use the Explore function detailed above to learn more about the locations within it.
##### Vehicles[β](#vehicles "Direct link to Vehicles")
###### How can I get a vehicle?[β](#how-can-i-get-a-vehicle "Direct link to How can I get a vehicle?")
You can buy vehicles from the [Sinespace Shop](https://sine.space/shop/category/26/0/Vehicle/). When logged in to the platform itself, click on the "Shop" button located at the bottom of your screen. Once the Shop is open, click on the tab marked "Vehicles." You can purchase a vehicle by clicking on the "Buy" button located under the vehicle picture. Vehicles can be purchased with either Silver or Gold.
###### How do I drive my vehicle around?[β](#how-do-i-drive-my-vehicle-around "Direct link to How do I drive my vehicle around?")
To drive a vehicle, first click on the "Inventory" button located at the bottom of your screen. Scroll through your inventory items, and then click on the vehicle you want to use. When the "Drive" button appears, click on it, and the vehicle will spawn in your current region. Once the vehicle appears, click on it and you will automatically be placed in the driver's seat.
To turn and accelerate, use the arrow or WASD keys. Use the space bar to brake. To get out of the vehicle, just click on it again. The vehicle will automatically despawn once you have exited it.
##### Outfits and Clothing[β](#outfits-and-clothing "Direct link to Outfits and Clothing")
###### How can I change my outfit?[β](#how-can-i-change-my-outfit "Direct link to How can I change my outfit?")
To change your avatar's outfit, click on the "Outfit" button at the bottom of your screen. This will open the Outfit window.
To see all of the clothes and accessories you currently own, click on the individual "Wardrobe" buttons or on the "Inventory" button. To change your clothing, click on the item you want to wear and it will be placed on your avatar. We do have a layering system in place, so you can wear multiple items of clothing at one time.
Once you have chosen all the items you want to wear, click on the "Save and Close" button to save your avatar and return to the region.
###### How can I purchase more clothes?[β](#how-can-i-purchase-more-clothes "Direct link to How can I purchase more clothes?")
To purchase additional clothes and accessories, click on the "Shop" button at the bottom of your screen. Once inside the Shop, click on the "Clothes" tab located at the top of the menu. You can browse our collection of clothes and accessories by using the search function or by clicking on the category tabs on the right. When you find an item you like, you can preview it by clicking on the item picture or the "Preview" button. Clicking on the "Buy" button will complete your purchase. Clothing and accessories can be purchased with either Silver or Gold.
###### How can I make a new outfit?[β](#how-can-i-make-a-new-outfit "Direct link to How can I make a new outfit?")
Our Outfit system allows you to create new avatar looks and save them for future use. To make a new outfit, click on the "Outfit" button. Once the Outfit window has opened, you will see a button on the left-hand side labeled "New Outfit." Click on this button, and two boxes will appear -- one that says "Enter a Name" and another saying "Base Male." Enter the name of the outfit (for example, "Business Casual Dress,") and then use the dropdown menu next to Base Male to specify whether this outfit is intended for a "Base Male" avatar or a "Base Female." Once you have done of these things, click the button that says "Create." You can then choose your avatar's hair, skin, clothing, and accessories. When you're finished designing your avatar, click the button labeled "Save and Close" to keep this outfit saved for whenever you want to use it. You can also use the dropdown menu at the top to see all the outfits you have made, and use the "Switch" button to switch to another saved outfit.
##### Friends and Communication[β](#friends-and-communication "Direct link to Friends and Communication")
###### How can I add users as friends?[β](#how-can-i-add-users-as-friends "Direct link to How can I add users as friends?")
To add another user as a friend, click on their avatar and then click on the "More" button that appears on the right side of the screen. When the other user's full profile pops up, click on the "Add Friend" button in their profile.
###### How can I invite friends to my location?[β](#how-can-i-invite-friends-to-my-location "Direct link to How can I invite friends to my location?")
You can invite a friend to join you in your current location by clicking on βFriends" button at the bottom of your screen, and then clicking on your friend's name. This will open a private chat window. Now click on the βTeleportβ button located within this private chat window. Once your friend accepts your invitation, they will teleport straight to you.
###### How can I remove people from my friends list?[β](#how-can-i-remove-people-from-my-friends-list "Direct link to How can I remove people from my friends list?")
To remove someone from your friends list, click on the "Friends" button at the bottom of your screen. Find the person you wish to remove, and click on their name. This will open up a private chat window. Now click on the "Remove Friend" button located within this private chat window.
###### How can I talk to other people?[β](#how-can-i-talk-to-other-people "Direct link to How can I talk to other people?")
You can talk to other in-world users via public text chat, or by sending private text messages. To talk to other users in public chat, click on the chat window at the bottom of your screen and type out your message. Once you're finished, you can hit the Enter key on your keyboard or click the "Send" button in the chat window.
To send a private chat message, click on a nearby user. A private chat window will open, where you can type your message and send it by hitting the Enter key on your keyboard or by clicking the "Send" button. If you've added friends to your Friends list, you can talk to them at any time by clicking on the "Friends" button and then clicking on their name.
You can also talk to other people currently in the same region as you by using region chat. The region chat will always display the name of the region, such as *Welcome Center*, so you can easily identify it.
###### Can I voice chat with other users?[β](#can-i-voice-chat-with-other-users "Direct link to Can I voice chat with other users?")
We have Vivox integrated into Sinespace. If a region creator has added Vivox zones, that means you can voice chat with other users in those zones. To activate this service, click on the "Voice Chat" button located at the bottom of your screen. Hold down the right Alt key while you're speaking, and let go of the right Alt key when you want to mute.
###### Can I e-mail other users within Sinespace?[β](#can-i-e-mail-other-users-within-sinespace "Direct link to Can I e-mail other users within Sinespace?")
Yes, you can e-mail other users in Sinespace by using our in-world e-mail feature. To e-mail a user, click on their avatar and then click on the "More" button that appears on the right side of the screen. Once their user profile is open, click the "E-mail" button to send them an e-mail. You can also send virtual items via Sinespace e-mail by clicking "Add an attachment."
##### Performance Related[β](#performance-related "Direct link to Performance Related")
###### My PC is lagging when I run Sinespace. What can I do?[β](#my-pc-is-lagging-when-i-run-sinespace-what-can-i-do "Direct link to My PC is lagging when I run Sinespace. What can I do?")
Your best option is to adjust the graphics settings. For an easy fix, click the "Settings" button located in the bottom right corner of the screen, and drag the "Visual Boost" slider to its lowest setting.
###### How can I improve the visual quality of Sinespace?[β](#how-can-i-improve-the-visual-quality-of-sinespace "Direct link to How can I improve the visual quality of Sinespace?")
You can increase the graphics settings to make the platform run faster. To do so, click the "Settings" button located in the bottom right corner of the screen, and drag the "Visual Boost" slider up. We also have Quick Settings designed to accommodate older PCs, mid-range PCs, high end PCs, and Gaming PCs. Choosing one of these will automatically lower or raise the Visual Boost slider to the appropriate level for your equipment. These settings will also enable or disable Post FX settings for our regions. If you want to manually control the Post FX settings, you can do so with the Advanced Settings menu.
###### Can I run Sinespace on an Ipad, Android, or my phone?[β](#can-i-run-sinespace-on-an-ipad-android-or-my-phone "Direct link to Can I run Sinespace on an Ipad, Android, or my phone?")
Right now Sinespace is only accessible with a PC that is running Windows, MacOS, or Linux. We have Android and iOS clients in the works, and you can access experimental versions on request. We are planning to release Sinespace across a range of devices in the future.
###### Why is there a button saying "Offline Mode?"[β](#why-is-there-a-button-saying-offline-mode "Direct link to Why is there a button saying \"Offline Mode?\"")
This usually means either that your internet is disconnected or you're currently behind a firewall that is preventing Sinespace from accessing the internet. You can still continue to play, but you wonβt be able to see other users.
###### My character is stuck and I canβt move! What should I do?[β](#my-character-is-stuck-and-i-cant-move-what-should-i-do "Direct link to My character is stuck and I canβt move! What should I do?")
There may be a couple of pesky bugs that cause your avatar to become stuck in a region. If you refresh the page, you'll unstick yourself and arrive back at your current region's default location. You can help us resolve this issue by sharing details of what happened. You can file a report with us by clicking the "Request Support" button under Help.
###### I found a bug. How can I report it?[β](#i-found-a-bug-how-can-i-report-it "Direct link to I found a bug. How can I report it?")
If you find a bug, please click on the "Help" button located at the bottom of the Sinespace client, and then click on "Request Support." It will be helpful if you entitle the message "Bug Report," and then provide as many details as possible about what happened. This message will be sent to our support team for review. You can also submit a bug report on our [forums](https://forum.sine.space/) on the Bug Report thread, or report the bug using Sine Wave's Freshdesk. You will have to create a new support ticket, and then fill in all of the details.
###### How can I see upcoming patches or news?[β](#how-can-i-see-upcoming-patches-or-news "Direct link to How can I see upcoming patches or news?")
To see upcoming changes or news, visit our [blog](https://blog.sine.space/). To speak with fellow community members or learn more about our experimental features, visit our [forums](https://forum.sine.space/).
##### Currency[β](#currency "Direct link to Currency")
###### What are Silver and Gold, and how can I use them?[β](#what-are-silver-and-gold-and-how-can-i-use-them "Direct link to What are Silver and Gold, and how can I use them?")
Silver is the currency of the platform. You can use it to purchase items from our [in-world Shop](https://sine.space/shop), and to participate in activities. Gold is an alternative to Silver, which can be purchased with real life currency. Some items in the Shop can only be purchased with Gold.
###### How can I earn Silver?[β](#how-can-i-earn-silver "Direct link to How can I earn Silver?")
You can earn Silver by doing various activities and quests.
######
##### Activities and Quests[β](#activities-and-quests "Direct link to Activities and Quests")
###### How do I do an activity or quest?[β](#how-do-i-do-an-activity-or-quest "Direct link to How do I do an activity or quest?")
Activities and quests are marked by an exclamation point icon on the map. To travel to an activity, click on the βExploreβ button located at the bottom of your screen, and then click on the activity or quest name on the map. This will teleport you to the activity or quest. Now click on the item or avatar with the exclamation point hovering overhead, and the quest will begin.
###### How can I take a snapshot?[β](#how-can-i-take-a-snapshot "Direct link to How can I take a snapshot?")
Our built-in Snapshot tool lets you take amazing snapshots and selfies. To get started, click on the "Snapshot" button at the bottom of your screen. This will open the tool, and present you with several options. You can add a filter, make your avatar strike a pose, change the camera angle, or add an overlay. You also have the option to capture the scene you want to photograph as a GIF, or to create a 360Β° image. Once you've chosen the settings you want, click the button labeled "Take Photo."
If you're not a fan of the picture you just took, you can click the "Retake Pic" button to try again. If you're happy with it, hit "Save and Upload." You can then name your image, add a description, and save it to your Sinespace album or your computer. You can also check the "E-mail" option if you'd like to e-mail a copy to someone in Sinespace, or make the image your profile pic by clicking on "Make Profile Pic."
##### Account Related[β](#account-related "Direct link to Account Related")
###### I forgot my password. How can I reset it?[β](#i-forgot-my-password-how-can-i-reset-it "Direct link to I forgot my password. How can I reset it?")
To reset your password, click on the "Sign In" button on [our website](https://sine.space/) then click on "Reset Your Password." We will send an e-mail to your registered e-mail address with a link to reset your password.
###### I forgot my username, how do I recover it?[β](#i-forgot-my-username-how-do-i-recover-it "Direct link to I forgot my username, how do I recover it?")
If you have forgotten your username, you can find it on your account settings page.
###### How do I change my password?[β](#how-do-i-change-my-password "Direct link to How do I change my password?")
You can change your password by logging in and going to your account settings page. Once you're there, type your current password and new password into the appropriate boxes and click "Update."
###### How do I update my e-mail address?[β](#how-do-i-update-my-e-mail-address "Direct link to How do I update my e-mail address?")
You can change your e-mail address by [creating a support ticket](#).
###### Is Sinespace free to use?[β](#is-sinespace-free-to-use "Direct link to Is Sinespace free to use?")
Yes, Sinespace is completely free to play. Every user gets a free region, which you can access by clicking on the "Home" button. If you require more regions, you will have to purchase land.
##### Home Regions[β](#home-regions "Direct link to Home Regions")
###### What is a home region?[β](#what-is-a-home-region "Direct link to What is a home region?")
Your home region is your own personal area in Sinespace. You can decorate your region, invite friends to visit you, and and even hold parties! Your home region is ready and waiting for you as soon as you sign in to Sinespace -- just click on the "Home" button at the bottom of your screen to teleport to it. You can add additional areas by clicking on the "Home" tab and then clicking "Create New Room."
###### How do I travel to my rooms?[β](#how-do-i-travel-to-my-rooms "Direct link to How do I travel to my rooms?")
Click on the "Home" button at the bottom of your screen. You can teleport to any of the rooms you've created from here, and you can also disable and enable rooms.
###### How can I purchase furniture for my home?[β](#how-can-i-purchase-furniture-for-my-home "Direct link to How can I purchase furniture for my home?")
Click on the Shop button at the bottom of your screen. When the Shop opens, click on the "Furniture" tab. This will allow you to browse through our catalog of furniture items and decor. When you find something you like, you can purchase it using the "Buy" button.
###### How do I place furniture in my home?[β](#how-do-i-place-furniture-in-my-home "Direct link to How do I place furniture in my home?")
To place furniture in your room, you will need to click on the "Edit Room" button while standing in the room you want to decorate. Once you do, you'll see an Inventory manager appear at the bottom of your screen. Click on any item in the inventory, it will be spawned into the room. Once it is spawned, you can move it around with the tools located at the top of the screen.
info
If you hold the Alt key as you make your selection, the furniture will be placed on the closest surface below your cursor. If you do not have the Alt key pressed, the furniture will be placed on the floor. If you hold down Shift while placing, your furniture, it will temporarily deactivate the Snap and Align modes.
###### How do I decorate my home?[β](#how-do-i-decorate-my-home "Direct link to How do I decorate my home?")
While standing in the room you want to decorate, click on the "Edit Room" button. This will bring up a suite of tools that you can use to decorate your room.
###### How do I buy a room design?[β](#how-do-i-buy-a-room-design "Direct link to How do I buy a room design?")
To buy a room design, click on the "Shop" button, and then click on the "Room" tab. You can browse through the available room designs. To buy one, click on the "Buy" button.
###### How can I change the room design of my home?[β](#how-can-i-change-the-room-design-of-my-home "Direct link to How can I change the room design of my home?")
First, go to the home with the layout you want to change. When you are there, click on the "Edit Room" button, and then click on the "Design" button at the top of the screen. A pop-up called "Region Templates" will appear on the left side of the screen. Click on the room template you want to use, and then confirm or reject the change. Click on "Swap Template" to change the template.
warning
When you swap region templates, all of the furniture in your room will be reset. The room will be empty, and you will need to decorate it again.
###### How do I change the light colors in my home?[β](#how-do-i-change-the-light-colors-in-my-home "Direct link to How do I change the light colors in my home?")
To change the light colors, click on the "Edit Room" button. At the top of the screen, a button labeled "Lights" will appear. Click it, and when the pop-up opens, you will see a list of all the lights in your home. Use the "Brightness" slider to change the brightness of the lights, or click on one of the available swatches to change the color. You can also pick a custom color by clicking on the "Custom Color" button.
##### Payment Related[β](#payment-related "Direct link to Payment Related")
###### My payment went through, but I havenβt received my Gold yet. What do I do?[β](#my-payment-went-through-but-i-havent-received-my-gold-yet-what-do-i-do "Direct link to My payment went through, but I havenβt received my Gold yet. What do I do?")
Please submit a [support ticket](https://support.sine.space/support/home) with your transaction ID. As the subject, put "Payment: \[your transaction ID]." (E.g "Payment: c4545433423.")
###### My credit card isn't working on your website, what can I do?[β](#my-credit-card-isnt-working-on-your-website-what-can-i-do "Direct link to My credit card isn't working on your website, what can I do?")
As a first step, please check to make sure you've entered your details correctly. If you still encounter problems making a purchase, please [contact us](https://support.sine.space/support/home) with your account name, and we will get in touch shortly.
###### What payment methods do you accept?[β](#what-payment-methods-do-you-accept "Direct link to What payment methods do you accept?")
We support a variety of payment methods, including PayPal, credit card, mobile phone payments and more.
######
[β](#-1 "Direct link to -1")
---