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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Firing bullet in 2D unsuccessful

Discussion in 'Scripting' started by Anon1234, Apr 29, 2015.

  1. Anon1234

    Anon1234

    Joined:
    Feb 17, 2014
    Posts:
    78
    I went on Googling on how to fire a bullet in 3D space, since firing one in 2D would be same, just with different coordinates. The script I found (original):
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class BulletItself : MonoBehaviour {  
    6.     //the object that will be spawned
    7.  
    8.     public GameObject bulletPrefab;
    9.  
    10.  
    11.  
    12.     // Use this for initialization
    13.     void Start () {
    14.      
    15.      
    16.      
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void Update () {
    21.      
    22.         if (Input.GetButtonDown("Fire1")){//when the left mouse button is clicked
    23.          
    24.             print ("1");//print a message to act as a debug
    25.          
    26.             FireBullet();//look for and use the fire bullet operation
    27.          
    28.         }
    29.     }
    30.  
    31.  
    32.  
    33.  
    34.     public void FireBullet(){
    35.      
    36.      
    37.      
    38.         //Clone of the bullet
    39.         GameObject Clone;
    40.      
    41.         //spawning the bullet at position
    42.         Clone = (Instantiate(bulletPrefab, transform.position,transform.rotation)) as GameObject;
    43.         Debug.Log ("Bullet is found");
    44.      
    45.      
    46.         //add force to the spawned objected
    47.         Clone.rigidbody.AddForce(1000,0,0);
    48.      
    49.         Debug.Log ("Force is added");
    50.      
    51.     }
    52.  
    53.  
    54.  
    55.  
    56.  
    57.  
    58.  
    59. }
    So I instantly tried to modify it and clean it up (remove comments and remove the unnecessary [Enter]'s).
    But then what I see in MonoDevelop is:
    Clone.rigidbody.AddForce(1000,0,0);
    "AddForce" creates an error, MonoDevelop says
    "UnityEngine.Component does not contain definition of `AddForce`.
    Tried to fix it, by:
    Clone.GetComponent<Rigidbody>.AddForce(1000,0,0);
    But the error I get from it is: "?", nothing else, just a funny question mark. So I went back to Unity, and it says:
    "Assets/Scripts/Player/BulletItself.cs(24,23): error CS0119: Expression denotes a `method group', where a `variable', `value' or `type' was expected". (24,23), points exactly to this line.

    And I'm so lost. Is there no easy way to do this? I'm not one of those that just copy, I copy, modify and learn, but heck, so many nice outdated too-specific JavaScript tutorials on how to do this, and not a single would be just "paste this script, put "Bullet" into slot, play with it until you learn, expand the code yourself".

    Back to the problem, how can I resolve it?
     
  2. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    AddForce takes a Vector3, not three integers.

    Code (CSharp):
    1. var rigidBody = clone.GetComponent<Rigidbody>();
    2. var force = new Vector3(100f,0f,0f);
    3.  
    4. rigidBody.AddForce(force);
    Familiarize yourself with this: http://docs.unity3d.com/ScriptReference/
    Very handy.
     
  3. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    GetComponent<Rigidbody>()

    you're missing the ()

    ben, there is an overload with x, y, z, (forcetype) as the parameters...
     
    BenZed likes this.
  4. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    BAHAH! I did not know this.
    I guess I should ALSO familiarize myself with the ScriptReference :p
     
  5. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,384
    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5.  
    6. public class BulletItself : MonoBehaviour
    7. {
    8.     public GameObject bulletPrefab;
    9.  
    10.     void Update()
    11.     {
    12.  
    13.         if (Input.GetButtonDown("Fire1"))
    14.         {
    15.             FireBullet();
    16.         }
    17.     }
    18.  
    19.     public void FireBullet()
    20.     {
    21.         GameObject newBullet = (GameObject)Instantiate(bulletPrefab, transform.position, transform.rotation);
    22.         newBullet.GetComponent<Rigidbody>().AddForce(Vector3.forward * 1000); // assuming you want forward..
    23.     }
    24. }
    25.  
    26.  
    You can no longer use a rigidbody directly by doing "someGameObject.rigidbody.AddForce(...)", you must access components by using "someGameObject.GetComponent<Rigidbody>()" where <Rigidbody> would be the component name you want to access, for instance a BoxCollider or something. The code you found is probably just a bit old.

    You may want to use a spawn point as well instead of "Instantiate(bulletPrefab, transform.position, transform.rotation)" so you might predefine a gameobject and reference it before the transform input there for position/rotation.

    Also, you'll probably want to do AddForce in a FixedUpdate method rather than just firing it one time at 1000 force...

    If you are using Visual Studio, turn on Code Completion and it will help a lot. Also check the scripting reference frequently as they typically have examples for things you want to do anyway.

    If you aren't using Visual Studio, then start using Visual Studio. :)
     
    Last edited: Apr 29, 2015
  6. Anon1234

    Anon1234

    Joined:
    Feb 17, 2014
    Posts:
    78
    I did nothing but just copied someone's script at tried to make it work, don't be like that :(

    There's actually no way of remembering them all and finding solution in there is quite hard, since you don't know what these errors mean, so you don't know where to find solution. Only I can do is Google first two pages of that error and attempt to find solution, in case it's not successful, I'm seeking help here :|

    MissingComponentException: There is no 'Rigidbody' attached to the "debullet(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)" game object, but a script is trying to access it.
    You probably need to add a Rigidbody to the game object "debullet(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)". Or your script needs to check if the component is attached before using it.
    UnityEngine.Rigidbody.AddForce (Vector3 force) (at C:/buildslave/unity/build/artifacts/generated/common/modules/NewDynamics.gen.cs:706)
    BulletItself.FireBullet () (at Assets/Scripts/Player/BulletItself.cs:15)
    BulletItself.Update () (at Assets/Scripts/Player/BulletItself.cs:9)

    Before you start shouting, yes, I attached default rigidbody to GameObject, yes, I attached default rigidbody to prefab (mainly by dragging GameObject into it's prefab), these messages grow exponentially (2^amount clicks).

    Message says
    "Or your script needs to check if the component is attached before using it."
    And I feel it has more to ask then Debug.Log(rigidbody == TRUE);

    Managed it get it to work, no errors, I can move, but, two strange things happen.

    First of all, performance drops ridiculously low, within 8 shots, FPS drops to, hmm, 5?
    Second of all, two bullets spawn in different directions, instead of going forward, they move little bit out of the ship, they form letter V instead of just one bullet forming a I.

    Probably performances issue, due to unlimited "Fires". I'll try to limit it.
    Unsuccessful:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class BulletItself : MonoBehaviour {
    5.     public GameObject bulletPrefab;
    6.     public bool allowedToShot = true;
    7.  
    8.     void Start() {
    9.     }
    10.     void Update() {
    11.         if (Input.GetButtonDown("Fire1")) {
    12.             FireBullet();
    13.         }
    14.         if (allowedToShot == false) {
    15.             new WaitForSeconds(3f);
    16.             allowedToShot = true;
    17.         }
    18.     }
    19.  
    20.     public void FireBullet() {
    21.         GameObject newBullet = (GameObject)Instantiate(bulletPrefab, transform.position, transform.rotation);
    22.         newBullet.GetComponent<Rigidbody2D>().AddForce(Vector2.right * 1000);
    23.         //newBullet = (Instantiate(bulletPrefab, transform.position+1.0*transform.forward,transform.rotation));
    24.         allowedToShot = false;
    25.     }
    26. }
    27.  
    28.  
    Tried to put it asleep, in case it just shoot the bullet. Bullets don't move, become big (same scale, visually bigger) and as soon as you release the left mouse button and you click again, every single bullet that you spawned, spawns it's bullet, so instead of just spawning two, you just spawn 2^(amount of bullets already spawned). Record is 20.000 bullets in 1 second.
     
  7. Anon1234

    Anon1234

    Joined:
    Feb 17, 2014
    Posts:
    78
    With everything I learned and found on the internet, I tried to craft more minimalistic one.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class BulletItself : MonoBehaviour {
    5.     public GameObject bulletPrefab;
    6.     public bool allowedToShot = true;
    7.     public double time;
    8.  
    9.     void Update() {
    10.         if (Input.GetButtonUp("Fire1")) {
    11.             FireBullet();
    12.         }
    13.     }
    14.  
    15.     void FireBullet() {
    16.         GameObject firedBullet = (GameObject)Instantiate(bulletPrefab, transform.position, transform.rotation);
    17.         Rigidbody2D Rigid = firedBullet.GetComponent<Rigidbody2D>();
    18.         Rigid.AddForce(new Vector2(5, 0));
    19.     }
    20. }
    21.  
    22.  
    Still same thing happens, if I keep left mouse button pressed it keeps spawning them and they don't move (both prefab and GameObject have their Rigidbody2D's attached. And clones also have rigidbody's. If you keep left mouse button pressed, they keep just spawning, if you release the mouse button, just twice as much spawn, and if you press left mouse button again, every single copy spawn their own bullets.
     
  8. Anon1234

    Anon1234

    Joined:
    Feb 17, 2014
    Posts:
    78
    I found a working way!
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class FireBullet : MonoBehaviour {
    5.     public GameObject Bullet;
    6.     public GameObject BulletPrefab;
    7.  
    8.     void Start () {
    9.    
    10.     }
    11.    
    12.     // Update is called once per frame
    13.     void Update () {
    14.         if (Input.GetMouseButton (0)) {
    15.             Vector2 originalPosition = new Vector2(Bullet.transform.position.x, Bullet.transform.position.y);
    16.            
    17.             Vector2 vec = new Vector2(0, 50);
    18.             Quaternion rot = Quaternion.Euler(0, 0, 0);
    19.             Vector2 rotVec = rot * vec;
    20.             // Random Angle and Random Distance, the Vector3 out of it.
    21.            
    22.             Vector2 newPos = (Vector2)this.transform.position + rotVec;
    23.             Debug.Log (newPos);
    24.         }
    25.     }
    26. }
    27.  
    But then I need it to tell Unity, to not copy the bullets anymore, except if it's from original bullet. The only issue now is, that it replicates every bullet fired, instead of just the original one, if you help me on this one. I'd be out in no time.