Variables Previously not Null now come out as NULL

Godot Version

godot 4.5.1

Question

Hey I was working on my first test project and tried to mess with some code I have removed involving Ray Casting and all of my code has broken as the exported variables have decided to become for no reason I would appreciate your assistance. Error given is “ Invalid operands ‘Nil’ and ‘float’ in operator ‘*’ ” and is procking on line 54. aka the line with the code :

velocity.x = lerp(velocity.x, 0.0, accel * delta)

Whole code:

extends CharacterBody3D



@export var speed = 8.0
@export var crouch_speed = 4.0
@export var accel = 16.0
@export var jump = 8.0
@export var crouch_height = 2.4
@export var crouch_transition = 8.0
@export var sensitivity = 0.2
@export var min_angle = -80
@export var max_angle = 90

@onready var POV = $POV
@onready var collision_shape = $CollisionShape3D
#@onready var top_cast = $TopCast

var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
var look_rot : Vector2
var con_look_rot : Vector2
var stand_height : float
@export var controller_deadzone : float = 0.15
@export var controller_response_curve : float = 1.5  

func _ready():
	stand_height = collision_shape.shape.height
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)


func _physics_process(delta):
	
	var _space_state = get_world_3d().direct_space_state
	
	var move_speed = speed
	
	if not is_on_floor():
		velocity.y -= gravity * delta
	else:
		if Input.is_action_just_pressed("jump"):
			velocity.y = jump
		#elif Input.is_action_pressed("crouch") or top_cast.is_colliding():
			move_speed = crouch_speed
			crouch(delta)
		else:
			crouch(delta, true)

	var input_dir = Input.get_vector("left", "right", "forward", "back")
	var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	if direction:
		velocity.x = lerp(velocity.x, direction.x * move_speed, accel * delta)
		velocity.z = lerp(velocity.z, direction.z * move_speed, accel * delta)
	else:
		velocity.x = lerp(velocity.x, 0.0, accel * delta)
		velocity.z = lerp(velocity.z, 0.0, accel * delta)

	move_and_slide()
	
	
	
	# Controller input processing
	# Get right stick input values
	var right_y = Input.get_joy_axis(0, JOY_AXIS_RIGHT_X)
	var right_x = Input.get_joy_axis(0, JOY_AXIS_RIGHT_Y)
	
	# Apply deadzone
	if abs(right_x) < controller_deadzone:
		right_x = 0.0
	if abs(right_y) < controller_deadzone:
		right_y = 0.0
	
	# Apply response curve for better control feel
	right_x = sign(right_x) * pow(abs(right_x), controller_response_curve)
	right_y = sign(right_y) * pow(abs(right_y), controller_response_curve)
	
	# Apply rotation based on controller input
	con_look_rot.x += -right_x * sensitivity * 30
	con_look_rot.y += -right_y * sensitivity * 30
		
		

	con_look_rot.x = clamp(con_look_rot.x, min_angle, max_angle)
	
	var plat_rot = get_platform_angular_velocity()
	con_look_rot.y += rad_to_deg(plat_rot.y * delta)
	look_rot.y += rad_to_deg(plat_rot.y * delta)
	POV.rotation_degrees.x = look_rot.x + con_look_rot.x
	rotation_degrees.y = look_rot.y + con_look_rot.y



func _input(event):
	
	if event is InputEventMouseMotion:
		look_rot.y -= (event.relative.x * sensitivity)
		look_rot.x -= (event.relative.y * sensitivity)
		look_rot.x = clamp(look_rot.x, min_angle, max_angle)
		
	
	

func crouch(delta : float, reverse = false):
	var target_height : float = crouch_height if not reverse else stand_height
	
	#collision_shape.shape.height = lerp(collision_shape.shape.height, target_height, crouch_transition * delta)
	#collision_shape.position.y = lerp(collision_shape.position.y, target_height * 0.5, crouch_transition * delta)
	POV.position.y = lerp(POV.position.y, target_height - 1, crouch_transition * delta)

You’ve marked all those variables as @export variables so their value is set by the node instance in the scene editor where this code is applied to a node. The code by itself doesn’t tell the whole story.

Two solutions:

If you don’t want those variables altered for different instances of this kind of node, you can remove the @export bit from those lines.

If you do want different nodes that use this code to have different values for those variables, check where the code is assigned to nodes and scenes and make sure all of the instances have some sensible value assigned for every variable.

1 Like

What else would you need? Current structure is

Player (character 3D Node)

>Pivot (3D Node)

>>Mesh Instance

>Collision

>POV (3D Node)

>>Camera

>>>Raycast node

How did you determine they are null?

  1. Format your code by pressing Ctrl + E here on the forum and pasting your code into it.
  2. A screen shot of your scene tree. A text representation misses a LOT of nuance that you as a new Godot user might miss that we would not.
  3. A screen shot of the Inspector of your CharacterBody3D object showing all those exported variables.

Based on what I’m seeing, you are somehow setting all those variables to null. I’d recommend also posting your code that is adding your Player object to the world, as well as a screen shot of the actual level/main/whatever game structure you have that the Player is in. And while we are at it, tell us how you are testing this (what buttons are you pressing to start the scene), and what you are seeing - not just your conclusions. (What @normalized asked.)

I believe I have fixed it sorry was late when I posted so was asleep. They only let me put in 1 screenshot since I am still new.

I am getting an error that said that they were coming out null and when I hovered over the variables then it said they were coming out null.

We’ll need to see the exact error message and line of code that caused it.

I have fixed it to give more info.

I have fixed it. I just had to remove the RayCast Node. If you have an answer on why this worked I would love to hear it. But I will for now claim this as the solution. (even though when I add a new raycast node it isn’t broken this is what worked for me.)