[SOLVED] How to get an object id that spawned from a factory

Hello, dear Defold community! I have a problem, again :slight_smile:
I have ten different GO (call them “items”) with one item.script. Also, I have factories that spawn these GO.
Every “item” has a unique sprite and label but the same script.
I need to compare spawned “items” with the "reference"
I tried to do it by id, I wrote some code into the item.script

function init(self)
	item_id = go.get_id()
	print(item_id .. ' spawned')
end

but every item that spawned from the factory has id like “[/instance9]” where “9” just a serial number.

I the factory spawns one item every 5 sec it will be “[/instance0]” every time

Can you help me and explain how I can make the setup that I want?

I have solved this problem by adding a unique group ID to each “item” object. And detect collisions with this code

        if message.enter then
			if message.other_group == hash('item_1') then
				print('I caught the 1 ')
			elseif message.other_group == hash('item_2') then
				print('I caught the 2 ')
			end
		end

First, I’d recommend you read up on the local keyword from Lua, and it’s use in the Defold context.
The code item_id = go.get_id() is prone to be overwritten if there are multiple instances of that script.

See documentation.

Also, for your second approach, be aware that there is a maximum of 16 collision groups (if I recall correctly).

1 Like

Thank you! I didn’t know that.
So looks like my approach with a unique group ID is not good. But how I can solve it in another way?

You could take a look at the script properties to read and write custom properties:
Script component properties (defold.com)

This part might be especially helpful in your use-case.

3 Likes

I think what you want is to pass some data to your spawned instances via the factory, which can then be used to identify the item type.

local instance_of_item_1 = factory.create(component, p, nil, { item_type = 1 })
local another_instance_of_item_1 = factory.create(component, p, nil, { item_type = 1 }) 

local instance_of_item_2 = factory.create(component, p, nil, { item_type = 2 })
-- item.script
-- item_type set when created via factory
go.property("item_type",  1)

You can also send a message to the created instance if you need to pass strings as data, instead of using the properties.

edit - Piro beat me to it :smiley:

4 Likes

Guys… You are brilliant! Yes, it solves my problem. Thank you very much!

2 Likes

Can I add some questions to this topic?
I’m trying to read the property “item_id” on the “item” from another collider
I use this code

if message_id == hash("trigger_response") then
        if message.enter then
			if message.other_group == hash('item') then
				local item_property = go.get(message.other_id, 'item_id')
				print(item_property)
				-- msg.post('GUI#level_ui', 'increase_soup_score')
			end
		end
	end

And I got an error

ERROR:SCRIPT: assets/scripts/cauldron.script:32: '/instance0' does not have any property called 'item_id'

But it has

go.property('item_id', 0)

Where did I make a mistake?

You need to get the property from the script component, not the game object itself. See here: Script component properties

1 Like

Thank you! It’s works