Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | andrew.s |
Hi all,
I am trying to create an entity that predictively looks for where a player will be based on their position and velocity and shoots for that location. I’m mostly basing this on the GDC Video ‘Math for Game Programmers: Predictable Projectiles’.
Overall my logic seems to work decently well, but I am running into an issue where the projectile only seems to be spawning / being shot when the player is in a static state / not moving. Here’s the code for my ‘turret’ class, which aims and shoots at the player:
extends StaticBody2D
var target: Tank
var PROJECTILE_SPEED = 100
var pos
const proj = preload("res://Projectile.tscn")
# Called when the node enters the scene tree for the first time.
func _ready():
$Timer.start()
print("I am ready")
pos = $Position.global_position
func _process(delta):
pass
func track():
pass
var t_vel = target.velocity
var t_pos = target.global_position
var a = t_vel.dot(t_vel) - PROJECTILE_SPEED
var b = 2*(t_pos - pos).dot(t_vel)
var c = (t_pos - pos).dot((t_pos - pos))
if pow(b, 2) > 4*a*c and a != 0:
var t1 = (-b + sqrt(pow(b, 2) - 4*a*c))/(2*a)
var t2 = (-b - sqrt(pow(b, 2) - 4*a*c))/(2*a)
var t = min(t1, t2)
var predicted_pos = t_pos + t_vel*t
var dir = (predicted_pos - pos).normalized()
var final_vel = dir*PROJECTILE_SPEED
var projectile = proj.instance()
self.get_parent().add_child(projectile)
projectile.global_position = pos
print(final_vel)
projectile.VELOCITY = final_vel
func _on_Timer_timeout():
print("Firing")
track()
Sorry if it is a bit messy, this is still very in-progress. The class has a timer node attached for now which should be timing out and then firing every second, but it does not if the player (a ‘tank’ object) is moving.
Here is the code for my basic projectile:
extends Area2D
class_name TempProjectile
var VELOCITY: Vector2 = Vector2(0, 0)
func _physics_process(delta):
translate(VELOCITY*delta)
Any help or advice would be very appreciated
Does it keep on printing the “Firing”?
Then the problem might be lying in the if clause.
Print out the values of the comparisons in the clause in the line before it and check if (and why) the “if” may not be true.
wombatstampede | 2019-11-08 07:58
Yes it does. After looking at it again with fresh eyes, I noted that the ‘pow(b, 2) > 4ac’ was never evaluating to true while I was moving. That’s because the ‘a’ coefficient term should use pow(PROJECTILE_SPEED, 2) instead of PROJECTILE_SPEED, so ‘a’ was always too large.
I also for whatever reason needed to change the target velocity to the opposite sign to get the correct prediction. Not sure yet if this is an error on my part using the coordinate system or what. Without inverting the velocity, it will always fire behind the target instead of ahead.
Regardless, it’s working now which is great! Thanks for the suggestion.
andrew.s | 2019-11-10 00:46