Skip to main content

Casting and Recasting Laser Beams

·486 words·3 mins

Following a tutorial for laser beams here: https://www.youtube.com/watch?v=dg0CQ6NPDn8&ab_channel=GDQuest

It’s only one minute long but is it ever fast! Lots of pausing and playing.

Also switched over to static typing to avoid headaches in the future and to get better autocomplete. There were a couple of things I had to figure out to get my current code to compile. One of those was to include a class name declaration at the top of my GDScript.

block.gd

extends RigidBody2D

class_name Block

...

That exports the name Block globally so other GDScript files can import it.

Collision Debouncing
#

I have a Laser scene that’s a RayCast2D. If a collision is detected it adds a new Laser scene as a child, rotated by PI/4 for now… I’ll do the refraction index later. Most of the time it looks like this:

But sometimes, especially when I’m dragging, it flickers with an image like this:

By the way, that image was a pain to capture. I tried recording videos using Ubuntu’s screencast and Godot’s movie maker but both were horrible quality. The above is the result of several attempts at just pressing the print screen button at just the right time.

Anyway. I think it’s because when a collision is detected the child laser is added but it isn’t updated right away. That short stub is the default length of the Line2D used to render the laser.

More importantly, I think I need to debounce the collision detection. It detects a collision, adds the laser, then detects no collision and removes it. Or the child laser detects a collision and then I see a rotation of PI/2 instead of PI/4, but only briefly before it gets removed.

So… I don’t want to change is_colliding so frequently. If it’s been colliding for a few frames then I can create a child Laser instance. If it’s been not colliding for a few frames then I can remove it.

Got rid of the first problem by having the laser line start off hidden, only showing on its first call to _physics_process(). That seems to have solved it.

For the second problem I wrote a simple BoolDebouncer which only allows its value to be changed if it hasn’t changed for 500 ms. That’s a huge delay only to make it easier to troubleshoot for now.

It’s not solving the problem, though. I still get different angles and sometimes the laser even collides with its own emitter, giving this output:

At least, I think that’s what’s going on… but why is it angling in that particular direction?

Might need to track the object the ray collided with and prevent future collisions with the same object. Or at least the same side of the same object. That might not work for a curved surface, though. The ray might legitimately collide with the same surface twice.

Could be hitting limitations of the engine pretty quickly here, we’ll see.