Script API updates

Latest update

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.

  • Under the hood changes to script initialization times

  • Bug fixes: See known issues list here.

Documentation Updates

New Documentation

Updated Documentation

Previous updates

Updated: March 1, 2018

Detailed summary

  • New ScenePrivate.GetGravity and SetGravity
    • The scene properties now include gravity acceleration which can be set in G’s or m/s^2. These new Script API’s allow adjusting this gravity acceleration at runtime in m/s^2.
    • ScenePrivate.SetGravity(1.622f); // Set to moon gravity
    • float g = ScenePrivate.GetGravity(); // Get scene gravity
    • In addition, there are related constants for scene gravity:
      • ScenePrivate.DefaultGravity; // Default gravity m/s^2
      • ScenePrivate.GravityMinimum; // Lowest gravity (zero)
      • ScenePrivate.GravityMaximum; // Highest gravity (5G)
  • A few new Vector operations were added for convenience, namely:
    • float * Vector is now a supported operation
      • Previously only Vector * float was possible
    • Vector / float is now a supported operation
  • Objects now have a new keyframed motion type which has corresponding script support:
    • Added enumeration RigidBodyMotionType which includes:
      • MotionTypeDynamic
      • MotionTypeKeyframed
      • MotionTypeStatic
    • The RigidBodyComponent has a new API to query for this motion type:
      • RigidBodyMotionType t = rb.GetMotionType();
    • Additionally, the previous IsDyanmic() API has been deprecated.
  • FindScript improvements:
    • ObjectPrivate.FindScript<T>() now supports Reflective if an interface is used for <T> and a script on the object matches that interface.
    • New API ObjectPrivate.FindScripts(string name) to find scripts on an object by their class name.
    • Scripts must be Registered with the Reflective system to be found by either of these APIs.


Update: February 1, 2018

Detailed summary

  • New Unsubscribe pattern for all event subscriptions
    • All Subscribe methods now return an object that implements IEventSubscription with an Unsubscribe() method and an Active property.
    • Timers have been updated to use this as well, named Timers are deprecated.
  • New "SimpleScript" base class to offer a quicker start for simple script writing
    • This class offers methods to be overriden for common subscriptions and takes care of the subscriptions for you.
    • All events are run in a co-routine to support Wait and WaitFor.
    • Attributes can be used to change the behavior of the subscriptions or to register new events.
    • See SimpleScriptExample.cs for a more complete example
A Simple Greeter Example
public class SimpleExample : SimpleScript
	// This event occurs when a user enters the scene
	protected override void OnAddUser(AgentPrivate agent)
    		agent.SendChat($"Welcome to the {ScenePrivate.SceneInfo.ExperienceName} scene!");
  • New Audio API calls for playing a stream.
    • Enum “StreamChannel” corresponds to streams set up in Scene Settings.
      • MediaChannel
      • AudioChannel1, AudioChannel2, AudioChannel3, AudioChannel4
    • Agent:
      • PlayStream(StreamChannel streamChannel)
      • PlayStreamAtPosition(StreamChannel streamChannel, float loudness)
      • PlayStreamOnComponent(StreamChannel streamChannel, AudioComponent* audioComponent, float loudness)
    • Scene:
      • PlayStream(StreamChannel streamChannel)
      • PlayStreamAtPosition(StreamChannel streamChannel, float loudness)
    • Component:
      • PlayStreamOnComponent(StreamChannel streamChannel, float loudness)
  • 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.
// It is possible for a script to respond to the "Message" event before the WaitFor, in which case the response could be lost.
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
  • Coroutine operations (start/wait) always apply to active script to work better in cross script cases.
  • Removed "AllChannels" option for chat subscriptions. Scripts that were set to listen on all channels will now listen on the default 0 channel.
  • Fixed script stub dlls to not crash and created examples.csproj file for the example scripts, which is set up to use the stub dlls.
  • Fixed broken hyperlinks on script API help index.
  • More consistent behavior of user join/leave events in scripts.
  • Some optimizations to script memory tracking performance.


Was this article helpful?
3 out of 3 found this helpful
Have more questions? Submit a request


Article is closed for comments.