Just trying to expand Character controller project from GameDev.tv to save some parameters from player position, current level .
I have manage to save general settings → How to keep those GlobalScene Data persistent? - #2 by artemisia but wonder if I should now build on top of this script or make new autoload saver with export variables for each of those variables and logic.
currently level is managed by : Project Settings → Applications → Run → Main Scene
- there is possible transition via Portal.
Player position is managed by Player itself.
FileSystem architecture :
Started working on it :
It looks like easy task, but main culprit for me is portal() and access to data at right time.
class_name GeneralSaveSystemClass
extends Node
@export var levels : Array[String] = []
@onready var player_spawner: Node3D = $PlayerSpawner
var player
var level_node
var current_level_index: int = 0
var level
var player_position
func _ready() -> void:
player = get_tree().get_first_node_in_group("Player")
level_node = get_tree().get_first_node_in_group("Level")
func update_data() -> void:
player_position = player.global_position
level = level_node.scene_file_path
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("debug_key"):
update_data()
print(level)
print(player_position)
I have tested this, it’s all nice and works in one level. But as soon as you enter another level via portal
func _on_area_3d_body_entered(body: Node3D) -> void:
if body is Player:
UserInterface.change_scene(next_level, player_spawner.global_transform)
it complains :
Invalid access to property or key 'global_position' on a base object of type 'previously freed'.
Small change fixed this behavior, instead of _ready and storing old values now it’s updated on request, so maybe some signal to UI or manual save/load buttons to make it work?
edit : added exact data type, check for index
class_name GeneralSaveSystemClass
extends Node
@export var levels : Array[String] = []
@onready var player_spawner: Node3D = $PlayerSpawner
var player : CharacterBody3D
var level_node : Node3D
var current_level_index: int = 0
var level : String
var player_position : Vector3
func find_level_in_array() -> void:
for level_index in range(levels.size()):
if levels[level_index] == level:
current_level_index = level_index
break
func get_tree_reference() -> void:
player = get_tree().get_first_node_in_group("Player")
level_node = get_tree().get_first_node_in_group("Level")
func update_data() -> void:
get_tree_reference()
player_position = player.global_position
level = level_node.scene_file_path
find_level_in_array()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("debug_key"):
update_data()
print(current_level_index, " ", level, " ", player_position)
0 res://Levels/DebugLevel.tscn (10.54292, 0.925232, 17.60353)
1 res://Levels/TestLevel.tscn (10.00271, 0.925785, 12.79769)
1 Like