Hi, I am using a PhysicsServer2D on a bullet hell project that I’m working to improve performance, and I managed to spawn bullets in the server, but I’m still very new to this and I have no idea how to make collision work.
How would I be able to detect when the bullet collides with a non-physicsserver object (for example, a bullet getting queue_free() after colliding with a bullet_killzone area2d)
How would I be able to detect when something collides with a bullet? (for example, the player losing HP after a bullet collided with it)
Here is the current code for my bullets :
extends Node2D
var object
var image
@onready var shape = RectangleShape2D.new()
@export var texture : Texture2D
var bulletPosition
var bulletRotation
var bulletSize
var bulletSpeed
var physicsServer
var renderServer
var direction
func _ready():
direction = Vector2.RIGHT.rotated(deg_to_rad(bulletRotation))
shape.size = Vector2(64, 64)
physicsServer = PhysicsServer2D
object = physicsServer.body_create()
physicsServer.body_set_space(object, get_world_2d().space)
physicsServer.body_add_shape(object, shape)
var objectTransform = Transform2D(0, Vector2(bulletSize, bulletSize), 0, bulletPosition)
physicsServer.body_set_state(object, PhysicsServer2D.BODY_STATE_TRANSFORM, objectTransform)
physicsServer.body_set_mode(object, PhysicsServer2D.BODY_MODE_KINEMATIC)
physicsServer.body_set_collision_layer(object, 2)
renderServer = RenderingServer
image = renderServer.canvas_item_create()
renderServer.canvas_item_set_parent(image, get_canvas_item())
renderServer.canvas_item_add_texture_rect(image, Rect2(-32, -32, 64, 64), texture)
renderServer.canvas_item_set_transform(image, objectTransform)
func _physics_process(delta):
bulletPosition += direction * bulletSpeed * delta
var objectTransform = Transform2D(0, Vector2(bulletSize, bulletSize), 0, bulletPosition)
physicsServer.body_set_state(object, PhysicsServer2D.BODY_STATE_TRANSFORM, objectTransform)
renderServer.canvas_item_set_transform(image, objectTransform)
func _exit_tree():
PhysicsServer2D.free_rid(object)
RenderingServer.free_rid(image)
I’m curious to why spawning physics bodies and canvas items manually, in GD script, is going to improve performance? Traditional scene spawning will do this all for you in native code.
If you want to improve performance you need to use a GPUparticle node with collision detection enabled and a sub_emitter for collision effects.
Anyway to answer your question _body_set_sync_state_callback
This will notify you when there is a change and will return a physicsDirectBodyState2d to the callback function. This will allow you to manage all the collision information manually.
Thank you so much! As to why I’m using a physics server, I don’t really know tbh I thought it improved performance for the bullets to be managed by it?? Idk I’ll have to do more research
The only thing I think it would avoid is having nodes in the scene tree. Which I’m not sure is that much of a save compared to the number of interactions in GD script here.
I was thinking about GPUparticles and I’m not sure how to get the collision info back. There other option is a compute shader. But that would require you to develop your own physical checks.
Anyway I watched this a while back can’t remember what they did.
So I really wish I could get more into what is the best approach to improve performance, and I will definitely do so later, but this project is for a game jam that ends monday, so I dont really have time to learn and implement a new method that I currently know nothing about.
In the meantime, im unsure what to do with _body_set_sync_state_callback? Ive done a bit of research but couldnt find anything that was talking about it in the godot documentation, and i dont really know how to implement it into my code?
I was looking at the source code on it. It is basically a signal connecting function. Pass it an rid and a callable func. The callable requires one parameter. (Which is a physicsdirectbodystate.)
If you watch the video he uses a resource pooling technique and he turns off collisions for the bullets and uses a raycast quarry to do bullet collision.
I think you could just set a collision layer on the bullet and turn off the mask to get a similar efficiency. Then just have objects that are collidable mask the bullet layer. (Untested, but it seems that is what the physics quarry is all about.)
I gave up on the Physics server idea and just used regular Area2D for my bullets. To improve performance at least a little bit I toggled the Monitorable propertie off