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

Resolved Bullet spread with raycasts

Discussion in 'Scripting' started by SpyderManToo, Feb 10, 2021.

  1. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    How do I add bullet spread when I'm using raycasts?

    heres my shooting script

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using TMPro;
    4. using System.Collections;
    5.  
    6. public class Gun : MonoBehaviour
    7. {
    8.     [Header("Choose Gun")]
    9.     public bool isRifle;
    10.     public bool isPistol;
    11.     public bool isSniper;
    12.  
    13.     [Header("Score")]
    14.     public ScoreCounter scoreCounter;
    15.     public float _shotsFired;
    16.     public float _shotsHit;
    17.  
    18.     [Header("Hitmakers and Damage")]
    19.     public Image hitmarkerImage;
    20.     public float hitmarkerWait;
    21.     public float damage = 10f;
    22.     public float range = 100f;
    23.  
    24.     [Header("Cooldowns, Ammo, Reloading")]
    25.     public float gunCooldown;
    26.     public int maxAmmo;
    27.     public float reloadTime;
    28.     public GameObject reloadText;
    29.     int currentAmmo;
    30.     float cooldown;
    31.     bool isReloading = false;
    32.     bool canShoot;
    33.  
    34.     [Header("Aiming References")]
    35.     public Transform rifle;
    36.     public Transform pistolHolder;
    37.     public Transform sniperHolder;
    38.  
    39.     public Transform rifleAimPos;
    40.     public Transform pistolAimPos;
    41.     public Transform sniperAimPos;
    42.  
    43.     public Transform rifleStore;
    44.     public Transform pistolHolderStore;
    45.     public Transform sniperHolderStore;
    46.  
    47.     bool isAiming;
    48.     public GameObject sniperModel;
    49.  
    50.     [Header("Miscellaneous")]
    51.     public ParticleSystem hitImpact;
    52.     public Animator animator;
    53.     public TMP_Text ammoCount;
    54.     public PlayerLook playerLook;
    55.  
    56.     public Camera fpsCam;
    57.  
    58.     public Color CLEARWHITE = new Color(1, 1, 1, 0);
    59.  
    60.     public Recoil recoilManager;
    61.  
    62.  
    63.  
    64.  
    65.     void Start()
    66.     {
    67.     hitmarkerImage.color = CLEARWHITE;
    68.  
    69.     currentAmmo = maxAmmo;
    70.     }
    71.  
    72.     void OnEnable()
    73.     {
    74.     isReloading = false;
    75.     animator.SetBool("Reloading", false);
    76.     }
    77.  
    78.     void Update()
    79.     {
    80.     BasicSetup();
    81.  
    82.     ChooseGun();
    83.  
    84.     Aim();
    85.  
    86.     HitmarkerSetup();
    87.  
    88.     ammoCount.text = currentAmmo + "/" + maxAmmo;
    89.  
    90.  
    91.     }
    92.  
    93.     IEnumerator Reload()
    94.     {
    95.     isReloading = true;
    96.     Debug.Log("Reloading");
    97.  
    98.     hitmarkerImage.color = CLEARWHITE;
    99.  
    100.     animator.SetBool("Reloading", true);
    101.  
    102.     yield return new WaitForSeconds(reloadTime - .1f);
    103.  
    104.     animator.SetBool("Reloading", false);
    105.  
    106.     yield return new WaitForSeconds(.1f);
    107.  
    108.     currentAmmo = maxAmmo;
    109.     isReloading = false;
    110.  
    111.     }
    112.  
    113.     void Shoot()
    114.     {
    115.     scoreCounter.shotsFired += 1;
    116.  
    117.        currentAmmo = currentAmmo - 1;
    118.  
    119.     RaycastHit hit;
    120.  
    121.     if(Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
    122.     {
    123.         Debug.Log("You hit " + hit.transform.name);
    124.         hitmarkerImage.color = Color.white;
    125.  
    126.         ParticleSystem hitImpactPrefab = Instantiate(hitImpact, hit.transform.position, hit.transform.rotation);
    127.  
    128.         Destroy(hitImpactPrefab.gameObject, 1f);
    129.      
    130.         scoreCounter.shotsHit += 1;
    131.  
    132.  
    133.  
    134.      
    135.     }
    136.     }
    137.  
    138.     void ChooseGun()
    139.     {
    140.     if(isRifle)
    141.     {
    142.             if(Input.GetButton("Fire1"))
    143.         {
    144.         if(cooldown <= 0)
    145.             {
    146.             if(canShoot)
    147.             {
    148.             cooldown = gunCooldown;
    149.             Shoot();
    150.             recoilManager.Fire();
    151.             }
    152.             }
    153.         }
    154.     }
    155.  
    156.     if(isSniper)
    157.     {
    158.         if(Input.GetButtonDown("Fire1"))
    159.         {
    160.         if(cooldown <= 0)
    161.             {
    162.             if(canShoot)
    163.             {
    164.             cooldown = gunCooldown;
    165.             Shoot();
    166.  
    167.             Debug.Log("Playing sniper animation");
    168.  
    169.             animator.SetBool("SniperShot", true);
    170.             }
    171.             }
    172.         }
    173.     }
    174.  
    175.     if(isPistol)
    176.     {
    177.         if(Input.GetButtonDown("Fire1"))
    178.         {
    179.         if(cooldown <= 0)
    180.             {
    181.             if(canShoot)
    182.             {
    183.             cooldown = gunCooldown;
    184.             Shoot();
    185.  
    186.             animator.SetBool("PistolShot", true);
    187.             }
    188.             }
    189.         }
    190.     }
    191.  
    192.     }
    193.  
    194.     void BasicSetup()
    195.     {
    196.     if((currentAmmo > 0) && !isReloading)
    197.         canShoot = true;
    198.  
    199.     if(isReloading)
    200.     {
    201.         reloadText.SetActive(true);
    202.         return;
    203.     }
    204.  
    205.     if(cooldown > 0)
    206.     {
    207.         canShoot = false;
    208.         cooldown -= Time.deltaTime;
    209.  
    210.         if(isPistol)
    211.         animator.SetBool("PistolShot", false);
    212.  
    213.         if(isSniper)
    214.          animator.SetBool("SniperShot", false);
    215.         canShoot = true;
    216.     }
    217.  
    218.     if(currentAmmo <= 0)
    219.       {
    220.         StartCoroutine(Reload());
    221.         return;
    222.     }
    223.  
    224.     if(Input.GetKeyDown(KeyCode.R) && currentAmmo < maxAmmo)
    225.     {
    226.         StartCoroutine(Reload());
    227.     }
    228.  
    229.     if(!isReloading && !isAiming)
    230.        {
    231.         rifle.position = Vector3.Lerp(rifle.position, rifleStore.position, 2.5f * Time.deltaTime);
    232.         pistolHolder.position = Vector3.Lerp(pistolHolder.position, pistolHolderStore.position, 2.5f * Time.deltaTime);
    233.         sniperHolder.position = Vector3.Lerp(sniperHolder.position, sniperHolderStore.position, 2.5f * Time.deltaTime);
    234.     }
    235.  
    236.     if(!isReloading && isAiming)
    237.     {
    238.         rifle.position = Vector3.Lerp(rifle.position, rifleAimPos.position, 2.5f * Time.deltaTime);
    239.         pistolHolder.position = Vector3.Lerp(pistolHolder.position, pistolAimPos.position, 2.5f * Time.deltaTime);
    240.         sniperHolder.position = Vector3.Lerp(sniperHolder.position, sniperAimPos.position, 2.5f * Time.deltaTime);
    241.     }
    242.  
    243.     if(isReloading)
    244.         reloadText.SetActive(true);
    245.  
    246.     if(!isReloading)
    247.     {
    248.         reloadText.SetActive(false);
    249.     }
    250.     }
    251.  
    252.     void HitmarkerSetup()
    253.     {
    254.     if(hitmarkerWait > 0)
    255.     {
    256.         hitmarkerWait -= Time.deltaTime;
    257.     }
    258.     else if(hitmarkerImage.color.a > 0)
    259.     {
    260.         hitmarkerImage.color = Color.Lerp(hitmarkerImage.color, CLEARWHITE,  Time.deltaTime * 10f);
    261.     }
    262.     }
    263.  
    264.     void Aim()
    265.     {
    266.     if(Input.GetMouseButtonDown(1))
    267.     {
    268.         if(isReloading)
    269.         AimOut();
    270.  
    271.         AimIn();
    272.     }
    273.     else if(Input.GetMouseButtonUp(1))
    274.     {
    275.         AimOut();
    276.     }
    277.     }
    278.  
    279.     void AimIn()
    280.     {
    281.     if(isSniper)
    282.     {
    283.         fpsCam.fieldOfView = 30f;
    284.         playerLook.mouseSensitivity = 30f;
    285.         sniperModel.SetActive(false);
    286.         sniperHolder.position = sniperAimPos.position;
    287.  
    288.         if(isReloading)
    289.         {
    290.         fpsCam.fieldOfView = 70f;
    291.         playerLook.mouseSensitivity = 100f;
    292.         rifle.position = rifleStore.position;
    293.         pistolHolder.position = pistolHolderStore.position;
    294.         sniperModel.SetActive(true);
    295.         sniperHolder.position = sniperHolderStore.position;
    296.          isAiming = false;
    297.         }
    298.     }
    299.     else
    300.     {
    301.         fpsCam.fieldOfView = 55f;
    302.         playerLook.mouseSensitivity = 50f;
    303.         rifle.position = rifleAimPos.position;
    304.          pistolHolder.position = pistolAimPos.position;
    305.     }
    306.  
    307.  
    308.     isAiming = true;
    309.     }
    310.  
    311.     void AimOut()
    312.     {
    313.     fpsCam.fieldOfView = 70f;
    314.     playerLook.mouseSensitivity = 100f;
    315.     rifle.position = rifleStore.position;
    316.     pistolHolder.position = pistolHolderStore.position;
    317.     sniperModel.SetActive(true);
    318.     sniperHolder.position = sniperHolderStore.position;
    319.      isAiming = false;
    320.     }
    321. }
    322.  

    can someone help
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    Don't think raycasts really enter into it... However you're calculating velocity or direction, calculate it multiple times by rotating it to slightly-different angles on either side of the bore zero.

    Code (csharp):
    1. // assuming Velocity already contains which way you're shooting:
    2.  
    3. // this will shoot seven shots total, 3 left, 3 right, one in the middle
    4. for (int leftright = -3; leftright <= 3; leftright++)
    5. {
    6.  Vector3 realDirection = Quaternion.Euler( 0, 0, leftright * AngleBetweenBullets);
    7.  
    8.  // TODO: shoot your shot using realDirection for motion
    9. }
     
  3. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    wait so i have that code surrounding my if statement for the raycast?
    also what do you mean by "Don't think raycasts really enter into it"
    im confused
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    Whether you are raycasting, drawing lines, sending objects flying in each bullet direction, that was what does not matter.

    Deriving the direction of spray, as the code snippet above, is what matters. It's a even "fan" of vector directions spreading out. What you do with it is up to you.