Godot 3 to Godot 4 migration

Godot Version

4.2

Question

I was following GdQuest LaserBeam tutorial and find some issues while converting LeaserBeam2D from Godot 3 to Godot 4.

Original Code

# Casts a laser along a raycast, emitting particles on the impact point.
# Use `is_casting` to make the laser fire and stop.
# You can attach it to a weapon or a ship; the laser will rotate with its parent.
extends RayCast2D

# Speed at which the laser extends when first fired, in pixels per seconds.
export var cast_speed := 7000.0
# Maximum length of the laser in pixels.
export var max_length := 1400.0
# Base duration of the tween animation in seconds.
export var growth_time := 0.1

# If `true`, the laser is firing.
# It plays appearing and disappearing animations when it's not animating.
# See `appear()` and `disappear()` for more information.
var is_casting := false setget set_is_casting

onready var fill := $FillLine2D
onready var tween := $Tween
onready var casting_particles := $CastingParticles2D
onready var collision_particles := $CollisionParticles2D
onready var beam_particles := $BeamParticles2D

onready var line_width: float = fill.width


func _ready() -> void:
	set_physics_process(false)
	fill.points[1] = Vector2.ZERO


func _physics_process(delta: float) -> void:
	cast_to = (cast_to + Vector2.RIGHT * cast_speed * delta).limit_length(max_length)
	cast_beam()


func set_is_casting(cast: bool) -> void:
	is_casting = cast
	
	if is_casting:
		cast_to = Vector2.ZERO
		fill.points[1] = cast_to
		appear()
	else:
		# Reset the laser endpoint
		fill.points[1] = Vector2.ZERO
		
		collision_particles.emitting = false
		disappear()

	set_physics_process(is_casting)
	beam_particles.emitting = is_casting
	casting_particles.emitting = is_casting


# Controls the emission of particles and extends the Line2D to `cast_to` or the ray's 
# collision point, whichever is closest.
func cast_beam() -> void:
	var cast_point := cast_to

	force_raycast_update()
	collision_particles.emitting = is_colliding()

	if is_colliding():
		cast_point = to_local(get_collision_point())
		collision_particles.global_rotation = get_collision_normal().angle()
		collision_particles.position = cast_point

	fill.points[1] = cast_point
	beam_particles.position = cast_point * 0.5
	beam_particles.process_material.emission_box_extents.x = cast_point.length() * 0.5


func appear() -> void:
	if tween.is_active():
		tween.stop_all()
	tween.interpolate_property(fill, "width", 0, line_width, growth_time * 2)
	tween.start()


func disappear() -> void:
	if tween.is_active():
		tween.stop_all()
	tween.interpolate_property(fill, "width", fill.width, 0, growth_time)
	tween.start()

My Current Code

extends RayCast2D

@onready var tween: Tween

var is_casting := false:
	set = set_is_casting

func _ready():
	set_physics_process(false)
	$Line2D.points[1] = Vector2.ZERO

func _unhandled_input(event : InputEvent) -> void:
	if event is InputEventMouseButton:
		self.is_casting = event.pressed

func _physics_process(_delta: float) -> void:
	var cast_point := target_position
	force_raycast_update()

	if is_colliding():
		cast_point = to_local(get_collision_point())

	$Line2D.points[1] = cast_point

func set_is_casting(cast: bool) -> void:
	is_casting = cast
	set_physics_process(is_casting)

	if is_casting:
		appear()
	else:
		dissapper()

func appear() -> void:
	if is_instance_valid(tween):
		tween.kill()

	tween = create_tween()
	tween.tween_property($Line2D, "width", 0, 10.0)

func dissapper() -> void:
	if is_instance_valid(tween):
		tween.kill()

	tween = create_tween()
	tween.tween_property($Line2D, "width", 10.0, 0)

image

I have implemented like this but it only shows the Line2D but does not hide the Line2D, what to do now, please help !!!1

I don’t see anywhere the tween is restarted.
Try adding a tween.play() to the dissapper() function (this is a spelling mistake)

Yes, that was a spelling mistake :sweat_smile:, my bad !!