-1

Boxcast

The image above shows a boxcast, for what im trying to achieve this wont work. Essentially what would be best is to cast a half sphere or a a quarter sphere like I drew on top of the boxcast screenshot.

Im trying to make a system for the cannons to aim at enemies and shoot them, but the cannons on the right side of the ship should never try to target enemies on the left side of the ship, hence i figured this is a reasonable approach: boxcast a single side and go from there.

Alas, the boxcast is extremely limited for this problem as enemies can easily be outside the box, but still on the right side of the ship.

Is there a better way to do this? The boxcast is also limited in that you can only set 2 dimensions, its cubic size and then its length. I dont think I can use a SphereCast because that would also target enemies of the left side. Or is there a way to determine which enemies are in front, which are on the right, which are behind and which are to the left, and put those in Lists (rightEnemiesList, frontEnemiesList, leftEnemiesList, backEnemisList)?

How do i solve this? I dont want to be using 50 line raycasts on each side either, for performance reasons. Not to mention im actually calculating 4 sides, so we have cannons on each side but also on the front and back of the ship to shoot forwards and backwards.

The code for the boxcast, although it doesnt add much to this question:

        var half = ship.mainGunCaliber.range * .5f;
    var rotationY = hullParent.localEulerAngles;
    rotationY = new Vector3(0, rotationY.y, 0);
    Quaternion boxRot = Quaternion.Euler(rotationY);
    RaycastHit[] hits = Physics.BoxCastAll(hullParent.transform.position + hullParent.transform.right,
                                           Vector3.one * ship.length,
                                           hullParent.transform.right,
                                           boxRot,
                                           half);

Thank you!

Mad Hatter
  • 85
  • 9
  • It depends on the motion of the enemies how efficient this would be, but you could measure the angle from the `ship.transform.forward` to filter which side they're on, then filter on specific x/y/z positions relative to the `ship`'s local position and length/width/height. That should be enough info to sort enemies into lists for front/back/left/right. – Daevin Sep 13 '22 at 20:17
  • Could you explain how to do that? `foreach (Transform t in enemyTargets) { // LINQ call to find targets within 60degree angle of ship.transform.forward? }` – Mad Hatter Sep 13 '22 at 20:41
  • I can't give concrete code, I don't have access to Unity right now, but look into [`Vector3.SignedAngle`](https://docs.unity3d.com/ScriptReference/Vector3.SignedAngle.html). In this case, I think the `from` and `axis` vectors would both be `ship.transform.forward`, but I'm not positive so try play around with it a bit. Also, in case you were unaware, there's a [Game Development SE site](https://gamedev.stackexchange.com/); your game dev-related questions might get better traction there. – Daevin Sep 13 '22 at 20:54
  • Correction to what I said about the `from` and `axis` vectors: the `from` vector would be `ship.transform.forward`, the `axis` vector would be `ship.transform.up`. – Daevin Sep 13 '22 at 21:02

1 Answers1

0

Thanks to Daevin for pointing me in the right direction! This is what I got so far, it will add an enemy to the right List according to which direction they are in relation to our ship. Its not perfect because the angle is calculated from the center of the ship, which gives some weird results if the targets get too close. Also I have a feeling this isnt the most optimized way to do it, so Please if you have a better way tell us!

foreach (Transform target in enemyTargets)
        {

            if (Vector3.Distance(transform.position, target.position) > ship.mainGunCaliber.range)
                continue;

            Vector3 toTarget = target.position - transform.position;
            print(Vector3.SignedAngle(transform.forward, toTarget, Vector3.up));

            if (Vector3.SignedAngle(transform.forward, toTarget, Vector3.up) >= bowMinAngle &&
                Vector3.SignedAngle(transform.forward, toTarget, Vector3.up) <= bowMaxAngle)
            {
                if (!bowTargets.Contains(target))
                {
                    RemoveFromOthers(target);
                    bowTargets.Add(target);
                    print("added target to Bow");
                }
            }
            if (Vector3.SignedAngle(transform.forward, toTarget, Vector3.up) >= sbMinAngle &&
                Vector3.SignedAngle(transform.forward, toTarget, Vector3.up) <= sbMaxAngle)
            {
                if (!sbTargets.Contains(target))
                {
                    RemoveFromOthers(target);
                    sbTargets.Add(target);
                    print("added target to SB");

                }
            }
            if (Vector3.SignedAngle(-transform.forward, toTarget, Vector3.up) >= aftMinAngle &&
                Vector3.SignedAngle(-transform.forward, toTarget, Vector3.up) <= aftMaxAngle)
            {
                if (!aftTargets.Contains(target))
                {
                    RemoveFromOthers(target);
                    aftTargets.Add(target);
                    print("added target to Aft");

                }
            }
            if (Vector3.SignedAngle(transform.forward, toTarget, Vector3.up) >= psMinAngle &&
                Vector3.SignedAngle(transform.forward, toTarget, Vector3.up) <= psMaxAngle)
            {
                if (!psTargets.Contains(target))
                {
                    RemoveFromOthers(target);
                    psTargets.Add(target);
                    print("added target to PS");

                }
            }
Mad Hatter
  • 85
  • 9