Interactable error with "callable" function

Godot Version

4.5

Question

Hello! :smiley:

Ive been at this for about a half hour and still cant figure out exactly whats wrong.

I have an error message “Invalid access to property or key ‘interact’ on a base object of type ‘Callable’.” while trying to make an interactable object, it doesnt say whch script or line is the problem

player script:

extends CharacterBody3D

@onready var raycast = $Camera3D/RayCast3D
const SPEED = 5.0
const JUMP_VELOCITY = 4.5
@onready var target = raycast.get_collider


func _physics_process(delta: float) -> void:
	_update_camera(delta)
	if raycast.is_colliding():
		print("target")
		$CanvasLayer/BoxContainer/Label.show()
		print("interactable")
	if Input.is_action_just_pressed:
		target.interact
		

	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta



	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var input_dir := Input.get_vector("Left", "Right", "Up", "Down")
	var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	if direction:
		velocity.x = direction.x * SPEED
		velocity.z = direction.z * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)
		velocity.z = move_toward(velocity.z, 0, SPEED)

	move_and_slide()

func _input(event):
	if event.is_action_pressed("Exit"):
		get_tree().quit()

func _ready():
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

var _mouse_input : bool = false
var _mouse_rotation : Vector3
var _rotation_input : float
var _tilt_input : float
var _player_rotation : Vector3
var _camera_rotation : Vector3


func _unhandled_input(event):
	_mouse_input = event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED
	if _mouse_input :
		_rotation_input = -event.relative.x * MOUSE_SENSITIVITY
		_tilt_input = -event.relative.y * MOUSE_SENSITIVITY
		print(Vector2(_rotation_input,_tilt_input))

@export var TILT_LOWER_LIMIT := deg_to_rad(-90.0)
@export var TILT_UPPER_LIMIT := deg_to_rad(90.0)
@export var CAMERA_CONTROLLER : Camera3D
@export var MOUSE_SENSITIVITY : float = 0.5 




func _update_camera(delta):
	
	_mouse_rotation.x += _tilt_input * delta
	_mouse_rotation.x = clamp(_mouse_rotation.x, TILT_LOWER_LIMIT, TILT_UPPER_LIMIT)
	_mouse_rotation.y += _rotation_input * delta
	
	_player_rotation = Vector3(0.0,_mouse_rotation.y,0.0)
	_camera_rotation = Vector3(_mouse_rotation.x,0.0,0.0)
	
	CAMERA_CONTROLLER.transform.basis = Basis.from_euler(_camera_rotation)
	CAMERA_CONTROLLER.rotation.z = 0.0
	
	global_transform.basis = Basis.from_euler(_player_rotation)
	
	_rotation_input = 0.0
	_tilt_input = 0.0

object script:

extends Node3D

func interact():
print(“interacted”)
queue_free()

Did i do something wrong?

The error is talking about this line:

# ...
		#print("interactable")
	#if Input.is_action_just_pressed:
		target.interact

To fix it, you just need to add parentheses to raycast.get_collider:

@onready var target = raycast.get_collider()

Without them Godot thinks you’re trying to access the function as an object when you’re actually trying to call it. (In the parentheses you would put any function arguments, get_collider just happens to accept none)

Also, I assume target.interact is a function you want to call? In that case, you will want to put parentheses there as well.

target.interact()
As a general tip

I recommend using static typing for everything:

# object script

class_name Interactable # or a more specific class name
extends Node3D

# ...
# player script

class_name Player
extends CharacterBody3D

@onready var raycast: RayCast3D = $Camera3D/RayCast3D
const SPEED: float = 5.0
const JUMP_VELOCITY: float = 4.5
@onready var target: Interactable = raycast.get_collider()

With static typing debugging becomes a lot easier, for example in your case the error would have pointed directly to @onready var target: Interactable = raycast.get_collider instead of some later consequence of the mistake.

1 Like