Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Help finding Angle offset from target position for barrage/multiple arrow shots

Discussion in 'Scripting' started by Strom_CL, Oct 3, 2023.

  1. Strom_CL

    Strom_CL

    Joined:
    Nov 17, 2012
    Posts:
    84
    I'm working on figuring out how to add some additional arrows to my current single shot setup and I'm just not familiar enough with angles and quaternions and all that to finish this off and was hoping someone could help. Below is my thought process. I have player P shooting at target T currently, I instantiate the arrow then I do some initialization stuff on the arrow and it shoots at T along the red line, this works perfectly. I would like to instantiate two more arrows that are offset to the left and right of the initial arrow, these would be on the blue lines below

    Target Offset.png

    This is my code for instantiating the arrows, the barrage shot is the new code that has no offset currently, its just firing on the same path as the first arrow.

    Code (CSharp):
    1.  
    2.                        
    3. GameObject tmpProjectile = Instantiate(prefab, transform.position, Quaternion.identity);
    4. tmpProjectile.GetComponent<ProjectileScript>().initProjectile(closest.transform.position, this.gameObject);
    5.  
    6. if (barrageShot)
    7. {
    8.     GameObject tmpProjectile2 = Instantiate(prefab, transform.position, Quaternion.identity);
    9.     tmpProjectile2.GetComponent<ProjectileScript>().initProjectile(closest.transform.position, this.gameObject);
    10.     GameObject tmpProjectile3 = Instantiate(prefab, transform.position, Quaternion.identity);
    11.     tmpProjectile3.GetComponent<ProjectileScript>().initProjectile(closest.transform.position, this.gameObject);
    12.     barrageShot = false;
    13. }
    14.  
    And my code for when the arrow is instantiated:

    Code (CSharp):
    1.     public void initProjectile(Vector3 position, GameObject source)
    2.     {
    3.         transform.localScale *= size;
    4.  
    5.         dir = position - transform.position;
    6.         dir.y = 0;
    7.  
    8.         rb.velocity = dir.normalized * hSpeed;
    9.     }
    10.  
    I tried just adding a Vector3.one to the 2nd arrow, and subtracting a Vector3.one from the 3rd arrow and it looks like it works, but it gets weird based off how close or far I am from the target. Would appreciate any help getting this figured out.

    Thanks!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,283
    You can rotate any Vector3 by multiplying it with a Quaternion.

    For instance, Vector3.up is ... well, up.

    You could rotate it sideways by 25 degrees like so:

    Code (csharp):
    1. Vector3 original = Vector3.up;
    2.  
    3. Quaternion rotateBy25 = Quaternion.Euler( 0, 0, 25);
    4.  
    5. Vector3 tilted = rotateBy25 * original;
    Beware also of coding like this:

    Keep in mind that using GetComponent<T>() and its kin (in Children, in Parent, plural, etc) to try and tease out Components at runtime is definitely deep into super-duper-uber-crazy-Ninja advanced stuff.

    This sort of coding is to be avoided at all costs unless you know exactly what you are doing.

    If you run into an issue with any of these calls, start with the documentation to understand why.

    There is a clear set of extremely-well-defined conditions required for each of these calls to work, as well as definitions of what will and will not be returned.

    In the case of collections of Components, the order will NEVER be guaranteed, even if you happen to notice it is always in a particular order on your machine.

    It is ALWAYS better to go The Unity Way(tm) and make dedicated public fields and drag in the references you want.
     
  3. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    421
    Launch as many arrows as you want:

    Code (CSharp):
    1.     void LaunchProjectiles(int count)
    2.     {
    3.         for (int i=0;i<count;i++)
    4.         {  
    5.             float gapSize=5; // the amount of space between each projectile
    6.             Quaternion startRot=Quaternion.AngleAxis((-(gapSize*0.5f)*(count-1)+i*gapSize),Vector3.up);
    7.             GameObject obj=Instantiate(projectile,transform.position,startRot*transform.rotation);
    8.             obj.GetComponent<Rigidbody>().AddForce(obj.transform.forward*10,ForceMode.Impulse);
    9.             Destroy(obj,3);
    10.         }
    11.     }
     
  4. Strom_CL

    Strom_CL

    Joined:
    Nov 17, 2012
    Posts:
    84
    Works great for shooting out of the front of my character, I tried passing in a position for shooting at the mouse cursor (got direction from transform to mouse position) but I'm getting all three arrows stacked now, with no rotation. Is there an easy fix that? Thanks!
     
  5. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    421
    Is your view top down?. It sounds like you may be feeding it the wrong direction.
    Code (CSharp):
    1.     Vector3 mouseDirection=Input.mousePosition-new Vector3(Screen.width/2,Screen.height/2,0);
    2.     Vector3 direction=new Vector3(mouseDirection.x,0,mouseDirection.y);
     
  6. Strom_CL

    Strom_CL

    Joined:
    Nov 17, 2012
    Posts:
    84
    Its a 3d iso view like Soulstone Survivors.


    iso.png
     
    Last edited: Oct 4, 2023 at 6:54 AM
  7. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    421
    Code (CSharp):
    1.     void LaunchProjectiles(int count,Vector3 direction)
    2.     {
    3.         float gapSize=5; // the amount of space between each projectile
    4.         Quaternion midRot=Quaternion.LookRotation(direction,Vector3.up);
    5.         for (int i=0;i<count;i++)
    6.         {  
    7.             Quaternion startRot=Quaternion.AngleAxis((-(gapSize*0.5f)*(count-1)+i*gapSize),Vector3.up);
    8.             GameObject obj=Instantiate(projectile,transform.position,startRot*midRot);
    9.             obj.GetComponent<Rigidbody>().AddForce(obj.transform.forward*10,ForceMode.Impulse);
    10.             Destroy(obj,3);
    11.         }
    12.     }
     
    Strom_CL likes this.
  8. Strom_CL

    Strom_CL

    Joined:
    Nov 17, 2012
    Posts:
    84
    I think that's it! Everything's shooting at the cursor, has a nice spread and all. Not sure if its just because its midnight or movement but looks like rotation on the arrow is off a bit as it travels, but i'm probably just seeing things. :)

    @zulo3d Super appreciate the help with this, thanks!

     
    Nad_B and zulo3d like this.