Hi all. I’m currently working on a tank game in order to become more familiar with Unity. In the game, there will be projectiles moving at high speeds (1,500 m/s or more). At first, I was content with using Raycasts to represent these high speed shots, but as engagement ranges slowly expanded to 2-3 km, discrepancies began to occur.
First of all, I use a modified version of the TrajectorySimulation, and CalculateLeadForProjectiles scripts on the wiki along with a modified CalculateElevation function I kitbashed together from various sources. I don’t have the modified scripts with me right now as I am using a different computer. I’ll try to post them as soon as I can.
To the main question: Is there a way to properly simulate travel time while retaining the use of Raycasts?
Attached is an illustration of my current methods and problem
I have tried adding a delay in between Raycasts via yield WaitForSeconds(TimeProjectileMoves1Meter) but this only results in the simulation slowing to an unacceptable crawl, most likely limited by Update.
Thoughts on the matter would be most appreciated.
UPDATE: here is my code for firing the gun:
static function ShootProjectile(bullet:Projectile,muzzle:Transform,velocity:Vector3) {
var numVertices : int = 3000;
var positions = new Vector3[numVertices];
// The first line point is wherever the player's cannon, etc is
positions[0] = muzzle.position;
// Time it takes to traverse one segment of length segScale
var segmentScale : float = 1.0;
var segTime : float;
// The velocity of the current segment
var segVelocity : Vector3 = (muzzle.forward * bullet.speed) + (velocity);
var hit : RaycastHit;
for (var i=1; i<numVertices; i++) {
// Debug.Log(segTime);
// worry about if velocity has zero magnitude
if(segVelocity.sqrMagnitude != 0)
segTime = segmentScale/segVelocity.magnitude;
else
segTime = 0;
// Add velocity from gravity for this segment's timestep
segVelocity = segVelocity + Physics.gravity*segTime;
// Check to see if we're going to hit a physics object
if(Physics.Raycast(positions[i-1], segVelocity, hit, segmentScale)){
Debug.DrawLine (positions[i-1], hit.point, Color.red,30,false);
// set next position to the position where we hit the physics object
positions _= positions[i-1] + segVelocity.normalized*hit.distance;_
-
ballistics.HitProjectile(segTime,positions,i,segVelocity,segmentScale,bullet);*
return;
- }*
// If our raycast hit no objects, then set the next position to the last one plus v*t
else {
positions = positions[i-1] + segVelocity*segTime;
_ Debug.DrawLine (positions[i-1], positions[i-1] + segVelocitysegTime, Color.red,30,false);_
_ }_
_ }_
_ }*_
static function HitProjectile(time:float,positions:Vector3[],length:int,velocity:Vector3,scale:float,bullet:Projectile) {
* for (var i = 1; i < length+2; i++) {*
* var hit : RaycastHit;*
* if(Physics.Raycast(positions[i-1], velocity, hit, scale)){*
* Debug.DrawLine (positions[i-1], hit.point, Color.yellow,30,false);*
* var boom = new Instantiate(bullet.explosion,hit.point,Quaternion.identity);*
* var hitInfo : BulletHit = new BulletHit(20,10,hit.point);*
* hit.transform.root.SendMessage(“TakeDamage”,hitInfo,SendMessageOptions.DontRequireReceiver);*
* return;*
* }*
* else {*
* Debug.DrawLine (positions[i-1], positions[i-1]+velocity, Color.yellow,30,false);*
* }*
yield WaitForSeconds(time);
* }*
* Debug.Log(“No hit?”); *
* }*
As you can see, at the start of the for loop, segTime is defined as unit (segmentScale) divided by segVelocity (speed). The yield wait is in the HitProjectile function where I believed it would delay casting the next ray by the time it takes the bullet to move 1 segment.
To clarify, I am looking for a way to add a delay in between the Rays casted in the HitProjectile function. This should simulate the actual time it takes for the bullet to travel across the previously calculated trajectory in ShootProjectile.
The script is given the tank’s equipped bullet type, muzzle Transform and current velocity.