Fixed Turret incorrectly using references to freed objects

This commit is contained in:
Jakob Feldmann 2022-06-11 15:49:35 +02:00
parent bd6103a766
commit 5359d5dd75
7 changed files with 29 additions and 32 deletions

3
.gitignore vendored
View File

@ -22,4 +22,5 @@ export_presets.cfg
# Mono-specific ignores # Mono-specific ignores
.mono/ .mono/
data_*/ data_*/
.vscode/launch.json

2
.vscode/launch.json vendored
View File

@ -8,7 +8,7 @@
"name": "GDScript Godot", "name": "GDScript Godot",
"type": "godot", "type": "godot",
"request": "launch", "request": "launch",
"project": "C:\\Users\\jakob\\Documents\\Godot\\Wumper", "project": "C:\\Users\\Jakob F\\Documents\\Godot\\Wumper",
"port": 6007, "port": 6007,
"address": "127.0.0.1", "address": "127.0.0.1",
"launch_game_instance": true, "launch_game_instance": true,

View File

@ -3,7 +3,7 @@ extends KinematicBody2D
# Declare member variables here. Examples: # Declare member variables here. Examples:
# var a: int = 2 # var a: int = 2
# var b: String = "text" # var b: String = "text"
onready var sightline: RayCast2D = $RayCast2D onready var sightline: RayCast2D = $Sightline
onready var turret_state_machine = $TurretStateMachine onready var turret_state_machine = $TurretStateMachine
onready var lock_on_timer = $LockOnTimer onready var lock_on_timer = $LockOnTimer
onready var sight_lost_timer = $SightLostTimer onready var sight_lost_timer = $SightLostTimer
@ -19,8 +19,8 @@ onready var original_rotation = rotation
onready var rotation_speed_divider = 80 onready var rotation_speed_divider = 80
# TODO causes oscilation # TODO causes oscilation
onready var min_rotation_speed = deg2rad(0.3) onready var min_rotation_speed = deg2rad(0.3)
# TODO Bug when dying in the wrong state, missing prey instance
var prey = null var prey_ref = weakref(null)
# Ray that goes from the turret to the target # Ray that goes from the turret to the target
var target_ray var target_ray
@ -29,13 +29,18 @@ var target_ray
func _ready() -> void: func _ready() -> void:
$AnimationPlayer.play("Turret Rotation") $AnimationPlayer.play("Turret Rotation")
func prey():
return prey_ref.get_ref()
func searching(): func searching():
$AnimationPlayer.play("Turret Rotation")
if sightline.is_colliding(): if sightline.is_colliding():
# The collider returns not the area or body it hit, but the parent of them # The collider returns not the area or body it hit, but the parent of them
var collider = sightline.get_collider() var collider = sightline.get_collider()
if collider.is_in_group("player"): if collider.is_in_group("player"):
prey = collider print_debug(is_tracking_prey())
prey_ref = weakref(collider)
print_debug(is_tracking_prey())
# TODO should this stand still? # TODO should this stand still?
@ -44,7 +49,8 @@ func start_locking():
add_child(target_ray) add_child(target_ray)
target_ray.enabled = true target_ray.enabled = true
target_ray.exclude_parent = true target_ray.exclude_parent = true
target_ray.set_cast_to(to_local(prey.position)) if(prey() != null):
target_ray.set_cast_to(to_local(prey().position))
$AnimationPlayer.stop(false) $AnimationPlayer.stop(false)
lock_on_timer.start() lock_on_timer.start()
@ -53,6 +59,8 @@ func start_locking():
func is_locked_on_target(): func is_locked_on_target():
return lock_on_timer.is_stopped() return lock_on_timer.is_stopped()
func is_tracking_prey():
return true if(prey() != null) else false
# TODO simplify/split this method # TODO simplify/split this method
func shooting(): func shooting():
@ -69,22 +77,23 @@ func shooting():
) )
if sightline.is_colliding(): if sightline.is_colliding():
# The collider returns not the area or body it hit, but the parent of them # The collider returns not the area or body it hit, but the parent of them
# TODO Sight could be a cone instead of a ray
var collider = sightline.get_collider() var collider = sightline.get_collider()
if collider.is_in_group("player"): if collider.is_in_group("player"):
sight_lost_timer.stop() sight_lost_timer.stop()
target_ray.cast_to = to_local(prey.position) target_ray.cast_to = to_local(prey().position)
else: else:
if ( if (
sight_lost_timer.get_time_left() < 0.1 sight_lost_timer.get_time_left() < 0.1
&& sight_lost_timer.get_time_left() > 0 && sight_lost_timer.get_time_left() > 0
): ):
prey = null prey_ref = weakref(null)
target_ray.queue_free() target_ray.queue_free()
return return
if sight_lost_timer.is_stopped(): if sight_lost_timer.is_stopped():
sight_lost_timer.start() sight_lost_timer.start()
else: elif(prey() != null):
target_ray.cast_to = to_local(prey.position) target_ray.cast_to = to_local(prey().position)
spawn_projectile() spawn_projectile()

