Player scene dissapearing randomly

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

I was working on a simple movement test, and for some reason the player scene will randomly disspear when moving around

Printing the .visible property still returns true, as do all the movement variables

Only active script;

extends KinematicBody2D



# Called when the node enters the scene tree for the first time.
func _ready():
	pass # Replace with function body.

var horizontalMove
var verticalMove
var velocity : Vector2
var speed : float = 200
var accel : float = 10
var friction : float = 10
func get_input():
	velocity = Vector2.ZERO
	horizontalMove = Input.get_axis("moveLeft", "moveRight")
	verticalMove = Input.get_axis("moveUp","moveDown")
	velocity = Vector2(horizontalMove,verticalMove)

func apply_friction():
	velocity.x = move_toward(velocity.x, 0, friction)
	velocity.y = move_toward(velocity.y, 0, friction)
	
func apply_acceleration(_amount):
	pass

func _physics_process(_delta):
	velocity = move_and_slide(velocity * speed)
	apply_friction()

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
	get_input()
	if Input.is_action_just_pressed("test"):
		print($Sprite.visible)
	

Here is a sample scene - https://drive.google.com/file/d/1Z0JeC1SHJ57WRXCb9lENnLLF7kfnhKbo/view?usp=sharing

Am I missing something incredibly obvious here?

Thanks in advance,
Gian

:bust_in_silhouette: Reply From: DownloadFLD

What’s happening is your player scene is jumping quickly in the direction they’re travelling at seemingly random intervals. If you run your scene and go to the Remote view of the scene tree in the editor, you can inspect the values of your various scenes and nodes. Watch your Player’s transform when they disappear and it’ll read in the hundreds in one or both axes. So the player is still “visible”, but they’ve just catapulted off-screen.

I was able to “fix” this by simply not reassigning velocity to the result of move_and_slide() in _physics_process():

func _physics_process(_delta):
    move_and_slide(velocity * speed)
    apply_friction()

This stops the player from teleporting, but I’m not sure it will produce the result you want. I assume your apply_friction() function is meant to bring your player to a sliding stop over time. A couple other methods to do this could be to use lerp() or move_toward() in a similar way to how you’re doing it now:

lerp():

speed = lerp(speed, 0, friction)
move_and_slide(direction * speed)

move_toward():

velocity = velocity.move_toward(Vector2.ZERO, friction)
move_and_slide(velocity)

Both of these methods are very similar, where the lerp() option is affecting the speed of your character and applying it to a movement direction Vector2, while the move_toward() method is affecting the whole velocity vector which already has speed factored into it. Additionally, you’re already doing the second method with move_toward(), but you don’t need to break it up into individual axes! move_toward() will also take Vector2s.

I’d look into a couple movement controllers in the asset library and/or movement tutorials to get some ideas on even more ways to move your player, and how to properly use delta in your physics and process functions. Using delta in your movement calculations helps ensure a consistent move speed across varying framerates.
Here’s a helpful godot doc going over a few different methods of moving in 2D:

And here’s a video from a helpful tutorial series going over the basics of making a basic, 2D top-down RPG:

This is really helpful, thanks for your comment!

giancoppola | 2022-07-26 20:27

Really great answer. Please consider continuing to contribute, your input would be very much appreciated.

DaddyMonster | 2022-07-26 20:43

That’s so kind, thank you for the encouraging words! Godot is new to me but I’ve got a feeling I’ll be sticking around for quite a while.

DownloadFLD | 2022-07-26 21:34