Expressions and Drivers

This article refers to PFM v0.4.3 and newer and may not be representative of older versions.

Math Expressions

Any animatable actor property (color, radius, position, etc.) can be animated with a math expression (Similar to SFM's expression operators). The implementation is based on the high-performance exprtk library, which includes support for:

Examples

As a basic example, let's say you want to animate the position of your actor, so you move it to [0,30,0] at timestamp 0, [0,50,20] at timestamp 1 and [30,0,-20] at timestamp 2. You can then apply the math expression value *2 to the property, which will double the values, meaning your actor will move from [0,60,0] to [0,100,40] and then to [60,0,-40] instead.

Here are some other basic examples:

Inputs

These are the variables available for use with math expressions:

Constants:

Base Functions
Quaternion Functions

Contrary to SFM's expression operators, PFM's math expressions cannot reference anything outside of the animation channel for the property it's assigned to. To create dependencies between properties, you need to use animation drivers instead.

 

Animation Drivers

Animation drivers are similar to math expressions, with a few key differences:

Since animation drivers are Lua-based, that means you have the entire Lua API available, making them much more powerful tools compared to math expressions. Their purpose is to animate a property programmatically with dependencies to other properties. To do so, animation drivers can have input variables, which can be references to actors, components or component properties.

Examples

Animation drivers cannot be created through PFM yet, so the following are Lua-based examples. These may seem a little daunting, but once the system is integrated into the interface, drivers will be much easier to use.

local actorId = "327b5bb8-74ae-400e-bbf7-61a2ad2020d3" -- Id of the actor for whom we check the distance
local expr = [[
	local dist = trLight:GetDistance(trActor)
	return Color.Red:Lerp(Color.Lime,math.clamp((dist -120) /150.0,0.0,1.0)):ToVector()
]]
lightSource:AddDriver(
	ents.COMPONENT_COLOR,"color",
	game.ValueDriverDescriptor(expr,{
    	-- 'trActor' variable referencing the transform component of the actor
    	["trActor"] = "pragma:game/entity/ec/transform?entity_uuid=" .. actorId,
    	
    	-- 'trLight' variable referencing the transform component of the light
    	["trLight"] = "pragma:game/entity/ec/transform"
    })
)