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()