RigidBodyComponent.GetInverseInertia/SetInverseInertia(Vector) - This API allows script to control the inertia of the object on different axes. For example an object can be set to only spin around the z-axis by giving it a vector with zero’s in the x and y components.

Previous updates

Update: October 9, 2019

Simple Scripts

All SimpleScripts now have a Group property to control which scripts communicate with each other. Setting a Group is optional, if left blank the script will behave as before. If a Group is set, then that simple script will only send events to and receive events from other scripts in the same Group by default. There are a couple of advanced features added as well:

To send a message to a different Group append @othergroup to the event - for example to send an on message to the radio group a SimpleInteraction script could send on@radio.

To send a message to ungrouped simple scripts specifically, even if a Group is set on this script, append @ to the end of the event like: on@

Advanced Optional Sequencing for events to emit or receive events in order, using >> as a separator. This is an entirely optional and complex feature that will likely require some experimentation.

For simple scripts that send events the >> separator can be used to send different events on subsequent actions. For example a SimpleInteraction that sets "On 1st Click ->" to one>>two>>three will send one the first time it is clicked, two the second, three the third and one the fourth etc. If sequencing is used with SimpleScripts that have other sequencing options like SimpleInteraction's 1st/2nd/3rd/4th click it is recommended to use one or the other and not both styles. The behavior of setting 1st click to one>>two>>three is identical to setting 1st click to one, 2nd click to two and 3rd click to three.

For simple scripts the receive events they will only respond to the current event in the sequence. If the sequence is one>>two>>three then until a one event is received the two and three events will do nothing. When one is received the action will happen and then the script will wait for two and ignore one and three.

Rigidbody grab/Release callbacks API

Scripts can perform actions when a rigidbody is grabbed or release by an avatar, using the API RigidBodyComponent.SubscribeToHeldObject. This method returns information about who has grabbed/released the object, and what hand they are grabbing it with.

Scripts have access to the RigidBodies that an avatar is currently holding, using the API AgentPrivate.GetHeldRigidBodies.

Scripts can control at runtime whether or not an object can be grabbed by avatars, using the API RigidBodyComponent.SetCanGrab.

Update: September 10, 2018

Json serialization API

Sansar.Utility.JsonSerializer can be used to Serialize and Deserialze Json strings to/from C# objects.

Sansar.Utility.JsonSerializerOptions can control the serialization process (more options to come!)

Sansar.Utility.JsonSerializationData is available in a generic and non-generic form and contains both the C# object and the json string on a successful serialize or deserialize.

In anticipation of rezzable scripts (not yet enabled), this base class only has access to ScenePublic and a maximum of 10 parameters. SceneObjectScript scripts will not run on rezzed content; ObjectScript scripts can run on scene content or rezzable content.

SimpleScript base class deprecated.

Not to be confused with the new Simple scripts. Scripts that use this base class will still compile with a warning. Support for new compiles will be disabled in a future release.

Update: July 18, 2018

HTTP API

HttpClient property added to the ScenePrivate class.

HttpClient.Request can be used to make request to external web services. Only text content types are currently supported. Request/response size limits also apply.

HttpRequestOptions can be used for more control, including specifying the method, query parameters and headers.

Take note that the personal data may be shared with external services. This data includes:

Avatar name

A user's unique avatar identifier

When an avatar visits the experience

When an avatar leaves the experience

Where in the experience 3D space the avatar exists whilst in the experience

Public chat of avatars whilst in the experience

Multiple Animations on Objects support

Fbx files containing multiple animation clips can be imported.

Added AnimationComponent.GetAnimations() and AnimationComponent.GetAnimation(string animationName) to access these animations

Calling Animation.Play() will then transition to that animation, with a transition time specified by the new parameter AnimationParameters.BlendDuration.

Simple Scripts

New structure to ScriptExamples.csproj

12 new scripts that work together without modification by sending named events:

These files are available in your Sansar inventory by default, in the Purchased category and in the Sansar install folder, See Simple Scripts user guide for more information.

Error Handling and Throttled APIs update:

Methods with callbacks that used to return a useless UInt64 now have a void return type.

If an API takes an Action<OperationCompleteEvent> handler, and a handler is provided, then any exceptions thrown by that API will be passed to the handler. OperationCompleteEvent.Success will be false, .Message will be the name of the exception and a new .Exception field will hold the thrown exception.

Passing any potentially throttled API to a WaitFor will now return immediately with a ThrottleException in the OperationCompleteEvent instead of throwing the exception.

All throttled APIs now take an Action<OperationCompleteEvent> handler. The default handler will log exceptions and return instead of throwing.

