Getting error: Invalid access to property or key 'speed' on a base object of type 'Nil'

Godot Version

4.3

Question

Hey everyone, I am new to using godot and I am trying to build good habits by using resources for a hunting game. I seem to be having an issue where my movement script cannot pull the var speed from its referenced resource.

Here is the custom resource:

extends Resource
class_name AnimalStats

@export var health : int = 100
@export var speed : int = 100
@export var fall_acceleration: int = 75

And then the code on the entity I want to control is:

extends CharacterBody3D

@export var stats: AnimalStats

var target_velocity = Vector3.ZERO

func _physics_process(delta: float) -> void:
	var direction = Vector3.ZERO
	
	if Input.is_action_pressed("move_left"):
		direction.x += 1
	if Input.is_action_pressed("move_right"):
		direction.x -= 1
	if Input.is_action_pressed("move_forward"):
		direction.z += 1
	if Input.is_action_pressed("move_back"):
		direction.z -= 1
	
	if direction != Vector3.ZERO:
		direction = direction.normalized()
		$Pivot.basis = Basis.looking_at(direction)
	
	#ground velocity
	target_velocity.x = direction.x * stats.speed
	target_velocity.z = direction.z * stats.speed
	
	#vertical velocity aka Gravity
	if not is_on_floor(): 
		target_velocity.y = target_velocity.y - (stats.fall_acceleration * delta)
	
	#moving character
	velocity = target_velocity
	move_and_slide()

The error I get is Invalid access to property or key ā€˜speedā€™ on a base object of type ā€˜Nilā€™ and it appears on the line that says:

target_velocity.x = direction.x * stats.speed

The custom resource is being refernced in the inspector, but it does nothing when I try to play, just a grey screen. Anything Iā€™m missing? Not sure if it is needed but on the Main for the scene I load the resource too:

extends Node3D

func _ready() -> void:
	var loaded_resource = load("res://Animals/Deer/deer_stats.tres")

Iā€™m not confident enough to give you a true solution, but ā€œType ā€˜Nilā€™ā€ makes me think that stats isnā€™t properly loading the AnimalStats stuff. Iā€™d take a look at your @export var stats: AnimalStats line and make sure thatā€™s working the way you expect.

If there is a AnimalStats inside the inspectorā€™s stats property, then it should work. If you use this entity scene in another scene, then check itā€™s properties in the other scene too. Maybe re-save the scene and try again?

This loading should have no bearing on the entity scenes youā€™ve created.

I replaced the AnimalStats reference with just putting the varibles in directly, and then it seemed to work. Iā€™m not sure why its different to use a resource, but I would much rather use resurces having to do this for every animal.

I have no idea how @export works, but I do know how I got my Resource class working.

Resource file:

extends Resource

class_name Anim
var name
var time

func _init(animationName:String = "", animationTime:float = 0.0):
	self.name = animationName
	self.time = animationTime # time in seconds

File referencing Anim:

var myAnim = Anim.new("stand_idle_left", 1)

#another example: a list of Anim objects
var level_1 = [Anim.new(STAND, 1), #STAND and SIT are constants
				Anim.new(STAND, 2), 
				Anim.new(STAND, 2), 
				Anim.new(STAND, 2.5), 
				Anim.new(STAND, 3), 
				Anim.new(STAND, 3), 
				Anim.new(STAND, 3), 
				Anim.new(STAND, 3), 
				Anim.new(SIT, 1), 
				Anim.new(SIT, 1), 
				Anim.new(SIT, 1.5), 
				Anim.new(SIT, 3), 
				Anim.new(SIT, 4)]

Here, myAnim is an object of class Anim. Nothing fancy there. Since everything in the class is public (bad OOP practice but I didnā€™t care enough to change it), you can just change the member variables directly once the object is instantiated.

If @export keeps being persnickety, you can just do it like this instead.

Unfortunately removing @export doesnā€™t fix it. My undersatnding is that export just lets you adjust the values in the inspector as needed. I see in your example you do not try to refernce myAnim.time or myAnim.name. How would you go about doing that? I beleive thatā€™s the issue Iā€™m having in that ā€˜statsā€™ contains the var ā€˜speedā€™ and a value, but I canā€™t access it by reference for some reason.

1 Like

Ah yes that was my issue. The original instace did not refernce the resouce in the inspector. Once I made those the same, the instance in my Main worked. Thanks!

1 Like