Godot Version
v4.6.stable.official
Question
Git repo: GitHub - DaMushKen/PROJECT-WOUND · GitHub
In my WeaponsManager (res://scripts/weapons/WeaponsManager.gd) whenever I try to shoot I get an error saying: Trying to assign a value of type ‘Nil’ to a variable of type ‘Vector3’ (func shoot(), line 138).
Please help me I have been trying to fix this for so long. If there isn’t a fix to the way I am currently doing it please atleast tell me another way to do it. Thanks
I’d really rather not parse your entire repo for a problem in one script, you should put the script (or where you think the problem is in the script) in your post instead of just a repo link.
1 Like
Here is the script. The function I am talking about are shoot() and _get_3d_mouse_position()
class_name WeaponManager
extends Node3D
signal WeaponChanged
signal UpdateAmmo
signal UpdateWeaponStack
var current_weapon_debug : String
var current_weapon_stack_debug : String
var current_weapon_ammo_debug : String
@export var ANIM_PLAYER : AnimationPlayer
@onready var BULLET_POINT : Marker3D = get_node("WeaponRigs/BulletPoint")
const BULLET : PackedScene = preload("res://scenes/bullet/bullet.tscn")
var CURRENT_WEAPON
var WEAPON_STACK = [] # An array of weapons currently held by the player
var WEAPON_INDICATOR = 0
var NEXT_WEAPON : String
var WEAPON_LIST = {}
@export var WEAPON_RESOURCES: Array[WeaponResource]
@export var START_WEAPONS: Array[String]
func _ready() -> void:
Global.weapon_manager = self
Initialize(START_WEAPONS) # Enter the state machine
func _physics_process(delta: float) -> void:
Global.debug.add_property("Current Weapon", current_weapon_debug, 6)
Global.debug.add_property("Ammo", current_weapon_ammo_debug, 7)
Global.debug.add_property("Weapon Stack", current_weapon_stack_debug, 8)
func _input(event: InputEvent) -> void:
if event.is_action_released("SCROLL_UP"):
WEAPON_INDICATOR = min(WEAPON_INDICATOR +1, WEAPON_STACK.size() -1)
exit(WEAPON_STACK[WEAPON_INDICATOR])
if event.is_action_released("SCROLL_DOWN"):
WEAPON_INDICATOR = max(WEAPON_INDICATOR -1, 0)
exit(WEAPON_STACK[WEAPON_INDICATOR])
if event.is_action_pressed("SHOOT"):
shoot()
if event.is_action_pressed("RELOAD"):
reload()
func Initialize(start_weapons: Array):
# Create a dictionary
for weapon in WEAPON_RESOURCES:
WEAPON_LIST[weapon.WEAPON_NAME] = weapon
for i in start_weapons:
WEAPON_STACK.push_back(i) #Add start weapons
CURRENT_WEAPON = WEAPON_LIST[WEAPON_STACK[0]]
emit_signal("UpdateWeaponStack", WEAPON_STACK)
enter()
func enter():
ANIM_PLAYER.queue(CURRENT_WEAPON.ACTIVATE_ANIM)
emit_signal("WeaponChanged", CURRENT_WEAPON.WEAPON_NAME)
emit_signal("UpdateAmmo", [CURRENT_WEAPON.CURRENT_AMMO, CURRENT_WEAPON.RELOAD_AMMO])
func exit(next_weapon : String):
if next_weapon != CURRENT_WEAPON.WEAPON_NAME:
if ANIM_PLAYER.get_current_animation() != CURRENT_WEAPON.DEACTIVATE_ANIM:
ANIM_PLAYER.play(CURRENT_WEAPON.DEACTIVATE_ANIM)
NEXT_WEAPON = next_weapon
func Change_Weapon(weapon_name : String):
CURRENT_WEAPON = WEAPON_LIST[weapon_name]
NEXT_WEAPON = ""
enter()
func _on_weapon_anims_animation_finished(anim_name: StringName) -> void:
if anim_name == CURRENT_WEAPON.DEACTIVATE_ANIM:
Change_Weapon(NEXT_WEAPON)
if anim_name == CURRENT_WEAPON.SHOOT_ANIM and CURRENT_WEAPON.isAutoFire == true:
if Input.is_action_pressed("SHOOT"):
shoot()
func shoot():
if CURRENT_WEAPON.CURRENT_AMMO != 0 and !ANIM_PLAYER.is_playing():
ANIM_PLAYER.play(CURRENT_WEAPON.SHOOT_ANIM)
CURRENT_WEAPON.CURRENT_AMMO -= 1
emit_signal("UpdateAmmo", [CURRENT_WEAPON.CURRENT_AMMO, CURRENT_WEAPON.RELOAD_AMMO])
var bulletNode : Node = BULLET.instantiate()
var mouse3D : Vector3 = _get_3d_mouse_position()
if not mouse3D: return
#bulletNode.direction = -get_viewport().get_camera_3d().global_transform.basis.z.normalized()
bulletNode.direction = global_position.direction_to(mouse3D)
get_tree().root.add_child(bulletNode)
bulletNode.global_position = BULLET_POINT.global_position
else:
reload()
func _get_3d_mouse_position():
var mouse2DPosition : Vector2 = get_viewport().get_mouse_position()
var currentCamera : Camera3D = get_viewport().get_camera_3d()
var params : PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
params.from = currentCamera.project_ray_origin(mouse2DPosition)
params.to = currentCamera.project_position(mouse2DPosition, 100)
var worldspace : PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
var intersect : Dictionary = worldspace.intersect_ray(params)
if not intersect: return
var intersectPosition = intersect.position
intersectPosition.y = global_position.y
return intersectPosition
func reload():
if CURRENT_WEAPON.CURRENT_AMMO == CURRENT_WEAPON.MAGAZINE:
return
elif !ANIM_PLAYER.is_playing() and CURRENT_WEAPON.RELOAD_AMMO != 0:
ANIM_PLAYER.play(CURRENT_WEAPON.RELOAD_ANIM)
var RELOAD_AMOUNT = min(CURRENT_WEAPON.MAGAZINE - CURRENT_WEAPON.CURRENT_AMMO, CURRENT_WEAPON.MAGAZINE, CURRENT_WEAPON.RELOAD_AMMO)
CURRENT_WEAPON.CURRENT_AMMO += RELOAD_AMOUNT
CURRENT_WEAPON.RELOAD_AMMO -= RELOAD_AMOUNT
emit_signal("UpdateAmmo", [CURRENT_WEAPON.CURRENT_AMMO, CURRENT_WEAPON.RELOAD_AMMO])
func _on_update_ammo(ammo) -> void:
current_weapon_ammo_debug = str(ammo[0], " / ", str(ammo[1]))
func _on_update_weapon_stack(weapon_stack) -> void:
current_weapon_stack_debug = ""
for i in weapon_stack:
current_weapon_stack_debug += "\n" + i
func _on_weapon_changed(weapon_name) -> void:
current_weapon_debug = weapon_name
DaMushKen:
if not intersect: return
I see this line potentially causing an error. Your shoot function expects the function to return a Vector3, but you are returning nil. You should make your _get_3d_mouse_position() return a Vector3 by type, which will help you find the issue.
(This looks like func _get_3d_mouse_position() -> Vector3:)
When I make the function return Vector3 the line you said gives an error so it’s probably that one. I dont know how to do that line tho. If I remove it my game crashes
Just make it return Vector3.ZERO then check in the shoot() function if the Vector3 is blank, then handle that case
1 Like