0 votes

I was following a tutorial on Youtube about making a 3d top down shooter. Whenever I try to click to shoot my game crashes and I get the error

Attempt to call function 'shoot' in base 'null instance' on a null instance.

this is the code I have. this isn't my own original code.

extends KinematicBody

onready var gun_controller = $guncontroller

var speed = 8
var velocity = Vector3()

func _process(delta):

#movement
velocity = Vector3()

if Input. is_action_pressed("ui_right"):
    velocity.x -= 1
if Input. is_action_pressed("ui_left"):
    velocity.x += 1
if Input. is_action_pressed("ui_up"):
    velocity.z += 1
if Input. is_action_pressed("ui_down"):
    velocity.z -= 1

velocity = velocity.normalized() * speed

move_and_slide(velocity)

if Input.is_action_pressed("primary_action"):
    gun_controller.shoot()

its saying the error is from the last line of code above. just incase it is needed also Im putting the code for the gun controller and gun itself.

gun controller code

extends Node

export(PackedScene) var StartingWeapon
var hand :Position3D
var equipped_weapon : Spatial

func ready():
hand = get
parent().findnode("hand")
if StartingWeapon:
equip
weapon(StartingWeapon)

func equipweapon(weapontoequip):
if equipped
weapon:
print("Deleting current weapon")
equippedweapon. queuefree()
else:
print("No weapon equipped")
equippedweapon = weapontoequip. instance()
hand.add
child(equipped_weapon)

func shoot():
if equippedweapon:
equipped
weapon.shoot()

Gun Code

extends Spatial

export(PackedScene) var bullet

onready var roftimer = $Timer
var can
shoot = true

export var muzzlespeed = 30
export var millis
between_shots = 100

func ready():
rof
timer.waittime = millisbetween_shots / 1000.0

func _process(delta):
pass

func shoot():
if canshoot:
var new
bullet = bullet.instance()
newbullet.globaltransform = $muzzle.globaltransform
new
bullet.speed = muzzlespeed
var scene
root = gettree().getroot().getchildren()[0]
scene
root.addchild(newbullet)
print("pew")
canshoot = false
rof
timer.start()

Lastly Im posting the line to the tutorial I was using so if anyone needs an better idea of how it works

Tutorial video

Godot version v3.3
in Engine by (12 points)

Umm... Sorry, this is a bit confusing for me. Mind sharing the tutorial? Or even sharing the project via a google drive link would help a lot.

I do notice that your function 'shoot()' is not in the same script as your KinematicBody2d. For you KinematicBody2D script to access that particular function, you have to have them in the same script. (I'm not sure if this is the problem though. Like I said before, having access to the project itself would really help a lot)

Assuming you're not sure how to access functions from different scripts, you just need to get the node.

If both your nodes' have the same parent, all you need to do is: getparent().getnode(node name).shoot()

If your guncontroller node is a child under the KinematicBody2D (meaning KinematicBody = parent and guncontroller = child), then you can just
getnode(node name).shoot()
or
get
child(0) *based on index number. In gdscript, the first number is 0, second number is 1, and so on.

If your guncontroller node is not under the same parent, you can use an absolute path.
get
node("../Node2D/gun_controller").shoot()
absolute paths can be used anytime, though I find them finnicky and bothersome. I would only use them if I have to, as I rearrange nodes all the time. The '..' before the path is something you should put first everytime you want to use an absolute path.

And there we go. Sorry for the long (and extremely confusing) comment. If you want, you can add a link to a google drive file, and I can take a closer look.

1 Answer

0 votes

I'm not going to bother reading all of that, but when you get an error like that, it means the the value of gun_controller is null. This means that gun_controller does not actually refer to the node you want it to. You need to check your spelling, capitalization, and node tree in order to get the correct path to the node you want.

by (7,452 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.