Player velocity and position Set Get

Godot Version

4.2.2.stable

Question

I want to send a signal whenever the position of a CharacterBody2D changes. I used Set Get on a position variable to send the signal but it doesn’t work.

From my understanding, Set Get only detects when the variable is directly changed. I am using velocity to move the character so I am not actually directly changing the position. Is there a way around this or am I doing something else wrong?

extends CharacterBody2D

var player_speed: int = 51200
var pos = self.position:
	get:
		return pos
	set(value):
		pos = value
		position_updated.emit()

signal position_updated

func _physics_process(delta):
	player_movement(delta)

func player_movement(delta):
	if Input.is_action_pressed("down"):
		velocity.x = 0
		velocity.y = -player_speed * delta
	if Input.is_action_pressed("up"):
		velocity.x = 0
		velocity.y = player_speed * delta
	if Input.is_action_pressed("right"):
		velocity.x = player_speed * delta
		velocity.y = 0
	if Input.is_action_pressed("left"):
		velocity.x = -player_speed * delta
		velocity.y = 0

position_updated is only emitted when you set (change) pos variable. Even changing position or global_position doesn’t emit it, only changing pos.

You could store the previous position in a variable and then check in _process if it has changed, then emit the signal.

2 Likes

Thanks for suggesting that. The problem I wanted to solve ended up being much more convoluted but I ended up fixing it.

1 Like

You can emit your signal before move_and_slide if velocity is not zero

if not velocity.is_zero_approx():
    position_updated.emit()
move_and_slide()

Or to be more accurate, store it’s state then emit after move_and_slide

var moving: bool = not velocity.is_zero_approx()
move_and_slide()

if moving:
    position_updated.emit()