Types
Every public type lives in the Types module inside MotionFX. You rarely write them yourself: MotionFX's functions are already typed, so with --!strict your tracks are checked and names autocomplete as you type. This page covers the types you do write by hand, plus the shapes you'll meet in the editor.
Using the types
Require the Types module next to MotionFX. The most common reason is annotating what a Drive.Map function returns, because strict mode can't work out on its own that a table literal is a VignetteLayer or a ColorValue:
local Types = require(ReplicatedStorage.MotionFX.Types)
Driver = Drive.Map(envelope, function(amount: number): Types.VignetteLayer
return { Intensity = amount, Color = Color3.fromRGB(120, 0, 0), Inset = 0.3 }
end)
-- Or annotate a whole definition you build ahead of time
local definition: Types.EffectDefinition = { Tracks = {} }
Names
export type PrimitiveName = "FOV" | "Position" | "Rotation" | "Blur" | "Color" | "Vignette" | "Sound" | "Overlay"
export type ImpactName = "Earthquake" | "Explosion" | "Shake" | "Recoil"
export type InjuryName = "Blood" | "Concussion" | "BrainDamage"
-- Custom presets are plain strings, so the union ends with `string`.
export type PresetName = ImpactName | InjuryName | string
export type ViewName = "Default" | "FirstPerson" | "ThirdPerson" | "BackView"
The same names are grouped in MotionFX.Enum, so FX.Impact.Explosion and "Explosion" are interchangeable.
EffectDefinition
export type EffectDefinition = {
Duration: number?, -- nil = inferred from the drivers
FadeIn: number?,
FadeOut: number?,
Retrigger: RetriggerPolicy?, -- default "Stack"
MaxInstances: number?, -- cap for "Stack", default 8
Tracks: { Track },
Build: ((params: { [string]: any }) -> { Track })?,
}
export type RetriggerPolicy = "Stack" | "Refresh" | "Replace" | "Ignore"
| Field | Description |
|---|---|
Duration | A fixed length in seconds. If it is nil, the length is inferred. |
FadeIn / FadeOut | Effect-wide ramps. FadeOut covers the tail of a fixed duration, and it is also the default fade for Stop(). |
Retrigger | See Retrigger policies. |
Tracks | The fixed track list. It is required, so use {} if every track comes from Build. |
Build | Runs on every Play() with PlayOptions.Params and returns additional tracks, for example a push toward Params.Direction. |
Track
export type Track = FOVTrack | PositionTrack | RotationTrack | BlurTrack | ColorTrack | VignetteTrack | SoundTrack | OverlayTrack
Each track type is tagged by its Primitive, so once you write Primitive = "Rotation" the editor knows the track is a RotationTrack and checks its Driver. Their fields are listed on Primitives & Tracks, and which drivers each one accepts is in Which drivers fit.
The ready-made tracks return these same track types, and their option tables are ShakeConfig, KickConfig, EdgeConfig and so on, one per builder.
Overlay types
Used by overlays. OverlayConfig is the option table for Track.Overlay.
export type OverlaySheet = {
Images: { string }, -- asset ids, in order
Columns: number,
Rows: number,
FrameSize: Vector2?, -- one frame's size in pixels; required when a sheet holds more than one frame
Frames: number?, -- total frames, if the last sheet isn't full (default: every cell)
Fps: number?, -- the frame rate it was made for; used when the track doesn't set one
}
export type OverlayTrack = {
Primitive: "Overlay",
Sheet: OverlaySheet,
Driver: Driver<number>, -- opacity, 0..1
Fps: number?, -- default: the sheet's Fps, else 24
Loop: boolean?, -- default true
Color: Color3?,
ScaleType: ("Stretch" | "Crop" | "Fit")?,
Weight: number?,
Delay: number?,
}
export type OverlayConfig = {
Fps: number?, Loop: boolean?, Strength: number?, Color: Color3?,
ScaleType: ("Stretch" | "Crop" | "Fit")?,
Time: number?, Hold: number?, Release: number?, Delay: number?, Weight: number?,
}
CreateOptions
export type CreateOptions = {
Overwrite: boolean?, -- default false: Create errors on a duplicate name
}
PlayOptions
export type PlayOptions = {
Intensity: number?, -- 0..1+ master scale (default 1)
Duration: number?, -- override the definition's duration
Speed: number?, -- time scale (default 1)
FadeIn: number?,
FadeOut: number?,
Seed: number?, -- deterministic noise
Params: { [string]: any }?,
}
Handle
export type HandleState = "Playing" | "Stopping" | "Finished"
export type Handle = {
Id: number,
Name: string,
State: HandleState,
Intensity: number, -- read-only
SetIntensity: (self: Handle, value: number, fadeTime: number?) -> (),
Stop: (self: Handle, fadeTime: number?) -> (),
Finished: Signal<>,
}
Finished is a small signal with Connect, Once and Wait, like a Roblox event. Connect and Once return a connection with Disconnect(). See Handle.
Value types
What each primitive's driver must produce. See Primitives & Tracks for what every field does.
-- FOV, Blur: number Position, Rotation: Vector3 Vignette: number or VignetteLayer
export type VignetteLayer = {
Intensity: number,
Color: Color3?,
Inset: number?,
Size: number?,
Image: string?,
}
ColorValue
export type ColorValue = {
Tint: Color3?, -- multiplied together across effects
Saturation: number?, -- summed
Contrast: number?, -- summed
Brightness: number?, -- summed
}
Driver
You only need these to write a custom driver. The config tables for Envelope, Noise and Spring are documented with each function on the Drive page.
export type Sampler<T> = (t: number, dt: number) -> T
export type Driver<T> = {
Start: (context: PlayContext) -> Sampler<T>,
Duration: number?, -- natural length; nil = runs until stopped
}
PlayContext
A new context is created for every Play(). Stateful drivers get fresh state, and Seed keeps noise deterministic when it is set through PlayOptions.Seed.
export type PlayContext = {
Seed: number,
Params: { [string]: any },
}
Easing
export type Easing = {
Style: Enum.EasingStyle,
Direction: Enum.EasingDirection,
}
ViewSettings
export type ViewSettings = {
ShoulderOffset: Vector3, -- ThirdPerson: camera-space (right, up, back) offset from the head
BackViewDistance: number, -- BackView: studs in front of the character
BackViewHeight: number, -- BackView: studs above the head
HeadHeight: number, -- studs above the HumanoidRootPart
Responsiveness: number, -- smoothing: higher catches up faster
}