UEVR: Lua API

UEVR provides a Lua API that can be used to create plugins.

Scripts can be loaded under LuaLoader, and are automatically loaded from <game config folder>/scripts/*.lua.

The Lua API can also be loaded in different environments, like UE4SS. UEVR comes with a LuaVR.dll for this purpose.

Example

print("Initializing hello_world.lua") UEVR_UObjectHook.activate() local api = uevr.api; local uobjects = uevr.types.FUObjectArray.get() print("Printing first 5 UObjects") for i=0, 5 do local uobject = uobjects:get_object(i) if uobject ~= nil then print(uobject:get_full_name()) end end local once = true local last_world = nil local last_level = nil uevr.sdk.callbacks.on_post_engine_tick(function(engine, delta) end) local spawn_once = true uevr.sdk.callbacks.on_pre_engine_tick(function(engine, delta) --[[if spawn_once then local cheat_manager_c = api:find_uobject("Class /Script/Engine.CheatManager") local cheat_manager = UEVR_UObjectHook.get_first_object_by_class(cheat_manager_c) print(tostring(cheat_manager_c)) cheat_manager:Summon("Something_C") spawn_once = false end]] local game_engine_class = api:find_uobject("Class /Script/Engine.GameEngine") local game_engine = UEVR_UObjectHook.get_first_object_by_class(game_engine_class) local viewport = game_engine.GameViewport if viewport == nil then print("Viewport is nil") return end local world = viewport.World if world == nil then print("World is nil") return end if world ~= last_world then print("World changed") end last_world = world local level = world.PersistentLevel if level == nil then print("Level is nil") return end if level ~= last_level then print("Level changed") print("Level name: " .. level:get_full_name()) local game_instance = game_engine.GameInstance if game_instance == nil then print("GameInstance is nil") return end local local_players = game_instance.LocalPlayers for i in ipairs(local_players) do local player = local_players[i] local player_controller = player.PlayerController local pawn = player_controller.Pawn if pawn ~= nil then print("Pawn: " .. pawn:get_full_name()) --pawn.BaseEyeHeight = 0.0 --pawn.bActorEnableCollision = not pawn.bActorEnableCollision local actor_component_c = api:find_uobject("Class /Script/Engine.ActorComponent"); print("actor_component_c class: " .. tostring(actor_component_c)) local test_component = pawn:GetComponentByClass(actor_component_c) print("TestComponent: " .. tostring(test_component)) local controller = pawn.Controller if controller ~= nil then print("Controller: " .. controller:get_full_name()) local velocity = controller:GetVelocity() print("Velocity: " .. tostring(velocity.x) .. ", " .. tostring(velocity.y) .. ", " .. tostring(velocity.z)) local test = Vector3d.new(1.337, 1.0, 1.0) print("Test: " .. tostring(test.x) .. ", " .. tostring(test.y) .. ", " .. tostring(test.z)) controller:SetActorScale3D(Vector3d.new(1.337, 1.0, 1.0)) local actor_scale_3d = controller:GetActorScale3D() print("ActorScale3D: " .. tostring(actor_scale_3d.x) .. ", " .. tostring(actor_scale_3d.y) .. ", " .. tostring(actor_scale_3d.z)) local control_rotation = controller:GetControlRotation() print("ControlRotation: " .. tostring(control_rotation.Pitch) .. ", " .. tostring(control_rotation.Yaw) .. ", " .. tostring(control_rotation.Roll)) control_rotation.Pitch = 1.337 controller:SetControlRotation(control_rotation) control_rotation = controller:GetControlRotation() print("New ControlRotation: " .. tostring(control_rotation.Pitch) .. ", " .. tostring(control_rotation.Yaw) .. ", " .. tostring(control_rotation.Roll)) end local primary_actor_tick = pawn.PrimaryActorTick if primary_actor_tick ~= nil then print("PrimaryActorTick: " .. tostring(primary_actor_tick)) -- Print various properties, this is testing of StructProperty as PrimaryActorTick is a struct local tick_interval = primary_actor_tick.TickInterval print("TickInterval: " .. tostring(tick_interval)) print("bAllowTickOnDedicatedServer: " .. tostring(primary_actor_tick.bAllowTickOnDedicatedServer)) print("bCanEverTick: " .. tostring(primary_actor_tick.bCanEverTick)) print("bStartWithTickEnabled: " .. tostring(primary_actor_tick.bStartWithTickEnabled)) print("bTickEvenWhenPaused: " .. tostring(primary_actor_tick.bTickEvenWhenPaused)) else print("PrimaryActorTick is nil") end local control_input_vector = pawn.ControlInputVector pawn.ControlInputVector.x = 1.337 print("ControlInputVector: " .. tostring(control_input_vector.x) .. ", " .. tostring(control_input_vector.y) .. ", " .. tostring(control_input_vector.z)) local is_actor_tick_enabled = pawn:IsActorTickEnabled() print("IsActorTickEnabled: " .. tostring(is_actor_tick_enabled)) pawn:SetActorTickEnabled(not is_actor_tick_enabled) is_actor_tick_enabled = pawn:IsActorTickEnabled() print("New IsActorTickEnabled: " .. tostring(is_actor_tick_enabled)) pawn:SetActorTickEnabled(not is_actor_tick_enabled) -- resets it back to default local life_span = pawn:GetLifeSpan() local og_life_span = life_span print("LifeSpan: " .. tostring(life_span)) pawn:SetLifeSpan(10.0) life_span = pawn:GetLifeSpan() print("New LifeSpan: " .. tostring(life_span)) pawn:SetLifeSpan(og_life_span) -- resets it back to default local net_driver_name = pawn.NetDriverName:to_string() print("NetDriverName: " .. net_driver_name) end if player_controller ~= nil then print("PlayerController: " .. player_controller:get_full_name()) end end print("Local players: " .. tostring(local_players)) end last_level = level if once then print("executing stat fps") uevr.api:execute_command("stat fps") once = false print("executing stat unit") uevr.api:execute_command("stat unit") print("GameEngine class: " .. game_engine_class:get_full_name()) print("GameEngine object: " .. game_engine:get_full_name()) end end) uevr.sdk.callbacks.on_script_reset(function() print("Resetting hello_world.lua") end)

Example (when integrated into an environment like UE4SS)

local LuaVR = require("LuaVR") local function vr_print(text) print("[LuaVR Script] " .. text .. "\n") end local params = LuaVR.params local callbacks = params.sdk.callbacks local total_t = 0.0 -- Example usage of callbacks callbacks.on_pre_engine_tick(function(engine, delta) total_t = total_t + delta end) -- Modifies the camera position callbacks.on_post_calculate_stereo_view_offset(function(device, view_index, world_to_meters, position, rotation, is_double) position.z = position.z + 100.0 position.y = position.y - 100.0 end) -- UEVR_PluginInitializeParam -- UEVR_PluginVersion vr_print("Major: " .. tostring(params.version.major)) vr_print("Minor: " .. tostring(params.version.minor)) vr_print("Patch: " .. tostring(params.version.patch)) -- UEVR_PluginFunctions vr_print("Is drawing ui: " .. tostring(params.functions.is_drawing_ui())) params.functions.log_info("Hello from LuaVR!") params.functions.log_warn("Hello from LuaVR!") params.functions.log_error("Hello from LuaVR!") -- UEVR_VRData vr_print("Runtime ready state: " .. tostring(params.vr.is_runtime_ready())) vr_print("Is OpenVR: " .. tostring(params.vr.is_openvr())) vr_print("Is OpenXR: " .. tostring(params.vr.is_openxr())) vr_print("Is HMD Active: " .. tostring(params.vr.is_hmd_active())) local standing_origin = UEVR_Vector3f.new() params.vr.get_standing_origin(standing_origin) vr_print("Standing Origin: " .. tostring(standing_origin.x) .. ", " .. tostring(standing_origin.y) .. ", " .. tostring(standing_origin.z)) local rotation_offset = UEVR_Vector3f.new() params.vr.get_rotation_offset(rotation_offset) vr_print("Rotation Offset: " .. tostring(rotation_offset.x) .. ", " .. tostring(rotation_offset.y) .. ", " .. tostring(rotation_offset.z)) local hmd_index = params.vr.get_hmd_index() vr_print("HMD Index: " .. tostring(hmd_index)) local left_controller_index = params.vr.get_left_controller_index() vr_print("Left Controller Index: " .. tostring(left_controller_index)) local right_controller_index = params.vr.get_right_controller_index() vr_print("Right Controller Index: " .. tostring(right_controller_index)) local hmd_position = UEVR_Vector3f.new() local hmd_rotation = UEVR_Quaternionf.new() params.vr.get_pose(hmd_index, hmd_position, hmd_rotation) vr_print("HMD Position: " .. tostring(hmd_position.x) .. ", " .. tostring(hmd_position.y) .. ", " .. tostring(hmd_position.z)) vr_print("HMD Rotation: " .. tostring(hmd_rotation.x) .. ", " .. tostring(hmd_rotation.y) .. ", " .. tostring(hmd_rotation.z) .. ", " .. tostring(hmd_rotation.w)) if left_controller_index ~= -1 then local left_controller_position = UEVR_Vector3f.new() local left_controller_rotation = UEVR_Quaternionf.new() params.vr.get_pose(left_controller_index, left_controller_position, left_controller_rotation) vr_print("Left Controller Position: " .. tostring(left_controller_position.x) .. ", " .. tostring(left_controller_position.y) .. ", " .. tostring(left_controller_position.z)) vr_print("Left Controller Rotation: " .. tostring(left_controller_rotation.x) .. ", " .. tostring(left_controller_rotation.y) .. ", " .. tostring(left_controller_rotation.z) .. ", " .. tostring(left_controller_rotation.w)) end if right_controller_index ~= -1 then local right_controller_position = UEVR_Vector3f.new() local right_controller_rotation = UEVR_Quaternionf.new() params.vr.get_pose(right_controller_index, right_controller_position, right_controller_rotation) vr_print("Right Controller Position: " .. tostring(right_controller_position.x) .. ", " .. tostring(right_controller_position.y) .. ", " .. tostring(right_controller_position.z)) vr_print("Right Controller Rotation: " .. tostring(right_controller_rotation.x) .. ", " .. tostring(right_controller_rotation.y) .. ", " .. tostring(right_controller_rotation.z) .. ", " .. tostring(right_controller_rotation.w)) end local left_eye_offset = UEVR_Vector3f.new() local right_eye_offset = UEVR_Vector3f.new() params.vr.get_eye_offset(0, left_eye_offset) params.vr.get_eye_offset(1, right_eye_offset) vr_print("Left Eye Offset: " .. tostring(left_eye_offset.x) .. ", " .. tostring(left_eye_offset.y) .. ", " .. tostring(left_eye_offset.z)) vr_print("Right Eye Offset: " .. tostring(right_eye_offset.x) .. ", " .. tostring(right_eye_offset.y) .. ", " .. tostring(right_eye_offset.z)) local is_using_controllers = params.vr.is_using_controllers() vr_print("Is Using Controllers: " .. tostring(is_using_controllers))