-
Notifications
You must be signed in to change notification settings - Fork 433
Lua scripting
Lua script plugin provides an option to script using Lua. It provides a new type of component, which points to a lua script file. This file is executed when a game starts. Each component has lua sandboxed - it means that all variables and function are not accessible from other components unless they are put in the global table _G or accessed using LuaScript.getEnvironment.
Each script can contain function update(dt) and this function is called each frame.
Universe g_universeEngine g_engine
All scenes are visible to script as global variables, each with prefix "g_scene_" and ends with the name of a plugin, e.g.:
g_scene_rendererg_scene_animationg_scene_audiog_scene_physicsg_scene_lua_script
Every Vec3, color, decimal, integer and boolean property (you can see properties in the property grid in the editor) can be accessed from Lua. However name of a property is transformed in following way:
- Remove all nonalphabetic characters,
- If a character is after nonalphabetic character in the source name, it is uppercase in the Lua name.
For example:
-- property Fog color
GlobalLight.setFogColor(g_scene_renderer, cmp, {1, 0, 1})
local color = GlobalLight.getFogColor(g_scene_renderer, cmp) -- color == {1, 0, 1}Other than standard lua types there following types:
- Vec3 - a table with 3 numbers
- Quat - a table with 4 numbers
-
Entity Engine.createEntity(Universe universe) -
void Engine.logError(string text) -
void Engine.logInfo(string text) -
Vec3 Engine.multVecQuat(Vec3 vec, Vec3 axis, number angle) -
Vec3 Engine.multVecQuat(Vec3 vec, Quat quat) -
void Engine.setEntityPosition(Universe univ, Entity entity, Vec3 position) -
Vec3 Engine.getEntityPosition(Universe univ, Entity entity) -
void Engine.setEntityRotation(Universe univ, Entity entity, Vec3 axis, number angle) -
Quat Engine.getEntityRotation(Universe univ, Entity entity) -
void Engine.setEntityLocalRotation(Universe univ, Entity entity, Vec3 axis, number angle) -
Component Engine.createComponent(Scene scene, string type, Entity entity) -
void Engine.destroyComponent(Scene scene, string type, Component component) -
Component Engine.getRenderable(Scene scene, Entity entity) -
Entity Engine.createEntityEx(Engine engine, Universe universe, Table entity_description)
Usage:
Engine.createEntityEx(g_engine, g_universe, {
renderable = { Source = "models/utils/cube/cube.msh" },
position = {6, 5, 5}
})-
number LuaScript.addScript(Scene scene, Component script) -
void LuaScript.setScriptSource(Scene scene, Component script, number index, string path) -
Table LuaScript.getEnvironment(Scene scene, Entity entity, number script_index)#620 -
Script LuaScript.preloadScript(Scene scene, string path) -
void LuaScript.setTimer(Scene scene, number time_seconds, function callback) -
void LuaScript.unloadScript(Scene scene, Script script)unloadScripthas to be called once for each call ofpreloadScript
Engine.INPUT_TYPE_DOWNEngine.INPUT_TYPE_PRESSEDEngine.INPUT_TYPE_MOUSE_XEngine.INPUT_TYPE_MOUSE_YEngine.INPUT_TYPE_LTHUMB_XEngine.INPUT_TYPE_LTHUMB_YEngine.INPUT_TYPE_RTHUMB_XEngine.INPUT_TYPE_RTHUMB_YEngine.INPUT_TYPE_RTRIGGEREngine.INPUT_TYPE_LTRIGGER
number Engine.getInputActionValue(Engine engine, number action)void Engine.addInputAction(Engine engine, number action, number type, number key)
local LEFT_ACTION = 0
function init()
cmp = Engine.createComponent(g_scene_physics, "physical_controller", this)
Engine.addInputAction(g_engine, LEFT_ACTION, Engine.INPUT_TYPE_PRESSED, string.byte("A"), -1)
end
function update(dt)
local speed = 1
if Engine.getInputActionValue(g_engine, LEFT_ACTION) > 0 then
local v = Engine.multVecQuat({-speed, 0, 0}, {0, 1, 0}, yaw)
Physics.moveController(g_scene_physics, cmp, v, dt)
end
end
void Physics.moveController(Scene scene, Component cmp, Vec3 velocity, number time_delta)number Physics.getActorSpeed(Scene scene, Component cmp)Component Physics.getActorComponent(Scene scene, Entity entity)void Physics.putToSleep(Scene scene, Component component)void Physics.applyForceToActor(Scene scene, Component component, Vec3 force)is_hit, hit_entity, hit_position Physics.raycast(Scene scene, Vec3 origin, Vec3 dir)
If two entities with a physical component collide, onContact function is called in script on both of them:
function onContact(entity)
API_logError("not implemented - onContact(" .. entity .. ")")
endSoundHandle Audio.playSound(Scene scene, Entity entity, string clip_name, bool is_3d)void Audio.setSoundVolume(Scene scene, SoundHandle sound_id, number volume)void Audio.setEcho(IScene* scene, SoundHandle sound, number wet_dry_mix, number feedback, number left_delay, number right_delay)
string Renderer.getCameraSlot(Camera component)Camera Renderer.getCameraComponent(Entity entity)Renderable Renderer.getRenderableComponent(Entity entity)void Renderer.addDebugCross(Vec3 center, number size, number rgba_color, number life)Material Renderer.getTerrainMaterial(Terrain component)Texture Renderer.getMaterialTexture(Material material, number texture_index)void Renderer.setRenderableMaterial(Scene scene, Renderable component, number material_index, string path)void Renderer.setRenderablePath(Scene scene, Renderable component, string path)
bool Navigation.generateNavmesh()void navigate(Entity entity, Vec3 destination, number speed)void debugDrawCompactHeightfield()void debugDrawNavmesh()void debugDrawHeightfield()void debugDrawPaths()void debugDrawContours()number getPolygonCount()void generateTile(number x, number y, bool keep_data)bool save(string path)bool load(string path)void setGeneratorParams(number cell_size, number cell_height, number agent_radius, number agent_height, number walkable_angle, number max_climb)
function onPathFinished() ...Lua function onPathFinished is called on an entity which finished its path.
Following dear imgui functions are available in lua:
-
bool, number ImGui.DragFloat(string label, number value)The first returned value indicates whether
valuehas been changed. The second returned value is the newvalue -
bool ImGui.Button(string label)Returns true if the button has been clicked.
-
bool, bool ImGui.Checkbox(string label, bool checked)The first returned value indicates whether `checked` values has been changed. The second returned value is the new `checked`.
x = 0
checked = true
function onGUI()
-- button
if ImGui.Button("Test") then
Engine.logError("Test clicked.")
end
-- drag float
local changed = false
changed, x = ImGui.DragFloat("Drag float", x)
if changed then
Engine.logError("X changed, new value = " .. tostring(x))
end
-- checkbox
changed, checked = ImGui.Checkbox("Checkbox", checked)
if changed then
if checked then
Engine.logError("Checkbox is checked")
else
Engine.logError("Checkbox is unchecked")
end
end
endEditor.importAsset(Editor.import_asset_dialog,
{
output_dir = "D:\\Projects\\lumixengine_data\\models\\test\\yyy",
srcs = {
{
src = "C:\\Users\\Miki\\Downloads\\Nature Pack\\Nature Pack\\Objects\\Birch_01.fbx" ,
materials = {
{
matching = function(idx, name) return name:lower():find("branch") ~= nil end,
import = true,
shader = "leaves",
alpha_cutout = true,
textures = {
{
import = false,
to_dds = true
}
},
},
{
matching = function(idx, name) return name:lower():find("branch") == nil end,
import = true,
textures = {
{
import = true,
to_dds = true,
src = "c:\\path\\to\\texture.tga"
}
},
},
}
}
},
create_billboard = false,
scale = 0.01
})Import all .obj from a directory (Windows only):
for filename in io.popen([[dir "C:\Users\Miki\Downloads\3D Nature pack\Models\" /b]]):lines() do
if string.sub(filename,-string.len(".obj"))==".obj" then
Editor.importAsset(Editor.import_asset_dialog,
{
output_dir = "C:\\projects\\lumixengine_data\\models\\test",
lods = { 10, 100, -1, -1}, -- -1 == infinite distance
srcs = {
{
src = [[C:\Users\Miki\Downloads\3D Nature pack\Models\]] .. filename,
materials = {
{
matching = function(idx, name) return true end,
import = true,
},
}
}
}
})
Engine.logError(filename .. " imported")
end
endApp.loadUniverse(App.instance, "universes/player.unv")
while Engine.hasFilesystemWork(g_engine) do Engine.processFilesystemWork(g_engine) end
Engine.startGame(g_engine, App.universe)