Observe
Observers are builtin CET functions that allow developers to detect when a function/method is executed by the game. They must be registered inside the onInit event, in the init.lua
file.
There are two kinds observers:
ObserveBefore()
which is triggered right at the moment the function/method is calledObserveAfter()
which is triggered once the game finished to execute the function/method
The provided callback
is always filled as follow:
The first argument is the current object that execute the function/method. This argument is not present when function/method is static.
Others arguments passed to the targeted function/method, if any.
Definition
Observe(className, method, callback) -- alias of ObserveBefore()
ObserveBefore(className, method, callback)
ObserveAfter(className, method, callback)
--
-- ObserveBefore()
--
-- @param string className The parent class name
-- @param string method The method name to target
-- @param function callback The callback function
--
ObserveBefore('className', 'method', function(self [, arg1, arg2, ...])
-- method() has just been called
end)
--
-- ObserveAfter()
--
-- @param string className The parent class name
-- @param string method The method name to target
-- @param function callback The callback function
--
ObserveAfter('className', 'method', function(self [, arg1, arg2, ...])
-- method() has been called and fully executed
end)
Representation
Here is a visual representation showing where observers are executed in the game's script:
public class AimingStateEvents extends UpperBodyEventsTransition {
protected func OnEnter(stateContext: ref<StateContext>, scriptInterface: ref<StateGameScriptInterface>) -> Void {
// ObserveBefore('AimingStateEvents', 'OnEnter')
let aimingCost: Float;
let focusEventUI: ref<FocusPerkTriggerd>;
let timeDilationFocusedPerk: Float;
let weaponType: gamedataItemType;
let player: ref<PlayerPuppet> = scriptInterface.executionOwner as PlayerPuppet;
// ...
// ObserveAfter('AimingStateEvents', 'OnEnter')
}
}
In this representation, the observer callback would be filled with the following arguments:
Observe('AimingStateEvents', 'OnEnter', function(self, stateContext, scriptInterface)
-- self the 'AimingStateEvents' class
-- stateContext the original method argument
-- scriptInterface the original method argument
end)
In the code above, the observer listens to AimingStateEvents:OnEnter()
, which is triggered everytime the player enters in ADS state.
Additionally, the OnEnter()
method is responsible to apply different effects, like the camera zoom, the initial stamina drain etc... Following this logic, this means:
Using
ObserveBefore()
allows to hook in before these effects are appliedUsing
ObserveAfter()
guarantees the method finished to apply all the effects
Usage Examples
Give money each time the player crouches:
-- onInit
registerForEvent('onInit', function()
-- observe crouch OnEnter state
Observe('CrouchEvents', 'OnEnter', function(self, stateContext, scriptInterface)
Game.AddToInventory('Items.money', 1000)
end)
end)
Give money as long as the player is crouched:
-- onInit
registerForEvent('onInit', function()
-- observe crouch OnUpdate state
-- this is triggered continuously, as long as the player is crouched
Observe('CrouchEvents', 'OnUpdate', function(self, timeDelta, stateContext, scriptInterface)
Game.AddToInventory('Items.money', 20)
end)
end)
Observe event send to an AnimationControllerComponent (click on function's name in NativeDB to copy the full name in your clipboard):
-- init.lua
-- onInit
registerForEvent('onInit', function()
-- NativeDB will copy 'entAnimationControllerComponent::PushEvent;GameObjectCName'
-- We can ignore the left part to only keep:
Observe('AnimationControllerComponent', 'PushEvent;GameObjectCName', function(gameObject, eventName)
print('GameObject:', gameObject:GetClassName())
print('Event:', eventName)
end)
end)
Advanced Example
Give money when the player is crouched and in ADS:
-- set initial vars
isADS = false
isCrouch = false
-- decide to give money
-- this function can be defined outside of onInit
-- as it is only called within observers
shouldGiveMoney = function()
-- is in ADS and is crouched
if isADS and isCrouch then
Game.AddToInventory('Items.money', 1000)
end
end
-- onInit
registerForEvent('onInit', function()
-- observe ADS OnEnter state
Observe('AimingStateEvents', 'OnEnter', function(self, stateContext, scriptInterface)
isADS = true
shouldGiveMoney()
end)
-- observe ADS OnExit state
Observe('AimingStateEvents', 'OnExit', function(self, stateContext, scriptInterface)
isADS = false -- reset condition
end)
-- observe Crouch OnEnter state
Observe('CrouchEvents', 'OnEnter', function(self, stateContext, scriptInterface)
isCrouch = true
shouldGiveMoney()
end)
-- observe Crouch OnExit state
Observe('CrouchEvents', 'OnExit', function(self, stateContext, scriptInterface)
isCrouch = false -- reset condition
end)
end)
Last updated