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

Calling all math wizards.

Discussion in 'Scripting' started by Crawdad, Mar 24, 2021.

  1. Crawdad

    Crawdad

    Joined:
    Nov 23, 2016
    Posts:
    172
    Need some help with a script that isn't working as expected. I'm making a mistake in the math, but am not sure how to correct it. Trying to spread arced shots evenly along a spread, but they get clustered up on the positive side of rotation. Further comments in script. Help appreciated.
    Code (CSharp):
    1.     void SpreadShot()
    2.     {    
    3.         //launchpath is a vector3 calculated in another method.  It works correctly.
    4.         int spreadSplitNumber = 3;
    5.         Vector3 startPoint = transform.position;
    6.         float degreeStart = 70 / (spreadSplitNumber - 1);
    7.         float degreeShift = 35;
    8.         int splitCounter = 0;
    9.  
    10.         while (splitCounter < spreadSplitNumber)
    11.         {
    12.             thisPrefab = Instantiate(this.gameObject, startPoint, transform.rotation);
    13.             rb = thisPrefab.GetComponent<Rigidbody>();
    14.  
    15.             Quaternion rotation = transform.rotation * Quaternion.Euler(0, degreeShift, 0);
    16.  
    17.             //Attempting to rotate Vector3 launchPath so that it spreads out in an even spread.
    18.             //I suspect the problem is here.  Shots get clustered up on the positive side of rotation, not evenly from 35 degrees to -35.
    19.             launchPath = rotation * launchPath;
    20.  
    21.             rb.velocity = launchPath;
    22.  
    23.             degreeShift -= degreeStart; //incriments degree shift down according to spreadSplitNumber
    24.             splitCounter += 1;
    25.         }
    26.     }
    27.  
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,375
    If feel as if you're over complicating your code that makes reading your math difficult.

    Especially since you keep updating variables at the class scope rather than the method scope.

    From what I can get from your description... you want to shoot 3 projectiles in a 35deg spread in the direction you're facing (launchPath I assume is that facing direction).

    So lets rewrite this to use a for loop, and base our 3 spreads as the index of each step of the loop. Like so:
    Code (csharp):
    1.  
    2.     void SpreadShot()
    3.     {
    4.         //launchpath is a vector3 calculated in another method.  It works correctly.
    5.         int spreadSplitNumber = 5; //the number of spreads
    6.         Vector3 startPoint = transform.position; //start pos
    7.         float degreeShift = 35f; //the angle between each spread
    8.         float degreeStart = (degreeShift * (spreadSplitNumber - 1)) / 2f; //this would give you the clockwise 'start' position so that the spread would spread centered around launchPath
    9.  
    10.         for(int i = 0; i < spreadSplitNumber; i++)
    11.         {
    12.             var thisPrefab = Instantiate(prefab, startPoint, transform.rotation);
    13.             rb = thisPrefab.GetComponent<Rigidbody>();
    14.  
    15.             //just calculate our angle from degreeStart - the index we're at * degreeShift
    16.             Quaternion rotation = Quaternion.Euler(0f, degreeStart - degreeShift * i, 0f);
    17.             var path = rotation * launchPath;
    18.  
    19.             rb.velocity = path;
    20.         }
    21.     }
    22.  
     
    Last edited: Mar 24, 2021
    Crawdad and Kurt-Dekker like this.
  3. Crawdad

    Crawdad

    Joined:
    Nov 23, 2016
    Posts:
    172
    Thanks for the reply. Unfortunately, this gave me the same outcome. I inserted print(launchPath); right before rb.velocity = launchPath;, and you can see that two of the 3 launchPaths end up being the same.
    LaunchPaths.PNG
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,375
    I typeod my code when putting it in the browser (stupid browser)
    line 19 should be rb.velocity = path;

    I just edited my post to reflect that
     
    Crawdad likes this.
  5. Crawdad

    Crawdad

    Joined:
    Nov 23, 2016
    Posts:
    172
    That was the magic, right there! I was changing launchPath ever loop instead of using a separate variable. Even fixed my original script, though yours looks much nicer. Thanks for the help!