Calling function from another script in same gameobject (SOLVED)

I have a scripe ‘can_move’ and a script ‘basic_ai’. The script ‘basic_ai’ should be able to tell the can_move script to move left or right, up or down. Somehow I don’t get it to work though. I tried these three things.

My GameObject looks like this:

basic_ai.script:
local idle = 0
local moving = 1
local playing = 2

function init(self)
    self.state = idle
    self.time = 0
end

function update(self, dt)
    self.time = self.time + dt
    if self.time < 10 then
    	-- self.speed.x = -150
    	-- move_left(self)
    	msg.post("#can_move", "move_left")
    elseif self.time < 100 then
    	-- self.speed.y = 150
    	-- move_up(self)
    	msg.post("#can_move", "move_up")
    elseif self.time > 100 then
    	-- self.speed.x = 150
    	-- move_right(self)
    	msg.post("#can_move", "move_right")
    end
end

function on_message(self, message_id, message, sender)
    -- Add message-handling code here
    -- Remove this function if not needed
end

can_move.script
local max_speed = 150

-- screen borders
local min_x = 70
local max_x = 1210
local min_y = 70
local max_y = 650

-- pre-hashing ids
local move_up = hash("move_up")
local move_down = hash("move_down")
local move_left = hash("move_left")
local move_right = hash("move_right")

function init(self)
    self.speed = vmath.vector3(0, 0, 0)
end

local function move_up(self)
	self.speed.y = max_speed
end

local function move_down(self)
	self.speed.y = -max_speed
end

local function move_left(self)
	self.speed.x = -max_speed
end

local function move_right(self)
	self.speed.x = max_speed
end

local function check_screen_borders(position)
	if position.x < min_x then
		position.x = min_x
	elseif position.x > max_x then
		position.x = max_x
	end
	if position.y < min_y then
		position.y = min_y
	elseif position.y > max_y then
		position.y = max_y
	end
end

function update(self, dt)
    local position = go.get_position()
    position.x = position.x + self.speed.x * dt
    position.y = position.y + self.speed.y * dt
    check_screen_borders(position)
    go.set_position(position)
    self.speed.x = 0
    self.speed.y = 0
end

function on_message(self, message_id, message, sender)
    if message_id == move_up then
    	move_up(self)
    elseif message_id == move_down then
    	move_down(self)
    elseif message_id == move_left then
    	move_left(self)
    elseif message_id == move_right then
    	move_right(self)
    end
end

I thought because of the lua context (http://www.defold.com/doc/scripting?null#_lua_contexts) I could call directly the function of another script in my gameobject. Or am I doing something wrong? I also tried to use the message or directly accessing the variable, but didn’t work as well.

The first two options will not work:

  1. The basic_ai.script cannot access the properties of can_move.script. You can use go.property() to expose a property of a script to the “outside world”. This property will show up as something you can modify from the properties window, and other scripts can read and write the value using go.set() and go.get(). Note that using go.get() and go.set() is slow and it’s not recommended in say an update() loop.

  2. The basic_ai.script cannot access the local functions of the can_move.script. And if you declared the functions global (ie without local keyword) you’d be in an even worse position.

The way to do it is through message passing, like you’re doing in your code. Is it not working? Don’t you get the messages in can_move.script?

Thanks. Good to know that I tried to do the right thing in the beginning.
Somehow my gameobject won’t move by itself on my screen. So I guess the message doesn’t reach the can_move.script.

I’m only able to run the HTML5 version right now, so pprint() doesn’t really help to find out whether messages are received or not, since there is no console where I can see the prints.

OK. I got it. I tried it again with the messages after you confirmed me that I did the right thing with them.

It looks like I messed up variable names and function names. It was a naming conflict. Cause after renaming the pre-hashed message_ids it worked.

function on_message(self, message_id, message, sender)
    if message_id == move_up_hash then
    	move_up(self)
    elseif message_id == move_down_hash then
    	move_down(self)
    elseif message_id == move_left_hash then
    	move_left(self)
    elseif message_id == move_right_hash then
    	move_right(self)
    end
end

Ok, good to know that you solved it!