Godot Version
Godot Engine v4.4.1.stable.steam.49a5bc7b6
Question
Im trying to get an enemy position and put it in the CharacterBody2D’s script, but i don’t know on how to do this
Godot Engine v4.4.1.stable.steam.49a5bc7b6
Im trying to get an enemy position and put it in the CharacterBody2D’s script, but i don’t know on how to do this
I assume you have a player script of type Character body 2D.
You will need a way to reference your enemy to get any information like his transform. There are a lot of ways to do so:
example:
@onready var enemy : Node3D = $enemyPath
print(enemy.position)
If you’re going to be doing a Sonic-style platformer, you probably aren’t going to have a lot of enemies active at once. You may find the easiest way to do this is have a global script that contains an array of active enemies, and then you can loop over the array to determine the closest:
# LevelState.gd
var ActiveEnemies: Array = []
[...]
func get_closest_enemy(pos: Vector2) -> Node:
var closest: Node = null
var distsq = 1000000000.0 # "infinity"
for e in ActiveEnemies:
var testd = pos.distance_squared_to(e.position)
if testd < distsq:
distsq = testd
closest = e
return closest # NOTE: Could be null if no active enemies...
The test above uses distance squared because it’s cheaper; it gets rid of a square root per loop iteration. Distance squared doesn’t tell you absolute distance, but it’s fine for relative distance (eg: which thing is closer).
Once you have the node for the closest enemy, you have their position as well as lots of other information, and potentially the script driving it if you want to call functions on its script.
Update: I tried to use the raycast method. However my character keeps teleporting to the wrong poition
(the Jumpcount is for the double jump mechanic)
Here’s my code:
Thank you, i will also try this method and give the updates later
2000
seems like a lot.
I lowered the velocity to 200 but he still teleports below the enemy…
For this method should i put the enemies in the array like this?
What exactly do you want this to do? What you’ve said implies this is for a Sonic Adventure style homing attack, but are you hoping this will launch the player at the enemy, or are you hoping this will teleport them to an attack position?
If you want a homing attack that plays out over a fraction of a second (or longer, for that matter), you’ll need to store the target the player is attacking, set a vector towards the target, and update that vector each frame until they collide or are interrupted somehow. Particularly if your enemies move.
If you want an instantaneous homing teleport attack, you probably want to do something like:
func player_homing_attack(target: Node, radius: float):
position = target.position.direction_to(position) * radius
[do damage, play sounds, fx...]
Basically, get the normalized direction from the target to the player, scale that by the distance you want the player to be when they hit, set that as the player’s position.
I wanted to teleport sonic to the enemy for now. I tried implementing this code and it kinda works, the only problem is that when there is more than one enemy, sonic always teleport to the first one:
If you want to be able to hit multiple enemies in sequence, you’ll need to take the enemy you just hit out of the potential target set. If your enemies can only take one hit that’s pretty easy. If they can take multiple hits and you want to (say) bounce back and forth between two enemies, you’ll probably want to keep track of the last enemy you hit and have a way of telling your target function to ignore that one.
I think i found the solution (at least a temporary one).
#assigning the raycast
@onready var enemy: Node2D = $"Enemy Detection"
#assigning the colision point
var col_point
[...]
if enemy.is_colliding():
#Annotating the position
col_point = enemy.get_collision_point()
CanHomeAttack = true
if CanHomeAttack and Input.is_action_just_pressed("Jump") and !is_on_floor():
position = position.move_toward(col_point, 200)
velocity.y = -7000
velocity.x = 700
CanHomeAttack = false
Basically it will detect when the raycast collide with the enemy and annotate it’s position, then if i press the “Jump” button it will teleport to the colision point which is being detected by the raycast