Does anyone know why I’m getting an error at line 28 in hitscan_weapon.gd(*) script saying “Could not find type “Enemy” in the current scope.”
Here is the code:
extends Node3D
@export var fire_rate := 14.0 @export var recoil := 0.05 @export var weapon_mesh: Node3D @export var weapon_damage := 15 @export var muzzle_flash: GPUParticles3D @export var sparks: PackedScene
@onready var cooldown_timer: Timer = $CooldownTimer @onready var weapon_position: Vector3 = weapon_mesh.position @onready var ray_cast_3d: RayCast3D = $RayCast3D
Called every frame. ‘delta’ is the elapsed time since the previous frame.
func _process(delta: float) → void:
if Input.is_action_pressed(“fire”):
if cooldown_timer.is_stopped():
shoot()
Hi Reluxi, you should make this an Ask topic and tag it with the code from the video you are on. That way the correct TA will be notified. They might not see this otherwise.
I still get an error after trying to run the game saying “Invalid get index ’position’ (on base: ’null_instance’).” And it’s showing this line in hitscan_weapon.gd script:
@onready var weapon_position: Vector3 = weapon_mesh.position
Thank you! Now I can run the game, but there seems to be another problem. Whenever I try to shoot with my smg, the game crashes and another error appears saying “Cannot call method ‘restart’ on a null value.” And it’s showing this line in hitscan_weapon.gd script:
If you can double check that all the exported variables that are in the inspector have been assigned and see if that works.
The muzzle flash is another one the same as you done with the weapon_mesh previously. Need to ensure there’s something assigned, otherwise it will be null.
Thanks, that error also got cleared and I moved to the next lecture (Game Over), but I realized that when the enemy attacks, I don’t get a message in the output saying “Enemy attack!”, I just see the attack animation. I think the attacks should be like “Enemy attack!” 100 “Enemy attack!” 80 “Enemy attack!” 60 or something like that, and I also don’t get the Game Over screen because of that.
Here’s my enemy.gd(*) code if that’s needed
extends CharacterBody3D
class_name Enemy
const SPEED = 5.0
const JUMP_VELOCITY = 4.5
@export var max_hitpoints := 100
@export var attack_range := 1.5
@export var attack_damage := 20
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
@onready var navigation_agent_3d: NavigationAgent3D = $NavigationAgent3D
@onready var animation_player: AnimationPlayer = $AnimationPlayer
var player
var provoked := false
var aggro_range := 12.0
var hitpoints: int = max_hitpoints:
set(value):
hitpoints = value
if hitpoints <= 0:
queue_free()
provoked = true
func _ready() -> void:
player = get_tree().get_first_node_in_group("player")
func _process(_delta: float) -> void:
if provoked:
navigation_agent_3d.target_position = player.global_position
func _physics_process(delta: float) -> void:
var next_position = navigation_agent_3d.get_next_path_position()
# Add the gravity.
if not is_on_floor():
velocity.y -= gravity * delta
var direction = global_position.direction_to(next_position)
var distance = global_position.distance_to(player.global_position)
if distance <= aggro_range:
provoked = true
if provoked:
if distance <= attack_range:
animation_player.play("Attack")
if direction:
look_at_target(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 look_at_target(direction: Vector3) -> void:
var adjusted_direction = direction
adjusted_direction.y = 0
look_at(global_position + adjusted_direction, Vector3.UP, true)
func attack() -> void:
print("Enemy Attack!")
player.hitpoints -= attack_damage
You’ve declared the attack() function but haven’t actually called it anywhere.
I like Bram’s idea of keyframing the function call in the attack animation, but even before doing that or similar, you can also just temporarily call attack() where you play the animation. Then you can confirm that the function works, which will help you debug if there are any problems with keyframing it.