Large script: How to split? Accessing via .new()?

Hi,

I’m currently trying to make a very large script for the player a little more modular and move it into sub-scripts. However, I’m not really succeeding. I keep finding examples online that use “new()”, but that doesn’t work.

Here is my code (just a compressed example):

Player_Health.gd

extends Node

@onready var maxHealth 			= 10
@onready var currentHealth 		= maxHealth

Player.gd

func _ready() -> void:
	player_health = preload("res://scripts/characters/player/player_health.gd").new()
    # This returns only NULL
	print(player_health.maxHealth)

But it seems, the “newed” object is just NULL.

Where did I forget something?

Jeff

When you new() something it doesn’t get added to the scene tree, so @onready never goes off.

If you add func _init() → void: and set the variables inside PlayerHealth.gd it should work out.

You can also add parameters to init to manage new variables “easier”, like if you need the health object to initialize a “half_health” variable, you can add a parameter func _init(maxhp, halfhp) and the editor will give you an error if you call .new(one_param), because you now need two parameters :+1: I hope this last paragraph made sense :melting_face:

2 Likes

Thank you! Yes! Adding an _init did the trick!

PlayerHealth.gd

extends Node


var maxHealth		
var currentHealth


func _init(setMaxHealth) -> void:
	maxHealth 			= setMaxHealth
	currentHealth 		= maxHealth
	

Player.gd

func _ready() -> void:

	player_health = preload("res://scripts/characters/player/player_health.gd").new(10) # Set max health to 10
	print(player_health.maxHealth)
1 Like

No problem! As a bonus, you can also add a class name to PlayerHealth.gd anywhere towards the top of the script. I like to put it before extends Node. class_name HealthObject

Then instead of preload (path/to/.gd).new() you can write HealthObject.new()

3 Likes

Perfect! Thank you!

1 Like