-
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 Engine.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 is one more - Vec3. It is just table with three numbers.
-
void Engine.logError(string text) -
void Engine.logInfo(string text) -
Vec3 Engine.multVecQuat(Vec3 vec, Vec3 axis, number angle) -
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) -
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) -
void Engine.setRenderablePath(Scene scene, Component cmp, string path) -
Table Engine.getEnvironment(Scene scene, Entity entity, number script_index)#620```
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)Entity 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)
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
})