Search Unity

Bullet Shooting Problems

Discussion in 'Scripting' started by Vampyr_Engel, Oct 28, 2018.

  1. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449
    The script I have actually works but my bullet drops out of the gun and the bullets don't come out of the gunhole How do I correct this? And the gun doesn't move in the orientation of the player, i.e it doesn't move with mouselook
     
    Last edited: Oct 28, 2018
  2. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449


    And as you can see the performance slows right down and I have a 12GB AMD Athlon II X 2 B28 3.40 GHz Processor running Windows 7 Pro 34 Bit with 1GB ATI Graphics Card
     
    Last edited: Oct 28, 2018
  3. Reeii

    Reeii

    Joined:
    Feb 5, 2016
    Posts:
    91
    The problem with the gunhole: Save the local position of the gunhole (in relation to the gun) in some variable. At bullet instantiation, set the bullet's position to the world position of the saved local gunhole position using Transform.TransformPoint().

    The orientation problem: Set the gun as a child of the camera.

    The performance problem: Instantiation is a veeeeryyyyy slow task. Search for "object pooling" on google or youtube.
     
  4. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449
    OK Thanks but where do I put this? I tell you what here is the script


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Shooting : MonoBehaviour
    5. {
    6.     public float bulletSpeed = 10;
    7.     public Rigidbody bullet;
    8.  
    9.  
    10.     void Fire()
    11.     {
    12.         Rigidbody bulletClone = (Rigidbody) Instantiate(bullet, transform.position, transform.rotation);
    13.         bulletClone.velocity = transform.forward * bulletSpeed;
    14.     }
    15.  
    16.     void Update ()
    17.     {
    18.         if (Input.GetButtonDown("Fire1"))
    19.             Fire();
    20.     }
    21. }
    22.  

    And how do I make the bullets disappear after a while or when they hit their target?
     
  5. Reeii

    Reeii

    Joined:
    Feb 5, 2016
    Posts:
    91
    Forget what I said about the gunhole problem, it can be solved easier:
    In the scene, create an empty game object, set is as a child of the gun and set its position in front of the gunhole. Reference the game object in the script and use its position as the instantiation position.

    And avoid setting the rigidbody velocity directly, better use AddForce().

    For bullet disappearing after a while, you can use a coroutine.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class Shooting : MonoBehaviour
    4. {
    5.     public float bulletSpeed = 10;
    6.     public float timeToDisappear = 5;
    7.     public Rigidbody bullet;
    8.     public Transform gunhole; // the empty game object's transform
    9.     void Fire()
    10.     {
    11.         Rigidbody bulletClone = (Rigidbody) Instantiate(bullet, gunhole.position, transform.rotation);
    12.         bulletClone.AddForce(transform.forward * bulletSpeed);
    13.         StartCoroutine(DisappearCoroutine(bulletClone.gameObject));
    14.     }
    15.     void Update ()
    16.     {
    17.         if (Input.GetButtonDown("Fire1"))
    18.             Fire();
    19.     }
    20.  
    21.     private IEnumerator DisappearCoroutine(GameObject bulletToDisappear) {
    22.         yield return new WaitForSeconds(timeToDisappear);
    23.         Destroy(bulletToDisappear);
    24.     }
    25. }
    26.  
    For disappearing after hitting a target, use OnTriggerEnter() or OnCollisionEnter():
    https://docs.unity3d.com/ScriptReference/Collider.OnTriggerEnter.html
    https://docs.unity3d.com/ScriptReference/Collider.OnCollisionEnter.html
     
  6. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449

    OK thank you managed to get the shooting working except one thing everytime I shoot after a few shots I am blasted off the planet by recoil and great balls full of bullets keep coming out How do I make it so only bullets on at a time come out but can still be useful for a assault rifle or machine gun and I stay on the planet when I shoot
    ?
     
  7. Reeii

    Reeii

    Joined:
    Feb 5, 2016
    Posts:
    91
    The recoil problem: Try to place the empty game object more in front of the gunhole so the bullet won't be instantiated with a part that's inside the gun.

    And do you mean a delay between shooting, so you can e.g. only shoot once per 1 second?
     
  8. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449
    OK thanks and yes that is what I mean I need fast shooting for a machine gun or assault rifle and automatic pistol and slower for a semi automatic pistol,, revolver, automatic crossbow and a Semi Automatic Sniper rifle and I want both player and A.I to be able to shoot and use similar weapons
     
  9. Reeii

    Reeii

    Joined:
    Feb 5, 2016
    Posts:
    91
    You could create a bool (mayShoot). You only shoot if it is set to true and after shooting you start a coroutine that sets the bool to false for a set amount o time (timeBetweenShots).

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class Shooting : MonoBehaviour
    4. {
    5.     public float bulletSpeed = 10;
    6.     public float timeToDisappear = 5;
    7.     public Rigidbody bullet;
    8.     public Transform gunhole; // the empty game object's transform
    9.     public float timeBetweenShots = 1;
    10.     private bool mayShoot = true;
    11.     void Fire()
    12.     {
    13.         if (mayShoot) {
    14.             Rigidbody bulletClone = (Rigidbody) Instantiate(bullet, gunhole.position, transform.rotation);
    15.             bulletClone.AddForce(transform.forward * bulletSpeed);
    16.             StartCoroutine(DisappearCoroutine(bulletClone.gameObject));
    17.             StartCoroutine(DisallowShooting());
    18.         }
    19.     }
    20.     void Update ()
    21.     {
    22.         if (Input.GetButton("Fire1"))
    23.             Fire();
    24.     }
    25.     private IEnumerator DisappearCoroutine(GameObject bulletToDisappear) {
    26.         yield return new WaitForSeconds(timeToDisappear);
    27.         Destroy(bulletToDisappear);
    28.     }
    29.     private Enumerator DisallowShooting() {
    30.         mayShoot = false;
    31.         yield return new WaitForSeconds(timeBetweenShots);
    32.         mayShoot = true;
    33.     }
    34. }
    And if you want to implement automatic weapons, I would change "Input.GetButtonDown()" to "Input.GetButton()", otherwise you have to click the mouse each time so shoot (doesn't make any sense with automatic weapons).

    Quick tip: Take a break and look up what coroutines in Unity are. They'll be useful in many more cases.
     
  10. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449
    OK thank you very much for your help
     
  11. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449
    Yes I know but bullets are all coming out at the same time I want them to come out one at a time can you help with this please?
     
  12. Reeii

    Reeii

    Joined:
    Feb 5, 2016
    Posts:
    91
    Did you implement the coroutine I posted? If yes, this shouldn't be the case. Can you post the whole script again?
     
  13. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449
    Yes I did even changed mayShoot to Shoot still getting the same problem



    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class Shooting : MonoBehaviour
    4. {
    5.     public float bulletSpeed = 10;
    6.     public float timeToDisappear = 5;
    7.     public Rigidbody bullet;
    8.     public Transform gunhole; // the empty game object's transform
    9.     public float timeBetweenShots = 1;
    10.     private bool Shoot = true;
    11.     void Fire()
    12.     {
    13.         if (Shoot) {
    14.             Rigidbody bulletClone = (Rigidbody) Instantiate(bullet, gunhole.position, transform.rotation);
    15.             bulletClone.AddForce(transform.forward * bulletSpeed);
    16.             StartCoroutine(DisappearCoroutine(bulletClone.gameObject));
    17.             StartCoroutine(DisallowShooting());
    18.         }
    19.     }
    20.     void Update ()
    21.     {
    22.         if (Input.GetButton("Fire1"))
    23.             Fire();
    24.     }
    25.     private IEnumerator DisappearCoroutine(GameObject bulletToDisappear) {
    26.         yield return new WaitForSeconds(timeToDisappear);
    27.         Destroy(bulletToDisappear);
    28.     }
    29.     private IEnumerator DisallowShooting() {
    30.         Shoot = false;
    31.         yield return new WaitForSeconds(timeBetweenShots);
    32.         Shoot = true;
    33.     }
    34. }
     
    Last edited: Oct 29, 2018
  14. Reeii

    Reeii

    Joined:
    Feb 5, 2016
    Posts:
    91
    That's weird. I just tested the exact same script (but instead of instantiating the bullet I just logged a message) and it works perfectly fine.

    Looking at the video you posted the bug is probably that your Bullet prefab contains your Shooting script. Hence you have multiple instances of the script that each have their own bool "Shoot". Attach your Shooting script to your gun and not the the bullet.
     
    Vampyr_Engel likes this.
  15. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449

    OK I will try that then thanks
     
  16. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449

    Well it kind of works as I don't get a million bullets coming out at once its all one at a time on each mouseclick although if I hold down the mouse I seem to get a machine gun efect but still not getting the bullets to shoot straight out that needs a bit of work

     
  17. Reeii

    Reeii

    Joined:
    Feb 5, 2016
    Posts:
    91
    For the "machine gun effect" as you call it: Use Input.GetButton() in the Update() method
    For no "machine gun effect": Use Input.GetButtonDown()

    You can set rigidbody constrains to freeze the bullet's rotation so they won't change it.
     
    Vampyr_Engel likes this.
  18. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449
    Thank you got to run more smoothly but I think I need to learn how to raycast it
     
  19. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449
    But it looks good for hovertanks though

     
  20. shawndingo

    shawndingo

    Joined:
    Oct 4, 2018
    Posts:
    83
    You need to adjust the gravity. Your bullets are floating away..
     
  21. Vampyr_Engel

    Vampyr_Engel

    Joined:
    Dec 17, 2014
    Posts:
    449
    Tried doing that even tried making the shells and bullets gravity bodies, turning on the usual gravity on and of withe gravity on the planet all to no avail i think I need to kno w how to use raycasts