Calling all math wizards.

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.

    void SpreadShot()
    {     
        //launchpath is a vector3 calculated in another method.  It works correctly.
        int spreadSplitNumber = 3;
        Vector3 startPoint = transform.position;
        float degreeStart = 70 / (spreadSplitNumber - 1);
        float degreeShift = 35;
        int splitCounter = 0;

        while (splitCounter < spreadSplitNumber)
        {
            thisPrefab = Instantiate(this.gameObject, startPoint, transform.rotation);
            rb = thisPrefab.GetComponent<Rigidbody>();

            Quaternion rotation = transform.rotation * Quaternion.Euler(0, degreeShift, 0);

            //Attempting to rotate Vector3 launchPath so that it spreads out in an even spread.
            //I suspect the problem is here.  Shots get clustered up on the positive side of rotation, not evenly from 35 degrees to -35.
            launchPath = rotation * launchPath;

            rb.velocity = launchPath;

            degreeShift -= degreeStart; //incriments degree shift down according to spreadSplitNumber
            splitCounter += 1;
        }
    }

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:

    void SpreadShot()
    {
        //launchpath is a vector3 calculated in another method.  It works correctly.
        int spreadSplitNumber = 5; //the number of spreads
        Vector3 startPoint = transform.position; //start pos
        float degreeShift = 35f; //the angle between each spread
        float degreeStart = (degreeShift * (spreadSplitNumber - 1)) / 2f; //this would give you the clockwise 'start' position so that the spread would spread centered around launchPath

        for(int i = 0; i < spreadSplitNumber; i++)
        {
            var thisPrefab = Instantiate(prefab, startPoint, transform.rotation);
            rb = thisPrefab.GetComponent<Rigidbody>();

            //just calculate our angle from degreeStart - the index we're at * degreeShift
            Quaternion rotation = Quaternion.Euler(0f, degreeStart - degreeShift * i, 0f);
            var path = rotation * launchPath;

            rb.velocity = path;
        }
    }
2 Likes

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.
6969794--821588--LaunchPaths.PNG

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

1 Like

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!