OK, I think I understand why what I am trying to do won’t work, thank you.
My next question then is, is it possible to do this so that different enemies can have different max health? You mentioned having this in the class script enemy.gd:
@export var health := 100
But then I’m not sure how to change this for different enemy types because I now get an error if trying to define health in turret.gd (also I take your point about scenes and scripts not being the same thing - my inherited scene is an enemy called turret and has only one script, turret.gd which extends enemy)
Here’s a more complete copy of my codes. enemy.gd:
class_name Enemy
extends CharacterBody3D
@onready var player = get_tree().get_first_node_in_group('Player')
@onready var skin = get_node('skin')
@onready var gravity := 10.0
func hit(damage,health):
health -= damage
turret.gd (though literally the only thing in this script that’s relevant is var health := 200):
extends Enemy
@export var turnspeed := 2.0
@export var shot_timer := false
@onready var barrel := $skin/RayCast3D
var mortar := load("res://objects/mortar_enemy.tscn")
var instance
var detection_dist := 50.0
var health := 200
func _physics_process(delta: float) -> void:
move_logic(delta)
attack_logic()
move_and_slide()
func move_logic(delta) -> void:
var target_dir = (player.position - position)
var target_angle = -Vector2(target_dir.x,target_dir.z).angle() - PI/2
skin.rotation.y = rotate_toward(skin.rotation.y, target_angle, turnspeed * delta)
velocity.y -= gravity * delta
func attack_logic() -> void:
if not shot_timer and (player.position - position).length() < detection_dist:
$Timer.start()
shot_timer = true
#print("timer started")
instance = mortar.instantiate()
instance.position = barrel.global_position
instance.transform.basis = barrel.global_transform.basis
get_parent().add_child(instance)
func _on_timer_timeout() -> void:
shot_timer = false
bullet.gd:
extends Area3D
const speed := 87.0
@onready var mesh = $CSGSphere3D
@onready var ray = $RayCast3D
@onready var particles = $GPUParticles3D
@onready var player = get_tree().get_first_node_in_group("Player")
@export var damage := 1
func _ready() -> void:
pass
func _process(delta: float) -> void:
var travel_distance = speed * delta
ray.target_position = Vector3(0,-1,0) * travel_distance
position += transform.basis * Vector3(0,-speed,0) * delta
if player.barrel.is_colliding():
destroy()
if ray.is_colliding():
var collider = ray.get_collider()
if 'hit' in collider:
collider.hit(damage,collider.health)
destroy()
func destroy() -> void:
mesh.visible = false
particles.emitting = true
await get_tree().create_timer(1.0).timeout
queue_free()
func _on_timer_timeout() -> void:
queue_free()
Sorry I know this is long and my code is probably very shoddy, I’m just using this project to learn how Godot works. For this reason, I know it might seem pointless to be extending the enemy class at all, but I’m doing it to figure out how it all works as I feel like it will be useful to use in future. Thanks 