Is characterBody2D position wrong? or am I just stupid?

Godot Version

4.4

Question

I have a characterbody2d with a circle collision shape like below:

-CharacterBody2D - script
⌞CollisionShape2D (Circle shape)

The characterbody2d has the following script:

extends CharacterBody2D

@export var speed: int

func _ready() -> void:
	pass
	
func _process(delta: float) -> void:
	velocity = speed * Input.get_vector("left","right", "up", "down")
	move_and_slide()
	queue_redraw()

func _draw() -> void:
	draw_circle(global_position, 40.0, Color.BLUE, true, 1.0, false)

My idea was to draw a circle, and be able to move it, which seemed to work until I turned on visible collision shapes, which allowed me to observe the following behaviour:

Basically the further I am from the origin the more the collision shape and the drawing of the cirlce separate from each other

I don’t understand what’s wrong with this:
Is the position of the characterbody2d different from the rendered position?
Is that position supposed to be used only internally by godot and we should not mess around with that?
Is this issue related to the queue_redraw? When I turn it off seems to disappear, but if the screen resizes then the circle jumps. I’m guessing the resizing of the screen queues a redraw

am I just stupid and did something wrong?

1 Like

Did you by chance set the collision shape to Top Level?

Do you mean like, putting it as the father of the characterbody2d node?
If that’s the question, then, no

If you mean something else, then, can you let me know how to check if it’s on top level?

have you tried drawing the circle at Vector2.ZERO

draw_circle(Vector2.ZERO, 40.0, Color.BLUE, true, 1.0, false)
2 Likes

Putting something as top level is a Boolean variable under the transform tab

I think it’s something to do with local vs global coordinates? I am trying to think of a solution or have a better understanding. I remember having a similar problem when using Unity. but its been so long.

Gotcha, no, is not top level. Seems like putting it in vector zero does the trick as it was pointed by gertkeno

2 Likes

Yes, this seems to work. Makes me wonder, is the position of the drawing relative to the node which is calling it?

1 Like

The _draw function is relative to the Node2D’s transform, or similar for Control nodes.

Awesome, glad you two figured it out!

Thanks for the help!
I learned what top level is

1 Like

You’re very welcome, I’m glad I was able to help :+1:

1 Like

I see, I guess it makes sense since, when making more complex drawings is easier for us to let the engine apply the node’s transform instead of recalculating each point of the drawing ourselves
Thanks for the help!