• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Nexus2911 · Aug 05, 2014 at 02:40 AM · rigidbody2dinstantiate prefab

Cannot Access Rigidbody2D on Instantiated Prefab

I cannot access any rigidbody2d on my instantiated prefab (vehicle).

When I spawn my vehicle, it appears and moves just as it should.

The prefab contains VehicleController.cs which is not only responsble for movement but for also assembling elements such as joints and rigid bodies. Here's the excerpt which adds the rigid bodies to the wheels(only relevant code shown):

 public class VehicleController : MonoBehaviour {
     
     public float speed;
     public float aceleration = 0.15f; // Vehicle acceleration amount.
     public float breakForce = 0.1f; // Amount of vehicle braking force.
     
     public GameObject[] wheels = new GameObject[2]; // Array with all the wheels from the vehicle.
     public Wheel_Options wheelOptions; // Parameters for the WheelJoint2D.
     public LayerMask whatIsGround; // LayerMask that contain ground layers.
     //private GameObject whatIsGround;
     private bool grounded; // Show if the vehicle is on the ground.
     
     public int coinsCollected;
     public AudioClip coinCollectSound;
 
     private bool accel;
     
     void Start () {
 
         DataManager.control.Load (); 
     
         coinsCollected = DataManager.control.coins;
         
         speed = DataManager.control.engine;
 
         for (int i = 0; i < wheels.Length; i++) {
             // Verify if all the wheels are assigned
             if(wheels[i] == null){
                 wheels = new GameObject[0];
                 Debug.Log("Wheel not assigned.");
                 return;
             }
             // Verify if all the wheels has a CircleCollider2D
             else if (wheels[i].GetComponent<CircleCollider2D>() == null){
                 wheels = new GameObject[0];
                 Debug.Log("Circle collider no assigned to the wheel.");
                 return;
             }else{
                 //wheels[i].GetComponent<CircleCollider2D>().sharedMaterial = groundMat;
                 addWheelJoint2D(i);
             }
         }
     
     }
 
 
     // Add a WheelJoint2D to the wheel contained in the array in a specific position
     public void addWheelJoint2D(int wheelPosition){
 
         // Add the WheelJoint2D component to the wheel
         WheelJoint2D wheelJoint = gameObject.AddComponent("WheelJoint2D") as WheelJoint2D;
         // Verify if the wheel has a rigidbody2D.
         if(!wheels[wheelPosition].rigidbody2D)
             // Add a rigidbody2D to the wheel.
             wheels[wheelPosition].AddComponent("Rigidbody2D"); 
         
         // Set the rigidbody2D of the car to the wheelJoint2D
         wheelJoint.connectedBody = wheels[wheelPosition].rigidbody2D;
         // Create a new JointSuspension2D and set the variables to get a cool and real suspension
         JointSuspension2D suspension = new JointSuspension2D();

        ... // Removed for readability


         wheels [wheelPosition].GetComponent<Rigidbody2D> ().gravityScale = wheelOptions.gravityScale;
     }
 
 .. // Removed for readability.  Verified that script does successfully add rigidBody2D
 }

     

VehicleSpawner.cs:

 public class VehicleSpawner : MonoBehaviour {
 
     private GameObject selectedVehicle;
 
     // Use this for initialization
     void Start () {
 
         DataManager.control.Load ();
 
         selectedVehicle = DataManager.control.selectedVehicle;
         Instantiate(selectedVehicle,new Vector3(-20,2,0),Quaternion.identity);
 
         Debug.Log (selectedVehicle.rigidbody2D);
         Debug.Log (selectedVehicle.GetComponent<VehicleController>().wheels[1].rigidbody2D);
         // Both debug statements return null
 
         
     }
     
 
 }

As noted by the two debug statements, any attempt to access rigidbody2D returns null.

I need access to the rigid bodies for my CameraFollow script:

 public class CameraFollow : MonoBehaviour {
 
     private Transform target;
     public Vector3 offset;
     public float minZoom = 8.0f;
     public float maxZoom = 12.0f;
 
     void Awake (){
 
         camera.orthographicSize = minZoom;
 
     }
 
     void Start (){
 
         DataManager.control.Load ();
 
     }
 
     void FixedUpdate () {
 
         target = DataManager.control.selectedVehicle.transform;
 
         Vector3 pre;
         pre = target.transform.position;
         pre = new Vector3(pre.x,pre.y,-10);
         transform.position = pre + offset;
 
         camera.orthographicSize = Mathf.Lerp(camera.orthographicSize, 5 + Mathf.Abs(target.rigidbody2D.velocity.x / 2), Time.deltaTime);
 
     }
 }











Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by cascaid · Aug 05, 2014 at 07:16 AM

One issue: You're instantiating "selectedVehicle", but then calling .rigidbody2D on the prefab, not the instantiated object. The way to fix this is to assign the result of Instantiate to a variable:

 selectedVehicle = DataManager.control.selectedVehicle;
 GameObject newVehicle = (GameObject)Instantiate(selectedVehicle,new Vector3(-20,2,0),Quaternion.identity);
 Debug.Log (newVehicle.rigidbody2D);

The script you show only mentions adding rigidbodies to the wheels, not the vehicle itself, and I can't tell if/when that method is being called, so I'm afraid I can't offer much help on that.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Nexus2911 · Aug 05, 2014 at 07:29 AM 0
Share

@cascaid Thank you for your response.

I tried your code but debug still returns null.

Because the RigidBody2D is being added to the wheels I also tried:

 Debug.Log (newVehicle.GetComponent<VehicleController>().wheels[1].rigidbody2D);