Update: June 1, 2018

Interaction API - Adding a script with a public or [EditorVisible] Interaction property will make the object clickable and allow a prompt to be shown on hover. The Interaction can be enabled and disabled, and the prompt can be updated by the script.

Interaction.SetEnabled(bool enabled) - To enable or disable the Interaction

bool Interaction.GetEnabled() - Returns true if the Interaction is currently enabled.

Interaction.SetPrompt(string prompt) - Sets the prompt text for the Interaction.

string Interaction.GetPrompt() - Gets the current prompt text for the Interaction.

Advanced Script Feature: Lock - For use with library style scripts that respond to calls from other scripts through Reflective. The Lock allows a script to declare a "critical section" that can only be accessed by 1 coroutine at a time.

Animation.Reset() now resets to the end frame of the animation if it is playing backwards.

Changing animation ranges now maintains the paused animation frame if the paused frame is within the new range.

We fixed the bug where sequential animation commands would override previous commands so you no longer need to wait for Animation.Reset() to finish before playing the next animation, for example.

RigidBodyComponent.SetMotionType now throws an exception when attempting to set the motion type of an object beyond its maximum permissive motion type.

Fixed ScenePrivate.OverrideMediaSource() being ignored for late joiners.

OverrideMediaSource() fails to set the media URL back to the built-default URL .

New known issues:

ScenePrivate.SceneInfo.ExperienceName which was returning an empty string will now return "unset". In a future release this will be updated to return the full experience name as shown in the atlas.

Updated: May 7, 2018

Animation control on objects

Animated objects now have two new properties in the editor:

BeginOnLoad - set this to false to prevent an animation from automatically playing

PlaybackMode - configure the animation to play once, loop or ping-pong back and forth from start to finish.

The AnimationComponent for an object now exposes a new DefaultAnimation member of the type Sansar.Simulation.Animation.

Sansar.Simulation.Animation

This is the interface to access data on the animation as well as for controlling object animation playback from script. It has methods to Play, Pause, Reset and JumpToFrame on the animation.

Sansar.Simulation.AnimationParameters can be used to configure animation playback for a limited window of frames, or to adjust the playback speed or playback mode. This can be applied with Get/SetParameters or by using the alternate Play/Reset methods.

GetFrameCount returns the object’s total number of frames of animation.

Note that Sansar imports animations at 30fps and will resample your animation if it was authored at a different frame rate.

Sansar.Simulation.AnimationParameters

RangeStartFrame, RangeEndFrame

Start and end frame numbers

ClampToRange

Set this to true to clamp animation playback to the specified start and end frames

PlaybackMode

Loop - The animation plays from the start frame to the end frame and then repeats from the start frame again.

PingPong - The animation plays from the start frame to the end frame and then backwards from the end frame to the start frame and then repeats that process.

PlayOnce - The animation plays one time from the start frame to the end frame then pauses at the end.

PlaybackSpeed

Set this to a number greater than 1.0 to speed up animation playback. Set this to a number less than 0.0 to reverse the animation.

New API to override the media url in a scene:

AgentPrivate.OverrideMediaSource(url, [width, height])

Will override the media url for the particular user only.

ScenePrivate.OverrideMediaSource(url, [width, height])

Will override the media url for all users.

Example script: MediaOverrideExample.cs

Sansar.Color now supported as a script property at edit time, e.g.,

public Sansar.Color myColor;

This will present a color picker and RGB values in the editor.

Added visibility on container properties for local position and rotation in the property editor. This is helpful for understanding why some objects come with a non-identity ObjectPrivate.InitialRotation and also gives increased control for fine tuning placement in the scene.

Objects that have their container transforms driven by animation do not show or allow this same local position and rotation manipulation.

Wait and WaitFor work outside of coroutines. They do not work in script constructors but should work everywhere else.

Fixed number pad Enter key to work with the Client.SubscribeToCommand API.

Whitelisted several more C# exceptions so catching specific exceptions should work.

Updated: April 9, 2018

The most significant updates to the script API in R20 are the addition of the new Sansar.Simulation.LightComponent and the new properties on Sansar.Simulation.RigidBodyComponent. Almost all physics properties that can be adjusted in Havok are now exposed through script APIs.

The import process now allows the specification of a motion type which creates an inventory cluster resource with a baked in motion type. This is a powerful feature when combined with the ScenePrivate.CreateCluster script API as it allows runtime creation of user-created dynamic objects. In addition, objects that are imported as dynamic can be changed to and from other motion types at runtime allowing dynamic objects to become keyframed, and vice versa. See SetMotionType() below for more details.

