# Missle guideline (raycast)

hey guys,
iam trying to make a game similar to gunbound.
i cant figure out how to make a solid rounded guidline for my missle that shows where its going to hit.
(i cant use raycast because it must be rounded)
my missle velocity is depends on variable called force.
i need to do something like this:

This Red Line is what i am looking for.
anybody have any idea??

assuming the only force acting is gravity and you don’t have propulsion mid-flight.

taken from my ballistics class, used to trace the path of a mortar in a 3D enviroment, should be easy enough to convert to 2D.

start position should be the position in world space where the projectile appears and starts it’s journey.
forward is the forward vector of the muzzle
velocity… duh
maxTime is how long should we simulate the flight for
timeResolution is how long each tick is (basically the loop’s deltaTime)

``````    /// <summary>
/// Gets the ballistic path.
/// </summary>
/// <returns>The ballistic path.</returns>
/// <param name="startPos">Start position.</param>
/// <param name="forward">Forward direction.</param>
/// <param name="velocity">Velocity.</param>
/// <param name="maxTime">Total time to simulate.</param>
/// <param name="timeResolution">Time from frame to frame.</param>
public static Vector3[] GetBallisticPath(Vector3 startPos, Vector3 forward, float velocity, float maxTime, float timeResolution){

Vector3[] positions = new Vector3[Mathf.CeilToInt(maxTime / timeResolution)];
Vector3 velVector = forward * velocity;
int index = 0;
Vector3 curPosition = startPos;
for (float t = 0.0f; t < maxTime; t += timeResolution) {

if (index >= positions.Length)
break;//rounding error using certain values for maxTime and timeResolution

positions [index] = curPosition;
curPosition += velVector * timeResolution;
velVector += Physics.gravity * timeResolution;
index++;
}
return positions;
}
``````

hey,
it seems very helpful, but i cannot make it work. (mabe its because i am too new in unity)
if you cant point me how to do it i will be galde.
if i explain my self wrong, i want to add guideline aim all the time, and it will update with the power bar(as long as i press “space” it will give more force to the bullet) here is my code:

``````public class Weapon : MonoBehaviour {
public Rigidbody2D player_rb;
private float rotate_speed = 1f;
public Transform firePoint;
public GameObject bulletPrefab;
public Text rotate;
private int rotate_int;
private float cannon_move = 0f;
public float force;
//power_bar
public Image PowerBar;
public Text power;
public float current_power = 0;
public float max_power = 1000f;
public float recoil;

void Start()
{
PowerBar.fillAmount = current_power / max_power;
}
void Update () {
cannon_move = Input.GetAxisRaw("Vertical") * rotate_speed;
rotate_int = (Mathf.FloorToInt(firePoint.transform.eulerAngles.z));
rotate.text = rotate_int.ToString();
if (Input.GetButton("Fire_Bar"))
{
Power();
}
if (Input.GetButtonUp("Fire_Bar")) //realse button
{
StartCoroutine(Shoot());
}
//guideline aim
GetBallisticPath(firePoint.position,firePoint.forward,current_power,1000f,Time.deltaTime);
}
void FixedUpdate()
{
firePoint.Rotate(0, 0, cannon_move);
}
IEnumerator Shoot()
{
Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
yield return new WaitForSeconds(0.02f);
Zero_current_power();
Recoil(recoil);
}
void Power()
{
current_power += 250 * Time.deltaTime;
PowerBar.fillAmount = current_power / max_power;
power.text = "Power:" + Mathf.FloorToInt(current_power);
if (current_power > max_power)
{
StartCoroutine(Shoot());
}
}

void Recoil(float recoil)
{

}
private void Zero_current_power()
{
current_power = 0f;
PowerBar.fillAmount = current_power / max_power;
power.text = "Power:" + current_power;
}
//guideline aim
public static Vector3[] GetBallisticPath(Vector3 startPos, Vector3 forward, float velocity, float maxTime, float timeResolution)
{

Vector3[] positions = new Vector3[Mathf.CeilToInt(maxTime / timeResolution)];
Vector3 velVector = forward * velocity;
int index = 0;
Vector3 curPosition = startPos;
for (float t = 0.0f; t < maxTime; t += timeResolution)
{

if (index >= positions.Length)
break;//rounding error using certain values for maxTime and timeResolution

positions[index] = curPosition;
curPosition += velVector * timeResolution;
velVector += Physics.gravity * timeResolution;
index++;
}
return positions;
}
}
``````

