Unity shotgun making
Asked Answered
R

2

5

so I'm a bit new to C# with random math and I learned how to make a rifle, pistol, etc. But I want to learn how to make a shotgun with raycast, not with projectile. With raycast's I tired to do more then 1 raycast but didn't know how to make them random so now I'm just stuck with 1 raycast. I want to make a random spread when I shoot. Here is the script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ShotGun : MonoBehaviour {
    private int pellets = 9;

    private float spreadAngle = 10f;

    private float damage = 10f;

    private float range = 1000f;

    private Camera fpsCam;

    // Use this for initialization
    void Start () 
    {
    }

    // Update is called once per frame
    void Update () 
    {
        if (Input.GetButtonDown("Fire1"))
        {
            ShotgunRay();
        }

    }

    private void ShotgunRay()
    {
        RaycastHit hit;
        if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
        {
            Health_Armor target = hit.transform.GetComponent<Health_Armor>();

            if (target != null)
            {
                target.TakeDamage(damage);
            }
        }
    }
}
Rite answered 19/12, 2017 at 15:15 Comment(0)
M
3

Well this will be dependant on the gauge of the shotgun in question. I am going to suppose you have a 12 gauge shotgun, which normally has around 8 pellets. For this, you would need 8 separate raycasts, and 8 different "hit" objects. At approximately 25 yards, a standard 12 gauge shell will have spread roughly 40 inches in diameter, and its effective range (range before it slows down too much to hurt anything) is about 125 yards. This is not absolute, but it gives you a rough idea of what you're aiming for.

So, in pseudocode, I would create 8 raycasts, each with it's own respective "hit" object. All raycasts should have a length 114.3 units (unity uses meters as its unit of measurement, so 125 yards is 114.3 meters), then what you want to do is start every raycast at the center of the barrel and create a "random" rotation that would simulate a 40 inch (1.016 unity units) spread every 25 yards (or 22.86 unity units). You can achieve this by combining Random() with Quaternion.AngleAxis() until you get a good (realistic, but still very random) spread.

Also, I'd just like to point out. These values are based off of shooting a SLUG shell out of a rifled barrel. Using a rifled barrel with a slug gives the maximum amount of stopping power with a shotgun. So, you can consider these MAX values, with the MIN amount of weapon handling (as a slug can nearly blow your arm off). If, in your game, you want a plethora of shotguns and shells available for use, and you want the maximum level of realism, you will need to take into account if the current shell being shot is buckshot, birdshot, or a slug, and you also would need to take the type of barrel into account. Buck/birdshot may not be as effective at a farther range, but their handling is much improved.

Munro answered 19/12, 2017 at 15:30 Comment(0)
C
5

Multiple shots:

int amountOfProjectiles = 8;
if (Input.GetButtonDown("Fire1"))
    {
        for(int i = 0; i < amountOfProjectiles; i++)
        {
            ShotgunRay();
        }
    }

For the Randomness:

using Random = UnityEngine.Random;

Vector3 direction = fpsCam.transform.forward; // your initial aim.
Vector3 spread = Vector3.zero;
spread+= fpsCam.transform.up * Random.Range(-1f, 1f); // add random up or down (because random can get negative too)
spread+= fpsCam.transform.right * Random.Range(-1f, 1f); // add random left or right

// Using random up and right values will lead to a square spray pattern. If we normalize this vector, we'll get the spread direction, but as a circle.
// Since the radius is always 1 then (after normalization), we need another random call. 
direction += spread.normalized() * Random.Range(0f, 0.2f);

RaycastHit hit; if (Physics.Raycast(fpsCam.transform.position, direction, out hit, range)) { // etc...

To see your results, use Debug.DrawRay and DrawLine. We want to include the missed shots. (We draw for 1s, so it's easier to see)

if (Physics.Raycast(fpsCam.transform.position, direction, out hit, range))
{
    Debug.DrawLine(fpsCam.transform.position, hit.point, Color.green, 1f);
}
else
{
    Debug.DrawLine(fpsCam.transform.position, fpsCam.transform.position + direction * range, Color.red, 1f);
}

DrawLine draws (in case of hit) to the actual hitpoint in green. the missed shots get drawn in the length of range and in red.

Result: enter image description here

Crum answered 19/12, 2017 at 15:26 Comment(3)
Good answer and well commented, although there is no Mathf.Random method. Use Random.Range(-1f, 1f) instead.Manyplies
Thanks @ian I typed from memory, should have looked into the Docs :)Crum
i get a error in direction = fpsCam.transform.forward;Rite
M
3

Well this will be dependant on the gauge of the shotgun in question. I am going to suppose you have a 12 gauge shotgun, which normally has around 8 pellets. For this, you would need 8 separate raycasts, and 8 different "hit" objects. At approximately 25 yards, a standard 12 gauge shell will have spread roughly 40 inches in diameter, and its effective range (range before it slows down too much to hurt anything) is about 125 yards. This is not absolute, but it gives you a rough idea of what you're aiming for.

So, in pseudocode, I would create 8 raycasts, each with it's own respective "hit" object. All raycasts should have a length 114.3 units (unity uses meters as its unit of measurement, so 125 yards is 114.3 meters), then what you want to do is start every raycast at the center of the barrel and create a "random" rotation that would simulate a 40 inch (1.016 unity units) spread every 25 yards (or 22.86 unity units). You can achieve this by combining Random() with Quaternion.AngleAxis() until you get a good (realistic, but still very random) spread.

Also, I'd just like to point out. These values are based off of shooting a SLUG shell out of a rifled barrel. Using a rifled barrel with a slug gives the maximum amount of stopping power with a shotgun. So, you can consider these MAX values, with the MIN amount of weapon handling (as a slug can nearly blow your arm off). If, in your game, you want a plethora of shotguns and shells available for use, and you want the maximum level of realism, you will need to take into account if the current shell being shot is buckshot, birdshot, or a slug, and you also would need to take the type of barrel into account. Buck/birdshot may not be as effective at a farther range, but their handling is much improved.

Munro answered 19/12, 2017 at 15:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.