Creating a rigidbody with Physics2DServer does not work ?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By ggez

I just copy pasted the code from the docs, and for some reason it does not seem to work. I of course adapted the path to the sprite and double checked everything, but something does not seem to work.
Here is the docs:
https://docs.godotengine.org/de/stable/tutorials/optimization/using_servers.html#creating-a-2d-rigidbody-and-moving-a-sprite-with-it

Here is a pic of the scene tree, and the error message:

Code:

extends Node2D

var body
var shape

var canvas_item


func _body_moved(state, index):
	VisualServer.canvas_item_set_transform(canvas_item, state.transform)


func _ready():
	# create sprite
	var ci_rid = VisualServer.canvas_item_create()
	VisualServer.canvas_item_set_parent(ci_rid, get_canvas_item())
	canvas_item = load("res://icon.png")
	VisualServer.canvas_item_add_texture_rect(ci_rid, Rect2(canvas_item.get_size() / 2, canvas_item.get_size()), canvas_item)
	var xform = Transform2D().rotated(deg2rad(45)).translated(Vector2(20, 30))
	VisualServer.canvas_item_set_transform(ci_rid, xform)


	# create rigidbody
	body = Physics2DServer.body_create()
	Physics2DServer.body_set_mode(body, Physics2DServer.BODY_MODE_RIGID)
	shape = RectangleShape2D.new()
	shape.extents = Vector2(10, 10)
	Physics2DServer.body_add_shape(body, shape)
	Physics2DServer.body_set_space(body, get_world_2d().space)
	Physics2DServer.body_set_state(body, Physics2DServer.BODY_STATE_TRANSFORM, Transform2D(0, Vector2(10, 20)))
	Physics2DServer.body_set_force_integration_callback(body, self, "_body_moved", 0)

The code has a lot of lines, but it’s just this:
https://docs.godotengine.org/de/stable/tutorials/optimization/using_servers.html#creating-a-sprite
and this:
https://docs.godotengine.org/de/stable/tutorials/optimization/using_servers.html#creating-a-2d-rigidbody-and-moving-a-sprite-with-it
combined.

:bust_in_silhouette: Reply From: Jayman2000

The code in the documentation and the code that you posted is misleading.

canvas_item = load("res://icon.png")

The documentation names this variable “sprite”. It is neither a CanvasItem nor a Sprite. By calling get_class(),

canvas_item = load("res://icon.png")
print(canvas_item.get_class())

we can see that it is a StreamTexture. To make the code easier to understand, I recommend renaming it to texture.

var texture


func _body_moved(state, index):
    VisualServer.canvas_item_set_transform(texture, state.transform)


func _ready():
    # create sprite
    var ci_rid = VisualServer.canvas_item_create()
    VisualServer.canvas_item_set_parent(ci_rid, get_canvas_item())
    texture = load("res://icon.png")
    VisualServer.canvas_item_add_texture_rect(ci_rid, Rect2(texture.get_size() / 2, texture.get_size()), texture)

Now, the problem is more apparent. VisualServer.canvas_item_set_transform takes a CanvasItem’s RID as its first argument, but we’re giving it a StreamTexture. We can fix this by making ci_rid a member variable. Here’s what the code looked like when I was done with it:

extends Node2D

var body
var shape

var texture
var ci_rid


func _body_moved(state, index):
    VisualServer.canvas_item_set_transform(ci_rid, state.transform)


func _ready():
    # create sprite
    ci_rid = VisualServer.canvas_item_create()
    VisualServer.canvas_item_set_parent(ci_rid, get_canvas_item())
    texture = load("res://icon.png")
    VisualServer.canvas_item_add_texture_rect(ci_rid, Rect2(texture.get_size() / 2, texture.get_size()), texture)
    var xform = Transform2D().rotated(deg2rad(45)).translated(Vector2(20, 30))
    VisualServer.canvas_item_set_transform(ci_rid, xform)


    # create rigidbody
    body = Physics2DServer.body_create()
    Physics2DServer.body_set_mode(body, Physics2DServer.BODY_MODE_RIGID)
    shape = RectangleShape2D.new()
    shape.extents = Vector2(10, 10)
    Physics2DServer.body_add_shape(body, shape)
    Physics2DServer.body_set_space(body, get_world_2d().space)
    Physics2DServer.body_set_state(body, Physics2DServer.BODY_STATE_TRANSFORM, Transform2D(0, Vector2(10, 20)))
    Physics2DServer.body_set_force_integration_callback(body, self, "_body_moved", 0)

I see. Knew the issue was something with the CanvasItem, Thanks a lot! I will mark this question answered.

ggez | 2021-03-01 10:03