if you want my “Bullet script” tell me
thanks a lot!

Don’t just plug my method in, understand what it does and how to use it.

it does all the calculations but it doesn’t trace the path, it returns an array of positions in the form of a vector3, use that and a line renderer(or whatever you like) to display the path.

i don’t know why would the bullet script should matter, the only force in effect should be gravity(the script may do the inital kick and the hit logic, but it doesn’t matter for what we’re talking about)

also, i just saw how your calling it, where you put the “1000f” is the time to simulate, your simulating over 15 minutes of bullet travel and each tick is what ever the delta time for the current frame

call it like so

``````GetBallisticPath(firePoint.position,firePoint.forward,current_power,10f ,.1f);
``````

simulate 10 seconds of bullet travel with each tick being 1/10 of a second.

what you did earlier is a sure fire way to lag the fuck out.

hey, first of all thank you for your help.

1. i have tried to turn your vector3 script to vector2 script by this:
``````public static Vector3[] GetBallisticPath(Vector2 startPos, Vector2 up, float velocity, float maxTime, float timeResolution)
{

Vector3[] positions = new Vector3[Mathf.CeilToInt(maxTime / timeResolution)];
Vector2 velVector = up * velocity * Time.deltaTime;
int index = 0;
Vector2 curPosition = startPos;
for (float t = 0.0f; t < maxTime; t += timeResolution)
{

if (index >= positions.Length)
break;//rounding error using certain values for maxTime and timeResolution

positions[index] = curPosition;
curPosition += velVector * timeResolution;
velVector += (Vector2)Physics.gravity * timeResolution;
index++;
}
return positions;
}
``````

correct me if i wrong
2. this is how i am fire a bullet:

``````GameObject newBullet =  Instantiate(bulletPrefab, firePoint.transform.position, firePoint.transform.rotation) as GameObject;
newBullet.GetComponent<Rigidbody2D>().velocity = current_power * firePoint.transform.up * Time.deltaTime;
``````
1. i tried this code in Update():
``````aim_positions = GetBallisticPath(firePoint.transform.position, firePoint.transform.up, 200f, 10f, .1f);
aim_line.SetPositions(aim_positions);
``````

*the “200f” is example of “current_power”
*firepoint.up is because iam in 2D
4. i create a LineRenderer as child of “firePoint”
4. thats what i get:

the line is show:

*** the first problem, is that i get the start position in wrong place.
** the second problem is that its not path the way correcly. mabe the calculate used Z axis that i dont have?? please any advise??

I’m sorry but i don’t know why your 2D version isn’t working properly, but you can just use the 3D one, your game maybe 2D but you still have the Z axis there.

one thing i can say besides that is i think you still need to use .forward and not .up even though your in 2D.

its work now. i used very similar method that you advised me. and i use a LineRenderer Component and most importatnt is to enable world space . here is the code:

``````IEnumerator DrawPath()
{
Vector2 velocityVector = firePoint.transform.up * initialVelocity * Time.fixedDeltaTime;
int max_time_res = (int)(maxTime / timeResolution);
lineRenderer.positionCount = max_time_res;
int index = 0;
Vector2 currentPos = firePoint.transform.position;
for (float t = 0.0f; t < maxTime; t += timeResolution)
{
if (index >= max_time_res) { break; }
lineRenderer.SetPosition(index, currentPos);
currentPos += velocityVector * timeResolution;
velocityVector += Physics2D.gravity * timeResolution;
index++;
}
yield return new WaitForSeconds(5f);
}
``````

its all work now. thanks a lot SparrowsNest !!!

next time i will need you for destructible terrain lol