Invalid get Index 'is_colliding' (on base: 'null instance')

I have a raycast in my game going from the players camera until a certain point. This is used for detecting if you are shooting a target. I have the following code attached to the target.

func _input(event):
	if Input.is_action_just_pressed("fire"):
		if not doom_pistol.is_playing():
            #plays shooting animation
			doom_pistol.play("shoot")
            #bullet is the raycast
			if bullet.is_colliding and sprite_3d.visible == true:
				print("Hit")
				sprite_3d.visible = false
                # respawn is a timer to make the target visible again
				respawn.start()

When I shoot the target it gives the error
Invalid get Index ‘is_colliding’ (on base: ‘null instance’)

what is wrong?

bullet doesn’t exist, how is it defined?

@onready var bullet = $Head/Camera3D/Bullet

Does this match your Scene tree? Is there any reason Bullet would be deleted mid-game?


this is the scene tree I don’t think bullet could be deleted mid game.

I tried $Player/Head/Camera3D/Bullet
but it didn’t change anything

Looks like the right path, is this script attached to any other object? try print(self)

It is only attached to the target (which is an area 3d)

here is the full Target Script

extends Area3D


@onready var timerI = $"../Instantiate"
const TARGET = preload("res://target.tscn")
@onready var doom_pistol = $"../HUD/Control/DoomPistolAni"
@onready var sprite_3d = $Sprite3D
@onready var respawn = $TargetRespawn
@onready var bullet = $Head/Camera3D/Bullet

func _ready():
	_on_instantiate_timeout(Vector3(0,1,0))

func _on_instantiate_timeout(pos):
	var Instance = TARGET.instantiate()
	Instance.position = pos
	add_child(Instance)

func _input(event):
	if Input.is_action_just_pressed("fire"):
		if not doom_pistol.is_playing():
			doom_pistol.play("shoot")
			if bullet.is_colliding and sprite_3d.visible == true:
				print("Hit")
				sprite_3d.visible = false
				respawn.start()

Ah well you showed me the Player scene, the target has no idea of the Player’s children. $ paths are relative to the script’s children.

1 Like

how do I make the target know about the players children

In this case I think it’s better to have the player know what it’s hitting and use the target’s functions

# in player.gd
func _input(event: InputEvent) -> void:
	if Input.is_action_just_pressed("fire"):
		if not doom_pistol.is_playing():
			doom_pistol.play("shoot")
			if bullet.is_colliding():
				var target = bullet.get_collider()
				target.sprite_3d.visible = false
				target.respawn.start()
1 Like

I tried this first but then when I shoot the instances of the Target it affects the original I’m trying to fix that by putting the script on the target

resources shared between the targets will always be affected as one, unless you set “Local To Scene”, though I don’t see anything inside this snippet that would do such a thing.

Could you post your original sample? What is affecting “the original” that you don’t want?

func _input(event):
	if Input.is_action_just_pressed("pause"):
		if not isPaused:
			Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
			isPaused = !isPaused
		elif isPaused:
			Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
			isPaused = !isPaused
	elif Input.is_action_just_pressed("fire"):
		if not doom_pistol.is_playing():
			doom_pistol.play("shoot")
			if raycast.is_colliding() and sprite_3d.visible == true:
				print("Hit")
				sprite_3d.visible = false
				respawn.start()

code in player
This code works however when I shoot the clone it doesn’t disappear the actual target does

right, sprite_3d is only one target (i assume a target), you need to get the specific object the raycast is colliding with.

if raycast.is_colliding():
	var target = raycast.get_collider()
	target.sprite_3d.visible = false
	target.respawn.start()
1 Like

the target is a area 3d with a sprite3d child. When I do what you said it gives the error

‘invalid get index ‘sprite_3d’ (on base: Area3D(target.gd) )’

if it has a script on it I would recommend making a “hit” function or similar, so you may add more complex logic without target. before everything. I do not know what you want to happen with the target, I figure it would have a sprite_3d variable on it since that’s what you changed before.

# target.gd
func hit() -> void:
    if $Sprite3D.visible:
        $Sprite3D.visible = false
        $Respawn.start()

# player.gd
if raycast.is_colliding():
	var target = raycast.get_collider()
	target.hit()
1 Like

it works on the original target but the instance target runs the error
nonexistent function ‘hit’
so I guess the instance doesn’t have the script attached?

What’s the full error? Notice this one includes “target.gd” so the script is attached here.

Invalid Call. Nonexistent function ‘hit’ in base ‘Area3D’.

Maybe it doesn’t have the script then. Good time to add some filtering I suppose, I recommend a class_name Target for the target.

if raycast.is_colliding():
	var target = raycast.get_collider()
	print(target) # debugging? may help
	if target is Target: # or what ever your class_name is
		target.hit()