Search Unity

Missle guideline (raycast)

Discussion in 'Scripting' started by maryuma888, Nov 3, 2018.

  1. maryuma888

    maryuma888

    Joined:
    Nov 2, 2018
    Posts:
    11
    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??
     
  2. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    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)

    Code (CSharp):
    1.     /// <summary>
    2.     /// Gets the ballistic path.
    3.     /// </summary>
    4.     /// <returns>The ballistic path.</returns>
    5.     /// <param name="startPos">Start position.</param>
    6.     /// <param name="forward">Forward direction.</param>
    7.     /// <param name="velocity">Velocity.</param>
    8.     /// <param name="maxTime">Total time to simulate.</param>
    9.     /// <param name="timeResolution">Time from frame to frame.</param>
    10.     public static Vector3[] GetBallisticPath(Vector3 startPos, Vector3 forward, float velocity, float maxTime, float timeResolution){
    11.  
    12.         Vector3[] positions = new Vector3[Mathf.CeilToInt(maxTime / timeResolution)];
    13.         Vector3 velVector = forward * velocity;
    14.         int index = 0;
    15.         Vector3 curPosition = startPos;
    16.         for (float t = 0.0f; t < maxTime; t += timeResolution) {
    17.            
    18.             if (index >= positions.Length)
    19.                 break;//rounding error using certain values for maxTime and timeResolution
    20.            
    21.             positions [index] = curPosition;
    22.             curPosition += velVector * timeResolution;
    23.             velVector += Physics.gravity * timeResolution;
    24.             index++;
    25.         }
    26.         return positions;
    27.     }
     
  3. maryuma888

    maryuma888

    Joined:
    Nov 2, 2018
    Posts:
    11
    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:
    Code (CSharp):
    1. public class Weapon : MonoBehaviour {
    2.     public Rigidbody2D player_rb;
    3.     private float rotate_speed = 1f;
    4.     public Transform firePoint;
    5.     public GameObject bulletPrefab;
    6.     public Text rotate;
    7.     private int rotate_int;
    8.     private float cannon_move = 0f;
    9.     public float force;
    10.     //power_bar
    11.     public Image PowerBar;
    12.     public Text power;
    13.     public float current_power = 0;
    14.     public float max_power = 1000f;
    15.     public float recoil;
    16.  
    17.  
    18.     void Start()
    19.     {
    20.         PowerBar.fillAmount = current_power / max_power;
    21.     }
    22.     void Update () {
    23.         cannon_move = Input.GetAxisRaw("Vertical") * rotate_speed;
    24.         rotate_int = (Mathf.FloorToInt(firePoint.transform.eulerAngles.z));
    25.         rotate.text = rotate_int.ToString();
    26.         if (Input.GetButton("Fire_Bar"))
    27.         {
    28.             Power();
    29.         }
    30.         if (Input.GetButtonUp("Fire_Bar")) //realse button
    31.         {
    32.             StartCoroutine(Shoot());
    33.         }
    34.         //guideline aim
    35.         GetBallisticPath(firePoint.position,firePoint.forward,current_power,1000f,Time.deltaTime);
    36.     }
    37.     void FixedUpdate()
    38.     {
    39.         firePoint.Rotate(0, 0, cannon_move);
    40.     }
    41.     IEnumerator Shoot()
    42.     {
    43.         Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
    44.         yield return new WaitForSeconds(0.02f);
    45.         Zero_current_power();
    46.         Recoil(recoil);
    47.     }
    48.     void Power()
    49.     {
    50.         current_power += 250 * Time.deltaTime;
    51.         PowerBar.fillAmount = current_power / max_power;
    52.         power.text = "Power:" + Mathf.FloorToInt(current_power);
    53.         if (current_power > max_power)
    54.         {
    55.             StartCoroutine(Shoot());
    56.         }
    57.     }
    58.  
    59.     void Recoil(float recoil)
    60.     {
    61.      
    62.     }
    63.     private void Zero_current_power()
    64.     {
    65.         current_power = 0f;
    66.         PowerBar.fillAmount = current_power / max_power;
    67.         power.text = "Power:" + current_power;
    68.     }
    69.     //guideline aim
    70.     public static Vector3[] GetBallisticPath(Vector3 startPos, Vector3 forward, float velocity, float maxTime, float timeResolution)
    71.     {
    72.  
    73.         Vector3[] positions = new Vector3[Mathf.CeilToInt(maxTime / timeResolution)];
    74.         Vector3 velVector = forward * velocity;
    75.         int index = 0;
    76.         Vector3 curPosition = startPos;
    77.         for (float t = 0.0f; t < maxTime; t += timeResolution)
    78.         {
    79.  
    80.             if (index >= positions.Length)
    81.                 break;//rounding error using certain values for maxTime and timeResolution
    82.  
    83.             positions[index] = curPosition;
    84.             curPosition += velVector * timeResolution;
    85.             velVector += Physics.gravity * timeResolution;
    86.             index++;
    87.         }
    88.         return positions;
    89.     }
    90. }
    if you want my "Bullet script" tell me
    thanks a lot!
     
  4. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    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)
     
  5. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    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
    Code (CSharp):
    1. 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 F*** out.
     
  6. maryuma888

    maryuma888

    Joined:
    Nov 2, 2018
    Posts:
    11
    hey, first of all thank you for your help.

    1. i have tried to turn your vector3 script to vector2 script by this:
    Code (CSharp):
    1. public static Vector3[] GetBallisticPath(Vector2 startPos, Vector2 up, float velocity, float maxTime, float timeResolution)
    2.     {
    3.  
    4.         Vector3[] positions = new Vector3[Mathf.CeilToInt(maxTime / timeResolution)];
    5.         Vector2 velVector = up * velocity * Time.deltaTime;
    6.         int index = 0;
    7.         Vector2 curPosition = startPos;
    8.         for (float t = 0.0f; t < maxTime; t += timeResolution)
    9.         {
    10.  
    11.             if (index >= positions.Length)
    12.                 break;//rounding error using certain values for maxTime and timeResolution
    13.  
    14.             positions[index] = curPosition;
    15.             curPosition += velVector * timeResolution;
    16.             velVector += (Vector2)Physics.gravity * timeResolution;
    17.             index++;
    18.         }
    19.         return positions;
    20.     }
    correct me if i wrong
    2. this is how i am fire a bullet:
    Code (CSharp):
    1. GameObject newBullet =  Instantiate(bulletPrefab, firePoint.transform.position, firePoint.transform.rotation) as GameObject;
    2. newBullet.GetComponent<Rigidbody2D>().velocity = current_power * firePoint.transform.up * Time.deltaTime;
    3. i tried this code in Update():
    Code (CSharp):
    1. aim_positions = GetBallisticPath(firePoint.transform.position, firePoint.transform.up, 200f, 10f, .1f);
    2. 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:
    upload_2018-11-9_21-10-53.png
    the line is show:
    upload_2018-11-9_21-12-2.png

    *** 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??
     

    Attached Files:

  7. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    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.
     
  8. maryuma888

    maryuma888

    Joined:
    Nov 2, 2018
    Posts:
    11
    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:
    Code (CSharp):
    1. IEnumerator DrawPath()
    2.     {
    3.         Vector2 velocityVector = firePoint.transform.up * initialVelocity * Time.fixedDeltaTime;
    4.         int max_time_res = (int)(maxTime / timeResolution);
    5.         lineRenderer.positionCount = max_time_res;
    6.         int index = 0;
    7.         Vector2 currentPos = firePoint.transform.position;
    8.         for (float t = 0.0f; t < maxTime; t += timeResolution)
    9.         {
    10.             if (index >= max_time_res) { break; }
    11.             lineRenderer.SetPosition(index, currentPos);
    12.             currentPos += velocityVector * timeResolution;
    13.             velocityVector += Physics2D.gravity * timeResolution;
    14.             index++;
    15.         }
    16.         yield return new WaitForSeconds(5f);
    17.     }
    upload_2018-11-10_15-17-46.png



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

    next time i will need you for destructible terrain lol