Categories
Advanced Tutorials Uncategorized

Adding editor properties to Crayta scripts

Preface

All Crayta scripts can have properties that can be edited directly in the editor. This is a powerful concept both for easily testing values, and reusing the script on different entities to produce new kinds of behavior each time.

In this tutorial we will learn how to add properties in scripts as well as learn all the different types of properties available.

If you are coming from Unity to Crayta you will recognize this concept and find that it works in a similar manner.

In Unity to expose properties to the editor you add public properties to your script class (or use the SerializeField attribute). In Crayta you add a child table to the Script.Properties table of your script.

In Unity the exposed properties appear in the Inspector window in the editor, in Crayta in the Properties window.

In Unity you can use editable properties to edit values or reference objects, in Crayta you can do the same.

Adding properties in a script

When creating a new script, Crayta will add by default an empty table named Properties (often called the property bag) to your script.

If your script is named HealthScript then the property bag will be initially an empty Lua table:

Health.Properties = {}

To add a new property you append a child table (a Lua associative array) to the properties table with a number of options (key/values) in it:

Health.Properties = {
   { name = "maxHealth", type = "number"}
}

Below you can see the property bag of the main script used in the Health package.

And here is how these properties are exposed in the editor:

Property options

There are different types of properties (text, number, entity, template etc) which we will explain in detail in the next section. Though there are a number of property options that are available to all property types:

  • name – string
    • The property name that will appear in the editor.
  • type – string.
    • All available types are explained in the next section.
  • tooltip – string
    • A tooltip message that appears when hovering over the element in editor.
  • editable – bool (default:true)
    • False hides the property in the editor UI. Useful if you want a property just for replicating data to clients, and want to keep the UI tidy by preventing the user from being able to see/edit it.
  • editableInBasicMode – bool (default:true)
    • False hides the property, but only in basic mode.
  • container – string (default:nil)
    • Possible values: “” (empty string or nil), “array”
    • Setting this to “array” will present the property as an array of the given type, allowing the user to add and remove values. Each array element, and the “length” field is inherited from a template individually.
  • visibleIf – function (default: nil)
               function(properties) return 
                  properties.allowRespawns == true
               end

This function should return true when the property should be shown on the UI, false to hide it. Useful for keeping the UI tidy by hiding irrelevant options. The function’s properties parameter provides access to the other properties (just as you would access with self.properties in a script)

Property types

  • number
    • Optional extra attributes:
      • default – number (0)
      • min/max – number – sets the min/max value that can be entered into the editor UI. Doesn’t apply at runtime.
      • stepSpeed – number (default: 1) – adjusts how fast the number changes with a gamepad
      • slowStepSpeed – number (default: 0.1) – as above, but when pressing the ‘slow’ modifier
      • fastStepSpeed – number (default: 10) – as above, but when pressing the ‘fast’ modifier
      • allowFloatingPoint – bool (default: true) – allow/disallow decimal numbers in the editor UI. Doesn’t apply at runtime.
      • options – table, a list of allowed values, either named: {Slow = 0.25, Normal = 1, Fast = 2, Ludicrous = 100}, or unnamed: {0.25, 1, 2, 100}
      • editor – string (default: chosen automatically based on other settings; either enum, int or float). Changes the widget displayed in the editor.
      • Possible values: int, float, seconds, days, slider
  • string
    • Optional extra attributes:
      • default – string (“”)
      • options – table – a list of allowed values, either named: {Monday = “Mon”, Tuesday = “Tue”, Wednesday = “Wed”}, or unnamed: {“Monday”, “Tuesday”, “Wednesday”}
  • text
    • Similar to string, but localisable. Uses a Text type at runtime.
  • boolean
    • Optional extra attributes:
      • default – boolean (false)

  • vector
    • Optional extra attributes:
      • default – Vector.Zero or any other Vector value using Vector.New(1,2,3)
      • stepSpeed – number (default: 1) – adjusts how fast the number changes with a gamepa
      • slowStepSpeed – number (default: 0.1) – as above, but when pressing the ‘slow’ modifie
      • fastStepSpeed – number (default: 10) – as above, but when pressing the ‘fast’ modifier
  • vector2d
    • Optional extra attributes:
      • default – Vector2D.Zero or any other Vector2D value using Vector2D.New(1,2)
      • stepSpeed – number (default: 1) – adjusts how fast the number changes with a gamepa
      • slowStepSpeed – number (default: 0.1) – as above, but when pressing the ‘slow’ modifie
      • fastStepSpeed – number (default: 10) – as above, but when pressing the ‘fast’ modifier
  • rotation
    • Optional extra attributes:
      • default – Rotation.Zero or any other Rotation value using Rotation.New(0,90,0)
      • stepSpeed – number (default: 1) – adjusts how fast the number changes with a gamepa
      • slowStepSpeed – number (default: 0.1) – as above, but when pressing the ‘slow’ modifie
      • fastStepSpeed – number (default: 10) – as above, but when pressing the ‘fast’ modifier
  • entity
    • Optional extra attributes:
      • is – string (default: “”) – require the entity to be of a specific physical type: Character, User, Mesh, Light, Sound, Effect, Voxels, Trigger, Locator, Camera. This doesn’t apply at runtime.
  • color
    • Optional extra attributes:
      • default – Color.New(1, 1, 1, 1)
  • event
    • An event property allows you to broadcast a message to a number of listeners all at once.
    • Each event can have one or more listeners. 
    • Using the Send function available on the event will trigger all listeners, passing on any parameters given to it:
       -- using the send method on an event property
       self.properties.myEvent:Send(myParam)

There are two ways to setup a listener in the editor:

  1. Specifying an entity in the world (or in the same template) like a normal entity property.
  2. Specifying an entity within any template.

Then as a final step you choose a script on that entity and a function within that script. In the first case, which is the simplest, only the specified entity will receive the event (when using the send method).

In the second case, the event will be broadcasted to every instance of that entity in the world, including any entity that is spawned after the game starts. This is quite powerful when you have to inform all entities of the same type for a certain event e.g. all chests have to refill or all doors have to close.

For more advanced uses, there is a Listen method available on the event property which allows you to add a listener to an event procedurally, in code:

gameManager.properties.OnMatchStart:Listen(self, "SwitchOn")

This method accepts two arguments:

  • A script component, usually that would be set to self, the script where this method is used from.
  • A function name, which will be the method in that script which will be called when the event is broadcasted.
  • [asset type]
    • The following asset types can be easily referenced by any script using a property with one of the following types:
      • template, voxel, mesh, sound, world, effect, script, widget, skydome, innerhorizon, outerhorizon, grip, colorgrading, postprocess, skymesh, skylayer, voxelmesh
MyScript.Properties = {
    { name = "greenVoxel", type = "voxel"}
}

Here is how a script exposing multiple properties to the editor, looks like: