Hello, I have recently started using Defold to try to create a video game.
However, I am having an issue with the physics engine. My game objects will
only collide if I set the group and mask for all objects to the same value.
If I set one object to, for instance, “enemy” and set the mask to “enemy”, “default” the enemy
object will no longer collide with any other objects in the collection. Has anyone experienced this or
know what to do to solve it?
My player is able to push the enemies if colliding and the trigger debug circle shown will register the trigger if the player and enemies are within “range” using the following code:
if message_id == hash(“trigger_response”) then
However, once I change the enemy to use enemy group “enemy” the collisions and trigger responses are ignored.
The player object has a collisionobject sphere shape which is Kinematic. It also has a range collision object w/ a sphere which is larger and Trigger type. These are just placeholder graphics by the way
Tried again. It’s working now for the player/enemy collisions, but the enemies are now passing through the walls (static physics object) while previously they would collide and stop moving… The walls are “default” group/mask without any quotes.
EDIT: I change the wall mask to “default, enemy” to register hits to the enemies. Now, the enemies don’t pass through the wall when being pushed, but once stopped by a wall the player enters inside the enemy or the enemy teleports to just adjacent to the player…
Is there any way to determine the object type from a collision without using the group names? It would be much simpler if I could just ignore this feature and use the object types.
I see that you are using Kinematic physics objects. You are resolving the collisions on your own right?
What do you mean by object type? Which game object it is? You can get the object group and the object id from the collision_response or contact_point_response message (fields other_group and other_id).
I have the other_id of the object and tried setting a property in the enemy script via the following code:
go.property("objtype", "enemy")
The enemy is set to dynamic and the player is kinematic but I am resolving collisions with the walls manually following the platformer tutorial example.
When I attempt to lookup the property with the following code:
local objtype = go.get(hash(message.other_id), "objtype")
pprint("what's the type? ", objtype)
I get an error message such as “’/instance313’ does not have any property called ‘objtype’”
I just tried this. All my objects have scripts called “logic.script” and are added to the game objects with the id “logic” so that way I can access the properties without knowing what the object type is in advance. However, when I try to use the code you suggested I see an error:
DEBUG:SCRIPT: url: [world:/instance264#logic]
ERROR:SCRIPT: /player/logic.script:79: '/instance264#logic' does not have any property called 'objtype'
The code in my player’s logic.script file has the following function:
function on_message(self, message_id, message, sender)
if message_id == hash("trigger_response") then
local script_url = msg.url(nil, message.other_id, "logic")
pprint(script_url)
local objtype = go.get(script_url, "objtype")
pprint("what's the type? ", objtype)
elseif message_id == hash("contact_point_response") then
if message.group == hash("default") then
handle_geometry_contact(self, message.normal, message.distance)
end
end
end
and the code in my enemy’s logic.script file contains this:
function init(self)
go.property("objtype", "enemy")
end
All objects set a property “objtype” similar to the enemy in the init function.
The script properties must be declared outside any of the lifecycle functions (not inside init)! A common practice is to put them at the top of the .script file.
Alright I now have in the wall/enemy logic.script files just a single line each setting the objtype property, but still the same not sure what I’m doing wrong here. Sorry for the difficulty here I just started learning Defold so still wrapping my head around it.
Another thing to point out is that unless you plan on having many types of objects you should be fine using the collision group to identify what you collided with (enemy, wall, weapon etc).
I created a gop.lua file and use the gop method to pull up the object properties for each instance and then read the objtype property from that.
EDIT: I modified the gop.lua file suggested as such btw:
local M = {}
local gop_tables = {}
function M.get(url)
url = url or msg.url(".")
if type(url) == "string" then url = msg.url(url) end
if gop_tables[url.path] == nil then gop_tables[url.path] = {} end
return gop_tables[url.path]
end
function M.final(url)
url = url or msg.url(".")
if type(url) == "string" then url = msg.url(url) end
gop_tables[url.path] = nil
end
gop = M
In case anyone is reading this now, I don’t recommend using the gop.lua module unless absolutely needed. It does its job well, but it’s much better to use the groups as others advised here If anyone needs help with it, feel free to let me know.