Game Scripting with Lua in Ogre

Today, we will play more with Lua scripting in Ogre. Download the file:

Note that this is an updated version of the OgreScripting project that we used last week, so redownload this one, don't use the old one.

Get the project compiling and running. If you run the program, you get a little cube that you can control with the arrow keys (hold space to move the cube faster). As before, you can bring up the lua console with the ~, and type in commands. One helpful command is print, which displays text on a seconday overlay -- try it out!

Also, there is now a help function, that prints out C++ functions that are exposed to lua

Exposed Functions


We've modified ScriptManager.lua a little since last lecture:

-- Our quick and dirty script system.  We maintain a global array of scripts.  
-- The Ogre Frame Listener calls our ScriptManagerThink function, which in turn
-- calls the Think methods on all active scripts.

-- A more robust scripting system would have an eaiser way of indexing scripts, and
-- activating / deactivating / removing scripts.  This is just quick and dirty enough
-- to work for now.

-- Our table of running scripts
GlobalScripts = { }

-- Method to add a script.

function addScript(script, name)
    if name == nil then
		table.insert(GlobalScripts, script)
		GlobalScripts[name] = script

function removeScript(name)
	GlobalScripts[name] = nil

function ScriptManagerThink(time)
    for i, v in pairs(GlobalScripts) do	   
	   if v:Active() then

-- Handy print method.  Use print instead of debugOutput, to avoid crashes 
-- for nil values and non-string values.
function print(x)

-- Script "Class" -- pretty straighforward for now, scripts have a Think method
-- and an Active method by default, and nothing else
Script = {}

function Script.Active(this)
	return this.isActive

function Script.Think(this, time)


function Script.create()
	local s  = {}
	s.isActive = true	
	s.Active = Script.Active;
	s.Think = Script.Think
	return s

Sample Scripts

File Level1.lua

function destroySeeker(name)
	removeScript(name .. "_script")


function createSeekerTrigger(name, x, y, z)
    x = x or 0
	y = y or z
	z = z or 30
	createTriggerArea(name, x, y, z)
	setTriggerSize(name, 10, 10, 10)
	setOnEnter(name, "if triggerObject == 'player' then  createSeeker('" .. name .. "_seeker', 50, 0, 50)  end")
	setOnExit(name, "if triggerObject == 'player' then  destroySeeker('" .. name .. "_seeker') end")

function createSeeker(name, x, y, z) 
	if name == nil then
		print("createSeeker:  name required!")
	x = x or 0
	y = y or 0
	z = z or 0
	print("Creating Seeker: ID = " .. name .. ",  Location: " .. tostring(x) .. ", " .. tostring(y) .. ",  " .. tostring(z))
	createObject("MyCube.mesh", name)
	setPosition(name, x, y, z)
	setObjectSize(name, 5,1,1)
	local seekerScript = Script.create()
	seekerScript.Think = function(this, time)
		local pX, pY, pZ = getPosition("player")
		local mX, mY, mZ =  getPosition(name)
		local deltaX, deltaY, deltaZ = pX-mX, pY-mY, pZ - mZ
		setVelocity(name, deltaX , deltaY, deltaZ)
	-- We are using the 
	addScript(seekerScript, name .. "_script")


In-Class Exercise

Now to work! In the Content/Scripts folder, open up the level1.lua file, and extend it in the following ways