I am very new to Godot, but have some experience in programming in Python. I am making a 3D simple movement game to learn about the engine, and I want to add checkpoints throughout the level. I followed this tutorial (https://youtu.be/AEdEUeK_g4A) to get most of the code for the checkpoints, but it didn't work. I have spent a few more hours researching and changing the code, and now I am nearly there, I just can't figure out how to get the checkpoint to know where its position is.
I have moved things around from the original tutorial, and now the checkpoint script (extends Area3D) is autoloaded, so I can access it from other scripts. I have tested (with the print function) and it knows when the area has been entered, but when I press to load checkpoint, it takes me back to 0,0,0. I have set the initial check_point_pos vector3 to be 10,10,10, and it brings me there. So it seems the issue is that the vector3 is not being updated. What do I need to add to make the vector3 update with the correct position for each checkpoint? Ive tried a few things, but nothing is working so far.
extends Area3D
var check_point_pos = Vector3.ZERO
func save_check_point(pos_x, pos_y, pos_z):
check_point_pos.x = pos_x
check_point_pos.y = pos_y
check_point_pos.z = pos_z
func _on_area_entered(_body):
print("checkpoint")
save_check_point(self.position.x, self.position.y, self.position.z)
if Input.is_action_pressed("load_checkpoint"):
set_position(checkpt.check_point_pos)
[enter image description here](https://i.sstatic.net/an3cO.png)
The basic check point system needs two parts.
Area3D
.This is the part of your code that stores the last reached check point (and hence what would be in an Autoload):
extends Area3D
var check_point_pos = Vector3.ZERO
func save_check_point(pos_x, pos_y, pos_z):
check_point_pos.x = pos_x
check_point_pos.y = pos_y
check_point_pos.z = pos_z
These are the modifications I will do:
Area3D
, it fact it does not need a position in the world. So I'll change it Node
.save_check_point
.Variant
.This is the result (which, again, is what you will make into an Autoload):
extends Node
var check_point_pos:Vector3
Make sure you give it a name when making it an Autoload. I believe you are using the name checkpt
, so I'll use that for this answer.
And the Area3D
you place in the world, has this part of the code:
extends Area3D
func _on_area_entered(_body):
print("checkpoint")
save_check_point(self.position.x, self.position.y, self.position.z)
These are the modifications I'll make:
save_check_point
, we will set the variable directly.position
because that is relative to the parent Node3D
. Instead we will use global_position
which is relative to the game world origin.This is the result:
class_name CheckPoint
extends Area3D
func _ready() -> void:
if not area_entered.is_connected(_on_area_entered):
area_entered.connect(_on_area_entered)
func _on_area_entered(_area:Area3D) -> void:
print("checkpoint")
checkpt.check_point_pos = global_position
I would have expected that you would use body_entered
instead of area_entered
. Double check that area_entered
is what you want. If you actually want body_entered
the code would be like this:
class_name CheckPoint
extends Area3D
func _ready() -> void:
if not body_entered.is_connected(_on_body_entered):
body_entered.connect(_on_body_entered)
func _on_body_entered(_body:Node3D) -> void:
print("checkpoint")
checkpt.check_point_pos = global_position
I recommend to change the collision mask so that only the player character will trigger it, and nothing else.
Of course, recalling the check point looks like this (in your player character):
global_position = checkpt.check_point_pos
I also want to note that using an static var
is a viable alternative, this way you do not need an Autoload
and everything will be in a single script:
class_name CheckPoint
extends Area3D
static var check_point_pos:Vector3
func _ready() -> void:
if not area_entered.is_connected(_on_area_entered):
area_entered.connect(_on_area_entered)
func _on_area_entered(_area:Area3D) -> void:
print("checkpoint")
CheckPoint.check_point_pos = global_position
This time recalling the check point looks like this (in your player character):
global_position = CheckPoint.check_point_pos