0

I'm using godot 4.2.1 and try to orient this tutorial series in my first test project.

I made a map and common enemy which is inherited form base enemy and walks on a path. Also I made a TowerMk1 inherited from base tower. Now I want this tower to rotate and track enemies in it's range.

My problem is that body_entered signal of tower's Area2D doesn't trigger.

My BaseEnemy:

enter image description here

My CommonEnemy (pink rectangle - CollisionShape2D):

enter image description here

BaseTower:

enter image description here

TowerMk1 (blue circle - CollisionShape2D):

enter image description here

body_entered is connected in BaseTower in the editor - proof:

enter image description here

In TowerMk1 it's connected automatically because of an inheritance.

BaseTower script:

extends Node2D

@export var enemy_tracking : bool = true

var enemies = []

func _physics_process(delta):
    if enemy_tracking:
        track_enemy()
    else:
        pass

func track_enemy():
    var target = select_enemy()
    if not target == null:
        turn_to(target)

func select_enemy():
    var max_progress = -1
    var target
    var current_progress
    for enemy in enemies:
        current_progress = enemy.get_progress()
        if current_progress > max_progress:
            target = enemy
            max_progress = current_progress
        
    return target

func turn_to(target):
    get_node("TowerSprite").look_at(target.position)

func _on_range_body_entered(body):
    if body is BaseEnemy:
        enemies.append(body.get_parrent())


func _on_range_body_exited(body):
    if body is BaseEnemy:
        enemies.erase(body.get_parrent())

I put a debugger stop flag on this row:

enter image description here

But it is not triggered at all!

I marked a checkbox to show collision shapes during a debug and this is how it looks:

enter image description here

You can see that the pink rectangle is inside the blue circle (it was not spawned right here - they traveled from the beginning of the path). But the collision was not triggered.

Collision of both Range of the tower and AnimatebleBody2D of the enemy match in their parameters: Layer 1, Mask 1.

What do I do wrong?

2 Answers 2

2

The problem is the AnimatableBody2D, which is basically a StaticBody2D.

Referencing to this ticket in github

When StaticBody2D is moved, it is teleported to its new position without affecting other physics bodies in its path.

This is also true for AnimatableBody2D.

You could switch to an CharacterBody2D to make it work, or disable sync_to_physics in the AnimatableBody2D. Both will allow the area to detect your enemy.

Sidenode:

if body is BaseEnemy:

will not work, cause your AnimatableBody is not holding your script. Instead use:

if body.get_parent() is BaseEnemy:
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer. But I'm confused with "When moved manually, it affects other bodies in its path." in the description of AnimatableBody2D.
I think the problem is, that you are not directly moving the Body, but its parent. So the position of AnimatableBody2D actually does not change. I tried moving the Body directly be changing its position, which results in the area detecting the body. So I guess since the linear and angular velocity are estimated, it uses the bodys position for calculations. Since we move the PathFollow2D instead, the body is "porting" not moving into the area
-1
func _on_range_body_entered(body):
    if body is BaseEnemy:
        enemies.append(body)

func _on_range_body_exited(body):
    if body is BaseEnemy:
        enemies.erase(body)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.