Still null.

I've updated my question to show the full VehicleController script that will show you when that method for adding rigid bodies is being called.

Brief history: Incidentally, prior to all this instantiation business, when the prefab was manually added to the scene, the camera script could access the rigid body just fine using

target.rigidbody2d

even though I didn't target the wheels in that line...not sure how that worked but just an interesting note. So in this case, the CameraFollow script had a public field (target) in the inspector in which i just dragged and dropped the vehicle. That being said, I still want to stick with instantiation.

avatar image cascaid · Aug 05, 2014 at 08:40 AM 0
Share

The Start() method you are using to setup your object has not necessarily been run at this point, see: http://docs.unity3d.com/ScriptReference/$$anonymous$$onoBehaviour.Start.html

Awake() is a better place for setting up your object when it doesn't rely on external connections/states, which should apply in this case.

avatar image Nexus2911 · Aug 05, 2014 at 08:02 PM 0
Share

There's light at the end of the tunnel but still having issues. @cascaid - yes, placing some items in Awake() versus Start() did help.

In my VehicleSpawn script:

     selectedVehicle = Data$$anonymous$$anager.control.selectedVehicle;

     vechicle = (GameObject)Instantiate(selectedVehicle,new Vector3(-20,2,0),Quaternion.identity);
     Debug.Log (vechicle.rigidbody2D);

Debug returns the rigidbody2D. However, I still need to access that rigid body in my camera script. How do I do that without reinitializing the vehicle? I'd like to avoid merging the spawn and camera follow script if possible.

CameraFollow script:

   void FixedUpdate () {
     
             target = Data$$anonymous$$anager.control.selectedVehicle.transform;
     
             Vector3 pre;
             pre = target.transform.position;
             pre = new Vector3(pre.x,pre.y,-10);
             transform.position = pre + offset;
     
             camera.orthographicSize = $$anonymous$$athf.Lerp(camera.orthographicSize, 5 + $$anonymous$$athf.Abs(target.rigidbody2D.velocity.x / 2), Time.deltaTime);

avatar image Nexus2911 · Aug 06, 2014 at 08:26 PM 0
Share

Ok so, any attempt to access the the rigidbody2d outside the script in which the vehicle was instantiated will fail.

All I really need is the velocity of the rigidbody2D.

I've even tried creating a public method in the VehicleController script

 public float GetVelocity () {  // For CameraFollow script
         return rigidbody2D.velocity.x; 
     }


to return the the velocity.x of the rigidbody

Tried to access that method in my CameraFollow class:

 GameObject target = Data$$anonymous$$anager.control.selectedVehicle;
         float velX = target.GetComponent<VehicleController>().GetVelocity();

I still get "no RigidBody2D attached to "$$anonymous$$yVehicle".

I realize this is most likely due to what @cascaid was saying about assigning the instantiation. So I'm back to my second question - how do I access the rigidbody or at least the velocity of the rigid body without instantiating the prefab a second time?

avatar image cascaid · Aug 06, 2014 at 08:45 PM 0
Share

Argh, I wrote agreat big response, and managed to put it in the wrong box, so here's the short answer:

When you instantiate, it makes a copy of your prefab, therefore the item you can getting from your datamanager is a different instance of your vehicle to the one now called newVehicle.

The easiest way to add this to your camera, assu$$anonymous$$g you have the CameraFollow script on your scenes main camera, and it starts off disabled (untick the checkbox on the script) would be the following:

 selectedVehicle = Data$$anonymous$$anager.control.selectedVehicle;
 GameObject newVehicle = (GameObject)Instantiate(selectedVehicle,new Vector3(-20,2,0),Quaternion.identity);
 
 CameraFollow cameraScript = Camera.main.GetComponent<CameraFollow>();
 cameraScript.target = newVehicle.transform;
 cameraScript.enabled = true;
Show more comments
avatar image
0

Answer by Nexus2911 · Aug 06, 2014 at 11:01 PM

I didn't see an option to mark a comment as an answer. So based on @cascaid's input here's the answer.

I'm still using my VehicleSpawn script and I've placed that script onto a an empty game object. I've added a public field for the camera within my VehicleSpawn script. The camera is of course accessed by dragging the camera object into that public field.

At this time, accessing a rigidbody of an instantiated prefab is easiest when done within the same script in which the prefab is instantiated.

VehicleSpawner:

 public class VehicleSpawner : MonoBehaviour {
     
     private GameObject selectedVehicle;
     private GameObject vehicle;
     
     public Camera myCam;
     
     public Vector3 offset;
     public float minZoom = 8.0f;
     public float maxZoom = 12.0f;
     
     void Awake (){
         
         myCam.orthographicSize = minZoom;
     }
     
     void Start (){
         // Spawn vehicle
         DataManager.control.Load ();
         selectedVehicle = DataManager.control.selectedVehicle;
         vehicle = (GameObject)Instantiate(selectedVehicle,new Vector3(-20,2,0),Quaternion.identity);
         
     }
     
     void FixedUpdate () {
         
     
         // Access velocity of rigidbody for camera use
         myCam.orthographicSize = Mathf.Lerp(myCam.orthographicSize, 5 + Mathf.Abs(vehicle.rigidbody2D.velocity.x / 2), Time.deltaTime);
         
 
         
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

How to set Rigidbody2D velocity based on rotation 1 Answer

How to make gravity in 2D follow your phone postion 0 Answers

Weird Rigidbody2D.velocity.x problem, float out of control 0 Answers

2D Character jittering after build. (Unity 5) 1 Answer

Having issues with stacked rigidbody2D objects 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges