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 How to make gun accuracy

Discussion in '2D' started by deruderu_gamedev, Aug 2, 2021.

  1. deruderu_gamedev

    deruderu_gamedev

    Joined:
    Jul 1, 2021
    Posts:
    17
    Hello. Could you please teach me how to implement gun accuracy function like the one from nuclear throne? I want to make the bullet to slightly spread randomly instead of moving straight toward the point. Thanks

    This is the script for the bullet prefab btw.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Bullet : MonoBehaviour
    6. {
    7.     public float speed = 15f; // Bullet Speed
    8.     public float lifeTime; // Bullet Life Time
    9.     public GameObject destroyEffect; // Bullet Destroyed Effect
    10.  
    11.  
    12.     Rigidbody2D rb;
    13.  
    14.     private void Start()
    15.     {
    16.         rb = GetComponent<Rigidbody2D>();      
    17.     }
    18.  
    19.     private void FixedUpdate() // Bullet Movement Calculation
    20.     {
    21.         Vector2 movement = transform.right * speed;
    22.         rb.velocity = movement;
    23.     }
    24.  
    25.     void Awake() // Bullet Destroy Function
    26.     {
    27.         Destroy(this.gameObject, lifeTime);
    28.     }
    29.  
    30.     void OnCollisionEnter(Collision other) //Bullet Destroy When Collide
    31.     {
    32.         Destroy(gameObject);
    33.     }
    34. }
     
  2. TheNightglow

    TheNightglow

    Joined:
    Oct 1, 2018
    Posts:
    201
    the way I understand the code I assume you rotate the bullet first in the direction it is supposed to fly, and then let it fly straight to the right, correct?
    because of:
    Vector2 movement = transform.right * speed;

    in that case you simply want to rotate the bullet by a small random angle right after it spawns/ is rotated to the right direction (not sure how you spawn your bullet in right now since thats not part of the code you show)
    for a random angle, you can simply do something like
    float maxSpread = 5; //the 5 is just an example, could be anything >0 and <180
    Random.Range(-maxSpread, maxSpread)

    then you get a random angle between -5° and 5°
    then simply rotate the bullet by that angle
     
    deruderu_gamedev likes this.
  3. deruderu_gamedev

    deruderu_gamedev

    Joined:
    Jul 1, 2021
    Posts:
    17

    Thank you for the help, TheNightglow! And sorry for being late to reply.
    After implementing the line of code you suggested, the unity showed "error CS0103: The name 'Rnadom' does not exist in the current context". I am suppose to put the Random.Range(-maxSpread, maxSpread); in the void FixedUpdate, right? How could I fix this?

    And this is the bullet spawner script.
    Code (CSharp):
    1. public class BulletSpawner : MonoBehaviour
    2. {
    3.     public GameObject bulletPrefab;
    4.     public Transform shotPoint; // Bullet Spawner Position
    5.     public float fireRate;     // Bullet Fire Rate
    6.     float timeUntilNextShot;
    7.     public const int AMMO_MAX = 30; // Ammo Count
    8.     public static int ammo = AMMO_MAX;
    9.     private WeaponRecoil _weaponRecoil;
    10.     void Start()
    11.     {
    12.         _weaponRecoil = GetComponent<WeaponRecoil>();
    13.     }
    14.  
    15.     void Update() // Fire Input
    16.     {
    17.         if (Input.GetMouseButtonDown(0) && timeUntilNextShot < Time.time) // Fire Input Function
    18.         {
    19.             if (BulletSpawner.HasAmmo())
    20.             {
    21.                 _weaponRecoil.AddRecoil();
    22.                 Shoot();
    23.                 timeUntilNextShot = Time.time + fireRate; // Fire Rate Function
    24.             }
    25.         }
    26.         if (Input.GetKeyDown(KeyCode.R))
    27.         {
    28.             if (BulletSpawner.CanReload())
    29.             {
    30.                 BulletSpawner.ReloadAmmo();
    31.             }
    32.         }
    33.     }
    34.     void Shoot() // Bullet Spawner Rotation Calculation
    35.     {
    36.         Vector3 mousePos = Input.mousePosition;
    37.         mousePos.z = 5.23f;
    38.         Vector3 currentPos = Camera.main.WorldToScreenPoint(shotPoint.position);
    39.         mousePos.x = mousePos.x - currentPos.x;
    40.         mousePos.y = mousePos.y - currentPos.y;
    41.         float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
    42.         float spread = Random.Range(-10, 10);
    43.         Quaternion rotation = Quaternion.Euler(new Vector3(0f, 0f, angle));
    44.         Instantiate(bulletPrefab, shotPoint.position, rotation);
    45.         ammo--; // Ammo Consume
    46.     }
    47.     public static bool HasAmmo() // Ammo Works
    48.     {
    49.         return ammo > 0;
    50.     }
    51.     public static void ReloadAmmo() // Ammo Works
    52.     {
    53.         ammo = AMMO_MAX;
    54.     }
    55.     public static bool CanReload() // Ammo Works
    56.     {
    57.         return ammo < AMMO_MAX;
    58.     }
    59. }
     
  4. TheNightglow

    TheNightglow

    Joined:
    Oct 1, 2018
    Posts:
    201
    you need to import the UnityEngine library:
    in the very top, write:

    using UnityEngine;
     
  5. deruderu_gamedev

    deruderu_gamedev

    Joined:
    Jul 1, 2021
    Posts:
    17
    My apologies. I was making stupidest mistake ever. I wrote Rnadom instead of Random.
    Now the error dissapeared. But, still the bullet moving straight and not randomly spreadding. Do you have any idea why?
     
    Last edited: Aug 6, 2021
  6. TheNightglow

    TheNightglow

    Joined:
    Oct 1, 2018
    Posts:
    201
    well... u arent using the spread variable anywhere so far ;)

    Code (CSharp):
    1.         float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
    2.         float spread = Random.Range(-10, 10);
    3.         Quaternion rotation = Quaternion.Euler(new Vector3(0f, 0f, angle));
    4.         Instantiate(bulletPrefab, shotPoint.position, rotation);
    5.         ammo--; // Ammo Consume
    spread goes unused in the code above, try something like this:

    Code (CSharp):
    1.         float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
    2.         float spread = Random.Range(-10, 10);
    3.         angle += spread;
    4.         Quaternion rotation = Quaternion.Euler(new Vector3(0f, 0f, angle));
    5.         Instantiate(bulletPrefab, shotPoint.position, rotation);
    6.         ammo--; // Ammo Consume
     
    deruderu_gamedev likes this.