# [Godot 2] Predict target position not working

Attention Topic was automatically imported from the old Question2Answer platform.

Edit 2: I noticed I forgot an operator that I put in the actual code of enemy, when calculating the angle, but I did not put it here in the question. I updated the line now.
Edit: added code of ai_controller.gd, enemy shoot code and methods used in shoot code.

Hello!

I’m making a shooter game and I want to enemies fire bullets at a predicted player position. The enemies need to rotate to that position. My code was working when I made it for 2d, but I changed the game to a 3D view. I still using 2d for all the calculations. My approach was to keep z positions locked in -10 for all the objects that need calculations. So, I’m using only x and y to make the calculations and ignoring z positions (because all z positions are the same). I’m keeping the rotations only in z axis. After doing all this, the enemy started to miss the target. I researched a lot but I did not find an answer.

I’m using Godot 2.1.5

Here is the code:

``````
------------ Code in ai_controller.gd------------
func _fixed_process(p_delta):
ai_movement_process(_enemies_type_1)
for enemy1 in _enemies_type_1:
var current_enemy = enemy1.get_ref()
if current_enemy:
# This is the only method that changes rotation
current_enemy.update_rotation(p_delta)

```
current_enemy.check_player_distance_to_shoot()
if current_enemy.Fa != null:
current_enemy.update_ship_velocity()
current_enemy.reduce_player_speed_if_close_to()
var new_pos = current_enemy.get_global_2d_pos() + current_enemy.current_velocity * p_delta
if new_pos.x < 0:
new_pos.x = 0
elif new_pos.x > 5000:
new_pos.x = 5000
if new_pos.y < 0:
new_pos.y = 0
elif new_pos.y > 5000:
new_pos.y = 5000
current_enemy.set_global_2d_pos(new_pos)
```

------------Code in enemy.gd------------
extends Spatial

func _rotate_to_target(p_delta, p_target_player):
if p_target_player == null:
return

var the_tplayer = p_target_player.get_ref()

if !the_tplayer:
return

target_p_pos = _global_node.get_projectile_future_point(_shoot_from_node.get_global_2d_pos(), \
laser_shot_speed, the_tplayer.get_global_2d_pos(), the_tplayer.current_velocity)

var my_pos = get_global_2d_pos()

var ang = -(target_p_pos - my_pos).angle()

# Now I'm setting the angle straight
set_2d_rot(ang)

# I was using interpolation but it didn't worked either
set_2d_rot(lerp_angle(get_2d_rot(), ang, rotation_velocity * p_delta))

func shoot(p_weapon):
var the_laser = _laser_scn.instance()
the_laser.w_damage = laser_shot_damage
the_laser.w_fire_rate = laser_shot_fire_rate
the_laser.w_speed = laser_shot_speed
the_laser.w_range = laser_shot_range

var start_pos = _shoot_from_node.get_global_3d_pos()
the_laser.set_global_3d_pos(start_pos)
the_laser.start_position = Vector2(start_pos.x, start_pos.y)
the_laser.set_2d_rot(get_2d_rot())
_can_shoot_laser = false
_timer_laser_fire_rate.start()

------------https://forum.godotengine.org-28776/rotate-kinematicbody2d-based-mouse-position-varying-rate------------

func lerp_angle(p_start, p_end, p_delta): #In radians
if abs(p_start - p_end) >= PI:
if p_start > p_end:
p_end += 2 * PI
else:
p_start += 2 * PI

return lerp(p_start, p_end, p_delta)

------------Code in player.gd and enemy.gd and all objects that need position and rotation calculations in 2d------------

func get_global_2d_pos():
var pos = get_global_transform().origin
return Vector2(pos.x, pos.y)

func get_global_3d_pos():
return get_global_transform().origin

func set_global_3d_pos(p_position):
set_global_transform(Transform(get_global_transform().basis, p_position))

func get_2d_rot():
return get_rotation().z

func set_2d_rot(p_rotation):
set_rotation(Vector3(get_rotation().x, get_rotation().y, p_rotation))

------------Code in _global_node------------

func get_projectile_future_point(p_my_position, p_projectile_velocity, p_target_position, p_target_velocity):
var target_dir = (p_target_position - p_my_position).normalized()
var target_vel_ortho = p_target_velocity.dot(target_dir) * target_dir
var target_vel_tang = p_target_velocity - target_vel_ortho
var shot_vel_tang = target_vel_tang
var shot_speed = shot_vel_tang.length()

var direction = Vector2()

if shot_speed > p_projectile_velocity.length():
direction = p_target_velocity.normalized() * shot_speed
else:
var shot_speed_ortho = sqrt(p_projectile_velocity.length() * p_projectile_velocity.length() - shot_speed * shot_speed)
var shot_vel_ortho = target_dir * shot_speed_ortho

direction = shot_vel_ortho + shot_vel_tang

var pos_norm = (p_my_position - p_target_position).length()
var time_to_collision = pos_norm

if p_projectile_velocity.length() > p_target_velocity.length():
time_to_collision /= (p_projectile_velocity.length() - p_target_velocity.length())
else:
time_to_collision /= p_projectile_velocity.length()

var shot_velocity = direction
var collision_point = p_my_position + shot_velocity * time_to_collision

return collision_point
``````

Thanks in advance! =)

Edit: the code is not working after I changed some parameters. I don’t know why.

It is working now. I think I modified some code and forgot that I had modified. I’m seeing the spaceships hitting the player most of times. I remember it was little different when I was using 2d but it is working pretty close of what I wanted to it works. I changed some parameters when I started using 3d and I think the difference I’m seeing now is because of this.

Thanks for the people who helped in facebook group.

equus | 2018-12-13 18:44