Here are the new script features:

Lights

If you wish to author a light that can have its properties adjusted at runtime from script, then you must turn on the new “scriptable” property on lights in the editor. All light component “set” functions will throw an exception if they are called on a light component that is not “scriptable”.

Sansar.Color

New, similar to Sansar.Vector but with RGBA components

Expected range of each component is 0.0 to 1.0. The Alpha component is 1.0 by default.

Sansar.Simulation.LightType enumeration for the type of light

Directional, Point, Spot

Sansar.Simulation.LightComponent

New component to allow script control of lights

IMPORTANT: All properties are read-only unless the “scriptable” property is enabled on the light in the editor. ▪ IsScriptable is a read-only property that allows a script to check to see if a light can have its properties adjusted at runtime.

NOTE: Directional lights can not be script controlled at this time.

LightType is a read-only property that indicates if a given light is a directional, point or spotlight. All properties can be adjusted on all light types but only certain properties apply to each type.

Color and Intensity

These two properties are intertwined. The Sansar renderer does not differentiate between a bright gray light and a dim white light so they are coupled in the API to reflect this.

SetColorAndIntensity(Sansar.Color, float)

This API allows you to set the color of the light and its brightness. The color is mapped into sRGB space and then the specified intensity is applied to it.

GetNormalizedColor()

This returns the color of the light based on one of its components having a value of 1.0.

GetRelativeIntensity()

This gets the intensity of the light based on the normalized color from above.

GetRange(), SetRange(float)

API to get and set the range for point lights and spotlights.

The following APIs only apply to spotlights:

GetAngle(), SetAngle(float)

To get or set the cone angle of the spotlight. Larger numbers indicate a wider, less focused light.

GetAngularFalloff(), SetAngularFalloff(float)

Angular falloff is the sharpness of the edge of the projected light. Small values will indicate a very clear edge while large values will fade the light smoothly towards the edge of its cone.

GetNearClip(), SetNearClip(float)

This value indicates the distance between the position of the light and where its light projection actually begins. This is useful for positioning a light within a recessed light socket, for example, without having the shadow of the light bulb or socket projecting into the scene.

GetShadowPriority(), SetShadowPriority(int)

The renderer supports many shadow casting lights in the same scene but in the event that too many shadow casting lights are competing for resources, the ones with the larger shadow priority will be applied first.

GetCastsShadows(), SetCastsShadows(bool)

This is an alternate API for shadow priority that matches the property in the editor. It uses a value of 0 or 1 behind the scenes for the shadow priority.

Rigid bodies

GetMotionType(), SetMotionType(RigidBodyMotionType)

The import process now allows the specification of a motion type so dynamic and keyframed objects can be saved to user inventory.

IMPORTANT: The imported motion type also specifies the maximum permissive motion type of an object. Objects imported as dynamic can be changed to any motion type in script. Objects imported as keyframed can be changed to static and back to keyframed, but can never be changed to dynamic. Objects imported as static can not have their motion type adjusted from script.

GetBounce(), SetBounce(float)

The range is from 0 to 1, with smaller numbers being less bounciness and 1.0 being a perfectly elastic collision.

GetCenterOfMass(), SetCenterOfMass(Sansar.Vector)

The vector points to the center of mass of the object in local space.

GetDynamicFriction(), SetDynamicFriction(float)

Dynamic friction from 0 to 1 is the friction applied to the object when it is moving across the surface of another object. The simulated friction between two objects is the minimum of the two touching surfaces.

GetGravityFactor(), SetGravityFactor(float)

Range from 0 to 1 that scales the effect of gravity on this object.

GetLinearDamping(), SetLinearDamping(float)

Similar to air resistance, with the default value of 0 indicating no resistance.

GetStaticFriction(), SetStaticFriction(float)

Static friction from 0 to 1 is the friction that affects an object at rest on another object. The simulated friction between two objects is the minimum of the two touching surfaces.

SceneInfo.ApiVersionString and ApiVersion return the current script API version.

New Run argument in WaitFor will run code after the subscribe but before the wait to close some race conditions when using coroutines and cross script events.

Example

// It is possible for a script to respond to the "Message" event before the WaitFor, in which case the response could be lost.
PostScriptEvent("Message");
WaitFor(SubscribeToScriptEvent, "Response");
// Instead this is guaranteed to do PostScriptEvent after being set up to receive the response.
WaitFor(SubscribeToScriptEvent, "Response", () => { PostScriptEvent("Message") });

New limits on number of pending events on a script to prevent memory blowout

Use PendingEventCount to get number of pending events.

Events queued when there are already 256 pending events will be discarded