- Home /
make projectiles always hit target
Hey guys, Making a 3d TD game where I have one of my towers shooting a projectile to hit an enemy unit. Since the enemy units are moving the projectile doesnt hit its target every time. I heard this can be remedied by using the speed and direction of the enemy. I dont know how I would include this though. I dont think it would hit if the enemy changed direction either. Does anyone know of a way I could solve this problem? Code is posted below. Thanks in advance,
AstarAIEnemy enemyObjectDetection = EnemySpawn.enemyList[closestIndex].GetComponent<AstarAIEnemy> (); //gets astarai code for that unit
targetPosition = enemyObjectDetection.transform.position; //sets the enemy position to the pos of the player unit
float distanceToTargetPos = Vector3.Distance (targetPosition, transform.position); //finds distance between the two units
//projectile motion code
// while (true) {
Projectile.position = this.transform.position; //puts projectile at archers pos
//calc velocity
float projectile_Velocity = distanceToTargetPos / (Mathf.Sin (2 * firingAngle * Mathf.Deg2Rad) / gravity);
// Extract the X Y componenent of the velocity
float Vx = Mathf.Sqrt (projectile_Velocity) * Mathf.Cos (firingAngle * Mathf.Deg2Rad);
float Vy = Mathf.Sqrt (projectile_Velocity) * Mathf.Sin (firingAngle * Mathf.Deg2Rad);
// Calculate flight time.
float flightDuration = distanceToTargetPos / Vx;
Projectile.rotation = Quaternion.LookRotation(targetPosition - Projectile.position); //rotates player/projectile towards object
while (elapse_time <= flightDuration) {
Projectile.Translate (0, (Vy - (gravity * elapse_time)) * Time.deltaTime, Vx * Time.deltaTime);
elapse_time += Time.deltaTime;
yield return null;
}
//yield return new WaitForSeconds(5f);
Projectile.position = this.transform.position; //resets so that unit can fire again
elapse_time = 0;
Answer by ABerlemont · Jun 24, 2014 at 09:04 AM
If you want your missile to "follow" your target wherever it goes you can do this :
using UnityEngine;
using System.Collections;
public class Missile : MonoBehaviour {
public Transform target;
float speed = 2f;
void Update(){
if(target == null) return;
transform.position = Vector3.MoveTowards(transform.position, target.position, Time.deltaTime * speed);
}
}
EDIT
Another way to do it.
This one is timed based instead of speed based so that's it's easier to control height.
using UnityEngine;
using System.Collections;
public class Missile : MonoBehaviour {
public Transform target;
float timeTravel = 10f;
float time = 0f;
Vector3 origin;
Vector3 destination;
float distance = 0f;
void Start(){
shootAt(target);
}
void shootAt(Transform newTarget){
target = newTarget;
time = timeTravel; // in seconds
origin = transform.position;
destination = target.position;
}
void Update(){
if(target == null) return;
time -= Time.deltaTime;
destination = target.position;
float progress = Mathf.InverseLerp(timeTravel, 0f, time);
//set projectile position
Vector3 newPosition = Vector3.Lerp(origin, destination, progress);
//set projectile height
newPosition.y = Mathf.Cos(Mathf.Lerp(-Mathf.PI * 0.5f, Mathf.PI * 0.5f, progress));
transform.position = newPosition;
if(transform.position == destination){
target = null;
}
}
}
@ABerlemont This would work but I also need it to arc like it was a projectile. Not just a missle.
I edited my answer to have the arc thing. To change height just multiply the newPosition.y before applying it to the object's position.
@ABerlemont I used your movetowards code with my existing physics code for the y component of velocity to get an answer. I had to put the target position inside the while loop so that it updates the enemy position while its traveling. Thanks for your help, ill give you the answer.
Your answer
![](https://koobas.hobune.stream/wayback/20220613152353im_/https://answers.unity.com/themes/thub/images/avi.jpg)