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

Monodevelop giving me annoying error

Discussion in 'Scripting' started by leapformula4, Dec 7, 2014.

  1. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    This is my code, it has a problem with the line that says:
    Code (CSharp):
    1. Rigidbody instantiatedProjectile = Instantiate (projectile, transform.position, transform.rotation) as Rigidbody;
    it keeps saying "Embedded statement cannot be a declaration or labeled statement"
    I am trying to make an empty object shoot a tank shell and this class is called FireShell.cs
    I am trying to make it shoot when I press space, and I can't bind space to Fire1. Either way the error won't let me run it in unity.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class FireShell : MonoBehaviour {
    5.     public Rigidbody projectile;
    6.     public float speed = 50;
    7.  
    8.     // Use this for initialization
    9.     void Start () {
    10.  
    11.     }
    12.  
    13.     // Update is called once per frame
    14.     void Update () {
    15.         if (Input.GetButtonDown ("Fire1"))
    16.         {
    17.             Rigidbody instantiatedProjectile = Instantiate (projectile, transform.position, transform.rotation) as Rigidbody;
    18.             instantiatedProjectile.velocity = transform.TransformDirection (new Vector3 (0, 0, speed));
    19.         }
    20.     }
    21. }
     
    Last edited: Dec 7, 2014
  2. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    Your code compiles fine for me.
     
  3. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    I'm a tad confused. Why are you instantiating a Ridgidbody and not an object?
     
  4. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    Hi guys. I just tried to fix my code and it works (Compiles). When I run the "game", the console continuously writes UnassignedReferenceException:
    The variable projectile of FireShell has not been assigned.
    You probably need to assign the projectile variable of the FireShell script in the inspector.

    I am working off of the tutorial here: http://forum.unity3d.com/threads/gun-shooting-script-c.222057/
    I finally kinda got it to fire the right way, but now I'm worrying about that exception. I'm guessing its bad as it might make my program slow or crash?

    @DRRosen3 It is rigidbody because the tutorial says to make it rigidbody. Also are you saying to make my tank shell an object? I mean the rigidbody has physics, I have not worked with objects yet so idk.
     
  5. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    OH!!! My script has a slot in the inspector for a rigidbody object!! That was what it was asking for, not the rigidbody that you attach to the empty game object to make it shoot. I guess they are both the same. It wont let me attach my rigidbody prefab to the slot!!! But the program runs find without it so what should I do??!!
    script.png
    The one above is an image of my script inspector. The one below is my gameobject that fires the projectile prefab. Both require a rigidbody, yet my script does not allow me to put one in, and complains that I have not set my rigidbody. By the way, my gameobject is inside of a cube.
    object.png
     
    Last edited: Dec 7, 2014
  6. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    One reason it might not let you attach it in the inspector, is because you can't modify a prefab directly. You have to first put the prefab into the scene. Modify it (in the scene) and then "Apply" the changes so they save to the original prefab.

    Secondly, what I meant by instantiating an object instead of a rigidbody, is this:

    Code (CSharp):
    1.   GameObject instantiatedProjectile = Instantiate (projectile, transform.position, transform.rotation) as GameObject;
    2.             instantiatedProjectile.rigidbody.velocity = transform.TransformDirection (new Vector3 (0, 0, speed));
    This works if the "projectile" is saved as a prefab object, with a rigidbody component attached to it.
     
  7. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    Well yes, my "projectile" (The part I am firing out of the square) is just: 1. empty prefab. 2. dragged my 3d tank shell model on top of the prefab icon. 3. applied rigidbody to prefab. 4. dragged the prefab onto my gameobject inspector's box where it asks for projectile.
    This fits in the box, but it doesn't fit in the other box in the script inspector. Please expand the images posted above, idk why it happens it asks for a rigidbody, clicking the circle won't let me add it.
     
  8. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    It asks for a rigidbody, because you specify in the script that the projectile prefab needs to be a rigidbody:
    Code (csharp):
    1. public Rigidbody projectile;
    If that is not required, you may instead use GameObject or Transform.

    Edit: If you want it to be a rigidbody, make sure that the actual prefab, meaning the file in the hierarchy, contains a rigidbody.
     
  9. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Yeah. I'm in agreement with @Dantus . That first line IMO should say "public GameObject projectile;".
     
  10. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Rigidbody is perfectly fine, just like any other type, as long as the actual prefab contains a component of that type. But my impression is that the prefab doesn't have a rigidbody which leads to the confusion.
     
  11. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    I changed it to GameObject, and am now trying to get the shells to destroy when they hit a sphere. Yes, the shells have mesh colliders and rigidbody attached, and my sphere has sphere collider and rigidbody. The shells are going straight through the sphere, coming out the other side, keep on going. IDK what I'm doing wrong. And it still complains that
    UnassignedReferenceException:
    The variable projectile of FireShell has not been assigned.
    You probably need to assign the projectile variable of the FireShell script in the inspector.

    Here is my complete code:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class FireShell : MonoBehaviour {
    5.     public GameObject projectile;
    6.     public float speed;
    7.  
    8.     // Use this for initialization
    9.     void Start () {
    10.  
    11.     }
    12.  
    13.     // Update is called once per frame
    14.     void Update () {
    15.         if (Input.GetButtonDown ("Fire1"))
    16.         {
    17.             Rigidbody instantiatedProjectile = Instantiate (projectile, transform.position, transform.rotation) as Rigidbody;
    18.             instantiatedProjectile.velocity = transform.TransformDirection (new Vector3 (0, 0, speed));
    19.         }
    20.     }
    21. }
    and

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DestroyShell : MonoBehaviour {
    5.     void OnCollisionEnter(Collision collision)
    6.     {
    7.         if(collision.transform.tag == "Sphere")
    8.         {
    9.             Destroy (collision.gameObject);
    10.         }
    11.     }
    12. }
    13.  
    I attached the 2nd script to my shell, the first one to my gameobject that fires the shells
     
  12. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Well what's happening is when the shell goes into the sphere it's destroying the sphere. The line that reads: "void OnCollisionEnter(Collision collision)"... Collision collision stores a reference to what the shell is colliding with, in this case the sphere.. So when you say: "Destroy(collision.gameObject);"...what you're saying is to destroy the sphere. If you want to destroy JUST the shell, then it should say: "Destroy(gameObject);". If you want to destroy both of them, then just add: "Destroy(gameObject);" after line 9.
     
  13. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    Code (csharp):
    1. Instantiate ( ... ) as Rigidbody;
    is going to be null.

    Because the instantiated GameIbject isn't a Rigidbody, it's a GameObject with a Rigibody component attached to it.

    Code (csharp):
    1. GameObject go = Instantiate(projectile) as GameObject;
    2.         go.rigidbody.velocity = ...whatever...
     
  14. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    That's completely false, even the scripting reference entry for Instantiate shows an example with a rigid body.
     
    Dantus likes this.
  15. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    Huh, what do you know? Okay, ignore what I said.
     
  16. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    this code doesn't work, and please, I asked about destroying the shell, not firing it.
    I appreciate the help, but I have this running well and I'd prefer to not change working things since they don't work afterwords.
     
  17. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    Just to elaborate my question is still not answered and I would be grateful If someone would look at my problem.
     
  18. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    For your UnassignedReferenceException is it possible that you accidentally have multiple instances of the script in your scene?

    Add some Debug calls and let us know if the collision is even occurring, and a Debug call in your firing script will let you know if there are multiple instances, as you'll see multiple debugs for a single shot.
     
  19. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    No, my shells don't move anymore, there is nothing I can do, I am about to give up lol. There are no scripts in my scene other than the one's attached to my tank gun and my cube ( I mean the empty gameobjects attached to those)
     
  20. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    ok. I tried to test if the next line was being executed (the one where it gives the shells velocity) and its not being executed. Actually I get an error at the line before that:
    NullReferenceException: Object reference not set to an instance of an object
    FireShell.Update () (at Assets/Scripts/FireShell.cs:18)

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class FireShell : MonoBehaviour {
    6.     public float speed;
    7.     public GameObject proj;
    8.     // Use this for initialization
    9.     void Start () {
    10.  
    11.     }
    12.  
    13.     // Update is called once per frame
    14.     void Update () {
    15.         if (Input.GetButtonDown ("Fire1"))
    16.         {
    17.             Rigidbody instantiatedProjectile = Instantiate (proj, transform.position, transform.rotation) as Rigidbody;
    18.             print ("Firing");
    19.             instantiatedProjectile.velocity = transform.TransformDirection (new Vector3 (0, 0, speed));
    20.             print ("moving");
    21.         }
    22.     }
    23. }
    and then it says:
    UnassignedReferenceException: The variable proj of FireShell has not been assigned.
    You probably need to assign the proj variable of the FireShell script in the inspector.

    And when I click this it points to my empty gameobject attached to my tank barrel. The name is highlighted in yellow, so idk whats wrong, I have set it to be shell prefab
     
    Last edited: Dec 9, 2014
  21. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    I see your problem, you made a change you forgot to revert.

    It should be
    Code (csharp):
    1. public Rigidbody projectile
    like in your original post. Not public GameObject.

    Don't forget to reassign the shell in the inspector after the code change.
     
  22. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    Thanks, my shells move now! I set up some more debug print(" ...."); statements in my other script, destroyshell, and it turns out it's not even being executed at all!

    what do I do?
     
  23. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    Where did you add the debug statements? If it was after the tag check, it could be possible that you forgot to tag your sphere as "Sphere". Do both objects have colliders? Is at least one of them not a mesh collider (mesh colliders cannot collide with other mesh colliders)?

    Your scripts work correctly as I tested them out last night to make sure.
     
  24. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    Yeah... my tank shell just hit my sphere and sent it flying. Its a collision and nothing is being destroyed!!!
     
  25. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    My destroy shell script is not executing. They are acting as colliders and everything seems to be working, but my script doesn't actually turn on.

    Actually it does. I do get one print statement that works, which says, In class (line 8). however, none of the later ones activate. To be specific, the next line, (line 9), the one that tests my collision, isn't turning on.
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class DestroyShell : MonoBehaviour {
    6.     void OnCollisionEnter(Collision col)
    7.     {
    8.         print ("in class");
    9.         if(col.gameObject.name == "Shell Prefab")
    10.         {
    11.             print ("in loop-hit");
    12.             Destroy (col.gameObject);
    13.             print ("destroyed");
    14.         }
    15.     }
    16. }
    17.  
    18.  
     
    Last edited: Dec 9, 2014
  26. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    Did you apply DRRosen3's change?

    I'll add this again too:
     
  27. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    umm, I dont get your question. Having removed the collision test loop, it destroys the tank shell. However, the collision test doesn't return true.

    I added my debug statements in my destroyshell class as I have inserted above.

    And Destroy(gameObject) doesn't work since the collision test isn't registering true. Right now as Destroy(col.gameObject) it works as intended but only when the collision test isn't there.
    Oh yeah, I forgot to say this was on my sphere.

    FYI this is my new script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DestroyShell : MonoBehaviour {
    5.     void OnCollisionEnter(Collision col)
    6.     {
    7.         print ("in class");
    8.         //if(col.gameObject.tag == "Shell Prefab")
    9.         //{
    10.             print ("in loop-hit");
    11.             Destroy (col.gameObject);
    12.             print ("destroyed");
    13.         //}
    14.         print ("exited class");
    15.     }
    16. }
    17.  
     
    Last edited: Dec 9, 2014
  28. leapformula4

    leapformula4

    Joined:
    Mar 26, 2014
    Posts:
    50
    So Thanks for all who helped, the collision detection doesn't work, I guess I'll move on to learning about character controller and creating a game next!
     
  29. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The collision detection doesn't work for very fast objects, unless you use continuous collision detection. The standard solution is to use raycasts.
     
  30. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    Since the collision is working as intended when you take out the check, you know the problem is in this line:
    Code (csharp):
    1. if(col.gameObject.tag == "Shell Prefab")
    Your shell isn't tagged "Shell Prefab". In case you didn't realize, tags and names are two different things.