Major issues with 3D player

Godot Version

3.6

Question

Okay so this one is very complicated but please stick with me.

I want to make it clear first why I am using Godot3. I started the project under Godot4.1 but after multiple months of it constantly giving me issues over the slightest thing and me getting nowhere, I decided to try Godot3.6 Stable. I was relieved to get further in only an hour than I ever did over 2 months.

Now I feel I must explain what I am trying to do.
My game is called Marauder, in this you control a player which is comprised of a floating animated model over a ball. The ball reacts to player input but is also dictated by physics. The floating player follows the ball.

At first this all worked fine, when I was using a non-animated model.
I have health, an Area node floater_area which is detected by the DamageBox Area node to apply it’s damage to the player.

If the floater_area enters the DamageBox, the DamageBox applies it’s damage to the animated_player and it’s health variable.

Each DamageBox can do it’s own damage with it’s own time interval.

I made a rigged player in Blender an animated it in Blender as well. I have been somewhat able to get that working but I may just animate in Godot in the future given my problems.

When I used the non-animated player, damage was applying fine. Now I can’t get it to do anything since I had to remake the whole dang thing for the Animated player.

The reason I have to keep remaking things from the ground up is because I can not use the animations if I put the rigged model into a non-inherited scene. I have tried to use the inherited scene as a base, but that is where I am finding these issues. I even rewrote the scripts for everything so that it should be compatible with the new player, but it’s not.

Of course this is a very complicated situation, with A LOT of code. I am looking to redo this all again in a different way, hopefully with better results.

There will be multiple players so I need to ensure that things like the DamageBox and the Spin_Blade (which flies towards the player and carries an invisible DamageBox with it) can detect the floater_area no matter the parent. (Currently the Spin_Blade follows the nearest floater_area with no issues but of course no damage)

Also I need to reconsider my Animations. Is there some magic way to use the animations from Blender that I am not aware of or is it best to start over in Godot?

Please let me know if you need any more clarification and sorry if this isn’t all that clear. I am really irritated by this since I was flying for a whole 2 weeks but have been stuck on this for nearly 3 months.
I may even make a video on this issue.

Godot is not a good skeletal animation tool, much harder to set up bone constraints for traditional animation. Keep animating with Blender.

You should totally be able to use the animations, you can access all the nodes from scripts and set the instantiated scene “editable children” to interact with the imported AnimationPlayer and skeleton.

Again should be possible, an scene via inheritance is the same as any other, scripts do not care how a set of nodes was created, only it’s composition.

An Area node can detect other Areas perfectly fine, will need details on how you are using them to deduce what is going wrong.

Godot should import animations from Blender, depends on how you export them. In 3.6 only GLTF and DAE are supported with animations, GLTF is highly recommended.

Yeah I need to be more specific.
I need to use a KinematicBody for the player model, which that model needs to follow the ball, have it’s own rotation speed when following the ball and be able to be effected by physics when the die() function is called.

I am using .glb which is just combined GLTF to be simple and the animations do show up under an AnimationPlayer, but using the imported model as the floater KinematicBody in another node (the main player node) results in no animation access.

Both areas used to detect before but now don’t. Here is the code:

parent script:
Note that I took the animation calls out since nothing happened

extends Node

export var max_health: int = 100
var current_health: int = max_health

onready var health_label = $Control/HealthCounter  # Reference to the health counter UI

func _ready():
	update_health_label()
	
	# Connect the signal from riged_player or floater_area
	var floater_area = $floater/floater_area
	if floater_area:
		floater_area.connect("apply_damage", self, "_on_damage_received")

# Function to take damage
func _on_damage_received(damage_amount: int):
	current_health -= damage_amount
	update_health_label()
	
	if current_health <= 0:
		die()

func update_health_label():
	health_label.text = str(current_health) + "%"

func die():
	print("Player has died")
	# Handle player death, disable control, etc.

DamageBox script:

extends Area

export var damage_amount: int = 10  # Damage this box applies
export var damage_interval: float = 1.0  # How often damage is applied

var damage_timer: float = 0.0
var inside_floater_area: bool = false
onready var floater_area = null  # Holds the reference to the floater_area

func _ready():
	add_to_group("damage_box")  # Ensure it is in the damage group
	collision_layer = 2  # Set appropriate collision layer
	collision_mask = 1   # Set appropriate collision mask to detect floater_area
	connect("body_entered", self, "_on_body_entered")
	connect("body_exited", self, "_on_body_exited")

func _process(delta):
	# Only apply damage if floater_area is inside
	if inside_floater_area and floater_area:
		damage_timer += delta
		if damage_timer >= damage_interval:
			# Apply damage to the riged_player
			var parent_node = floater_area.get_parent()
			if parent_node.has_method("take_damage"):
				parent_node.take_damage(damage_amount)
			damage_timer = 0.0  # Reset the timer

# Detect when floater_area enters the DamageBox
func _on_body_entered(body):
	if body.name == "floater_area":  # Ensure the entering body is floater_area
		inside_floater_area = true
		floater_area = body
		damage_timer = 0.0  # Reset the damage timer

# Detect when floater_area exits the DamageBox
func _on_body_exited(body):
	if body.name == "floater_area":
		inside_floater_area = false
		floater_area = null
		damage_timer = 0.0  # Reset the timer when exiting

Here is the structure of the player:

image

Never mind I fixed the detection issue. It was literally just using my old script that solved it.

extends Area

export var damage_amount: int = 10  # Damage specific to this box
export var damage_interval: float = 1.0  # How often damage is applied

var damage_timer: float = 0.0
var inside_floater: bool = false
onready var floater = null  # We'll set this when the floater enters

func _ready():
	collision_layer = 2  # DamageBox layer
	collision_mask = 1   # Detect the player layer (e.g., floater)
	connect("body_entered", self, "_on_Area_body_entered")
	connect("body_exited", self, "_on_Area_body_exited")


func _process(delta):
	# Only apply damage if the floater is inside
	if inside_floater and floater:
		damage_timer += delta
		#print("Damage Timer: ", damage_timer)
		if damage_timer >= damage_interval:
			#print("Applying damage: ", damage_amount)
			floater.take_damage(damage_amount)
			damage_timer = 0.0  # Reset the timer


# Detect when the floater enters the DamageBox
func _on_Area_body_entered(body):
	if body.name == "floater":  # Ensure it's the floater
		print("Floater entered the damage area.")
		inside_floater = true
		floater = body


# Detect when the floater exits the DamageBox
func _on_Area_body_exited(body):
	if body.name == "floater":
		inside_floater = false
		floater = null
		damage_timer = 0.0  # Reset the timer when leaving

Never mind all this is working. I read this and made the post while I was way too tired to be working on the game. Thank you so much, it seems I have forgotten everything I used to know about Godot.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.