Sprite2D Lerp to random position inside viewport window

Godot Version

v4.3.stable.official [77dcf97d8]

Question

Hi,
I’m trying to get a sprite to move in random directions inside the window’s boundaries (kinda like fish inside an aquarium)
The problem is this code doesn’t seem to work and I’m not sure why, even if the random position generated is inside the boundaries the sprite goes outside the view and I’m not sure why.
I even tried generating in a range from 0 to 1 and after a couple of times it just goes outside the view. What am I missing here?
I’m not using a camera and even when I tried I got the same results.

extends Sprite2D
@onready var screenSize = get_viewport().get_visible_rect().size

var speed = 3

func _ready():
	randomMovement()
	
func _input(event):
	if Input.is_key_pressed(KEY_K):
		randomMovement()

func randomMovement():
	print("Size:", screenSize)
	var rng = RandomNumberGenerator.new()
	var rndX = rng.randi_range(0, screenSize.x)
	var rndY = rng.randi_range(0, screenSize.y)
	print("X:", rndX,"Y:", rndY)
	
	position = lerp(position, Vector2(rndX, rndY), speed) #* delta)

Even though i am more of a 3D guy, the issue that might be is that in 2D Y direction is reversed. (the more up you go, the more negative the Y value is)

Also the issue might be also where you instantiate/place your Sprite, as far as i am aware position is in local space (local to the sprite), so you might need to use global_position to get the desired result.

But that said, I am just guessing, as i am working of what i know from documentation, as i mainly work with 3D…

Hope this will maybe fix your issue :slight_smile:

The code could look something like this:

global_position = lerp(position, Vector2(rndX, -rndY), speed) * delta)
1 Like

lerp is a simple math equation, it does not animate on it’s own; it is equivalent to this:

func lerp(a, b, t):
    return a + (b - a) * t

You want to use a Tween, something like so

func randomMovement():
	print("Size:", screenSize)
	var rng = RandomNumberGenerator.new()
	var rndX = rng.randi_range(0, screenSize.x)
	var rndY = rng.randi_range(0, screenSize.y)
	print("X:", rndX,"Y:", rndY)
	
	var tween := create_tween()
	tween.tween_property(self, "position", Vector2(rndX, rndY), 1.0)
1 Like

Yes, tween creates the intended effect.

The sprite was going out of bounds because I had the “speed” in the weight value of the Lerp function so it was exceeding the expected results by going over 1.
As the documentation says:

To perform interpolation, weight should be between 0.0 and 1.0 (inclusive). However, values outside this range are allowed and can be used to perform extrapolation.

Extrapolation was obviously not the intended effect in this case.

For anyone that needs to teleport the sprite instantly to the location you can use lerp like this:

	print("Size:", screenSize)
	var rng = RandomNumberGenerator.new()
	var rndX = rng.randi_range(0, screenSize.x)
	var rndY = rng.randi_range(0, screenSize.y)
	print("X:", rndX,"Y:", rndY)
	
	global_position = lerp(position, Vector2(rndX, rndY), 1)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.