View File

@ -39,7 +39,7 @@ position = Vector2( 0, -0.103346 )
scale = Vector2( 0.310271, 1.02855 ) scale = Vector2( 0.310271, 1.02855 )
shape = SubResource( 1 ) shape = SubResource( 1 )
[node name="RayCast2D" type="RayCast2D" parent="."] [node name="Sightline" type="RayCast2D" parent="."]
enabled = true enabled = true
cast_to = Vector2( 0, 1e+07 ) cast_to = Vector2( 0, 1e+07 )
collision_mask = 59 collision_mask = 59

View File

@ -1,14 +0,0 @@
extends RayCast2D
# Declare member variables here. Examples:
# var a: int = 2
# var b: String = "text"
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:

View File

@ -52,10 +52,11 @@ func _get_transition(_delta):
# TODO why only this way? # TODO why only this way?
parent.get_node("StateLabel").text = self.state parent.get_node("StateLabel").text = self.state
var new_state var new_state
if parent.prey != null && self.state == "searching": if parent.is_tracking_prey() && self.state == "searching":
parent.start_locking() parent.start_locking()
new_state = "locking" new_state = "locking"
if parent.prey == null && self.state == "shooting": # TODO Helper function with null check and reference check
if !parent.is_tracking_prey() && self.state == "shooting":
new_state = "searching" new_state = "searching"
if self.state == "locking" && parent.is_locked_on_target(): if self.state == "locking" && parent.is_locked_on_target():
new_state = "shooting" new_state = "shooting"

View File

@ -5,8 +5,8 @@
[ext_resource path="res://src/Contraptions/Platform/Spring.tscn" type="PackedScene" id=3] [ext_resource path="res://src/Contraptions/Platform/Spring.tscn" type="PackedScene" id=3]
[ext_resource path="res://src/Environment/Background.tscn" type="PackedScene" id=4] [ext_resource path="res://src/Environment/Background.tscn" type="PackedScene" id=4]
[ext_resource path="res://src/Contraptions/Platform/Track.tscn" type="PackedScene" id=5] [ext_resource path="res://src/Contraptions/Platform/Track.tscn" type="PackedScene" id=5]
[ext_resource path="res://src/Actors/Enemies/Machines/Turret.tscn" type="PackedScene" id=6]
[ext_resource path="res://src/UserInterface/Buttons/UI.tscn" type="PackedScene" id=7] [ext_resource path="res://src/UserInterface/Buttons/UI.tscn" type="PackedScene" id=7]
[ext_resource path="res://src/Actors/Enemies/Machines/Turret.tscn" type="PackedScene" id=8]
[sub_resource type="NavigationPolygon" id=1] [sub_resource type="NavigationPolygon" id=1]
vertices = PoolVector2Array( 16, 16, 0, 16, 0, 0, 16, 0 ) vertices = PoolVector2Array( 16, 16, 0, 16, 0, 0, 16, 0 )
@ -78,9 +78,9 @@ scale = Vector2( 2.83999, 0.56 )
[node name="KinematicBody2D" parent="Track" index="0"] [node name="KinematicBody2D" parent="Track" index="0"]
position = Vector2( 8, 0 ) position = Vector2( 8, 0 )
[node name="Turret" parent="." instance=ExtResource( 8 )] [node name="Turret" parent="." instance=ExtResource( 6 )]
position = Vector2( 479.52, 464 ) position = Vector2( 479, 520 )
scale = Vector2( 0.5, 0.5 ) scale = Vector2( 0.4, 0.4 )
[editable path="Spring4"] [editable path="Spring4"]
[editable path="Track"] [editable path="Track"]