Search Unity

Can't get AddForce or Destroy to work

Discussion in 'Scripting' started by Aimlessone, Dec 31, 2015.

  1. Aimlessone

    Aimlessone

    Joined:
    Jun 26, 2015
    Posts:
    46
    I cannot seem for the life of me to get my laser shot to move forward with force once they are instantiated. They instantiate just fine, but sit there after that. Doesn't seem to be any errors in my code regarding the AddForce. I've tried moving that to the FixedUpdate function but same result.

    Additionally the destroy function doesn't work. I get 'Destroying assests is not permitted to avoid data loss, when I swap laserShot with gameObject it seems to destroy my script component after the lifetime and I can no longer shoot.

    Any Ideas?

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ShootLaser : MonoBehaviour {
    5.  
    6.     public GameObject laserShot;
    7.     public float laserSpeed;
    8.     public float lifetime = 1.0f;
    9.  
    10.  
    11.  
    12.     void Update()
    13.     {
    14.         if (Input.GetKeyDown (KeyCode.Mouse0))
    15.         {
    16.             Instantiate (laserShot, transform.position, transform.rotation);
    17.             laserShot.GetComponent<Rigidbody> ().AddForce (transform.forward * laserSpeed);
    18.             Destroy (laserShot, lifetime);
    19.  
    20.         }
    21.  
    22.     }
    23.  
    24. }
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    'laserShot' refers to the prefab - the copy that's sitting in your project file. That's why it errors out when you try to destroy it - it would be destroying your project file! (And naturally, the velocity for a thing that doesn't exist in the scene is fairly meaningless, hence why you don't see any effect of that.)

    The Instantiate function returns the in-scene copy that it creates. If you grab that, then you'll be able to control it:
    Code (csharp):
    1. GameObject spawnedCopy = (GameObject)Instantiate(laserShot, transform.position, transform.rotation);
    (The extra (GameObject) there is because Instantiate returns the type UnityEngine.Object; you have to typecast it to GameObject.)
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    One other note, if you're going to have your laser object be controlled by physics at all, you almost certainly want to set GetComponent<Rigidbody>().velocity directly, rather than via AddForce.

    As you become more familiar, you may also ditch the physics control of the laser altogether, and have the laser move itself - that way you won't get odd bugs like the laser bouncing off of objects and then spinning like a baton on its way out :)
     
  4. Aimlessone

    Aimlessone

    Joined:
    Jun 26, 2015
    Posts:
    46
    StarManta,

    Thanks for the reply! So I understand what is going on with the destroy function and calling to destroy lasershot is actually calling to destroy the prefab. That makes sense, what I still can't make sense of is why my lasershot still won't shoot forward.

    Here is my code as it stands now.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ShootLaser : MonoBehaviour {
    5.  
    6.     public GameObject laserShot;
    7.     public float laserSpeed;
    8.     public float lifetime = 1.0f;
    9.  
    10.  
    11.  
    12.  
    13.     void Update()
    14.     {
    15.         if (Input.GetKeyDown (KeyCode.Mouse0))
    16.         {
    17.            
    18.             GameObject spawnedCopy = (GameObject)Instantiate (laserShot, transform.position, transform.rotation);
    19.             laserShot.GetComponent<Rigidbody> ().AddForce (transform.forward * laserSpeed);
    20.  
    21.  
    22.  
    23.         }
    24.  
    25.     }
    26.  
    27. }
    I've skipped adding the destruction part for now. For some reason when I add the: Destroy (GameObject, lifetime) it destroys the ShootLaser script after the set lifetime. (which I don't understand the logic in that either)
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,336
    You're still trying to add force to the prefab, rather than the spawned copy.
     
  6. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Change the AddForce line to...
    Code (CSharp):
    1. spawnedCopy.GetComponent<Rigidbody> ().AddForce (transform.forward * laserSpeed);
     
  7. Aimlessone

    Aimlessone

    Joined:
    Jun 26, 2015
    Posts:
    46
    Baste, Thanks! Totally didn't see that. Script works as intended now. Thank you!
     
  8. Aimlessone

    Aimlessone

    Joined:
    Jun 26, 2015
    Posts:
    46
    Munchy,

    Thanks, saw that right before you posted. Staring at the same script for long periods of time apparently makes you miss simple things.
     
  9. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    We've all been there :)