Search Unity

Instantiated rigidbodies behaving differently than rigidbodies placed in scene

Discussion in 'Scripting' started by samloeschen, Jan 16, 2013.

  1. samloeschen

    samloeschen

    Joined:
    Mar 22, 2010
    Posts:
    268
    Is there any reason a rigidbody would behave differently if its game object has been instantiated at run time vs. placed in the scene? My game involves a lot of manipulation of physics enabled objects, and while objects that are instantiated at runtime behave just fine, the the objects that are placed in the scene to begin with are acting very strangely. It is almost as if their transform's position is drastically off from their rigidbody's position.

    Nothing special is being done when instantiating the objects that do work....I'm merely instantiating prefabs in various positions. In fact, the very same identical prefab will behave differently whether it is instantiated or placed in the scene before the game is run. As for the code that is utilized by the player to manipulate certain objects, all objects are treated the same. In fact, the rigidbodies in the prefabs for all of these manipulatable objects have the exact same settings...so their behavior really should not vary at all.

    Thanks for any and all help guys, I'm really scratching my head here.
     
  2. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    They should behave the same, there's no default Unity behaviour that would make this seems different, but not sure what else to say if you don't post any code or an example project.
     
  3. samloeschen

    samloeschen

    Joined:
    Mar 22, 2010
    Posts:
    268
    Sorry for the late reply, it snowed pretty hard here so there were a few things for me to take care of.

    I put together a video that illustrates the problem a little bit better:



    Each object that can be picked up has an attached script called PickUp. It basically just has some boolean values for if the object is currently held, if it has been fired, etc. If it would help, I can post that as well.

    This is the code snippet that handles pulling the objects towards the player. It just adds every game object inside a trigger with the PickUp script attached to it to a list in the player's pick up manager. The manager handles all of the physics code.


    Code (csharp):
    1. function OnTriggerStay(col : Collider){
    2.     var obj : GameObject = col.gameObject;
    3.     var comp = obj.GetComponent(PickUp);
    4.     if(pulling){
    5.         if(comp){
    6.             if(list.IndexOf(obj) == -1){   
    7.                 list.Add(obj);
    8.             }
    9.         }
    10.     }
    11. }
    12.  
    13. function OnTriggerExit(col : Collider){
    14.     var obj : GameObject = col.gameObject;
    15.        
    16.     if(!pulling){
    17.         if(list.Contains(obj)){
    18.             list.Remove(obj);
    19.             list.TrimExcess();
    20.         }
    21.     }
    22. }
    23.  
    Here is the code snippet that handles adding pick ups to the list of items that the player currently holds. Like the pull snippet, uses a trigger to find the items it can add, and just submits them to a list in the player's pick up manager. It checks to make sure the player isn't throwing any objects before adding them.

    Code (csharp):
    1. function Start(){
    2.     list = tractorBeamObj.GetComponent(PickUpManager).heldList;
    3. }
    4.  
    5. function Update(){
    6.    
    7.     pulling = tractorBeamObj.GetComponent(PickUpManager).pulling  ;
    8. }
    9. function OnTriggerStay(col : Collider){
    10.     var obj : GameObject = col.gameObject;
    11.     if(pulling){
    12.         if(list.Count<maxPickUps){
    13.             if(!list.Contains(obj)){
    14.                 if(tractorBeamObj.GetComponent(PickUpManager).thro  wOne == false  tractorBeamObj.GetComponent(PickUpManager).throwAl  l == false){
    15.                     list.Add(obj);
    16.                     var pickUp = obj.GetComponent(PickUp);
    17.                     pickUp.held = true;
    18.                     pickUp.transform.parent = target.transform;
    19.                 }
    20.             }
    21.         }
    22.     }
    23. }
    24.  
    And here is the part of the manager that handles pulling the items as well as holding them in place. For holding them, it uses a simple spring code with a damp rate and rest distance. For pulling them, it just runs through the list and moves them towards a target position.

    Code (csharp):
    1. function FixedUpdate(){
    2.     for(var h : int = 0; h<heldList.Count; h++){
    3.         var diff1 : Vector3 = heldList[h].transform.position - target.transform.position;
    4.         var dir1 : Vector3 = diff1.normalized;
    5.         var dist1 : float = Vector3.Distance(target.transform.position, heldList[h].transform.position);
    6.         var sprForce : float;
    7.         var sprDisp : float;
    8.         var velDiff : Vector3;
    9.        
    10.         sprDisp = dist1 - sprRest;
    11.         velDiff = player.rigidbody.velocity - heldList[h].rigidbody.velocity;
    12.        
    13.         //calculate spring force and add it to the rigidbody
    14.         sprForce = (-sprK * sprDisp) - (sprDamp * heldList[h].rigidbody.velocity.magnitude);
    15.         heldList[h].rigidbody.AddForce(sprForce * dir1);
    16.        
    17.         //add difference to make objs keep up with player
    18.         heldList[h].rigidbody.velocity += velDiff;
    19.  
    20.         //remove from pull list
    21.         if(pullList.IndexOf(heldList[h]) != -1){
    22.             pullList.Remove(heldList[h]);
    23.             pullList.TrimExcess();
    24.            
    25.         }
    26.            
    27.     }
    28.    
    29.     if(pulling){
    30.         for(var p : int = 0; p<pullList.Count; p++){
    31.             var dir2 : Vector3 = (target.transform.position - pullList[p].rigidbody.position).normalized;
    32.             var dist2 : float = Vector3.Distance(pullList[p].rigidbody.position, target.transform.position);
    33.             pullList[p].rigidbody.AddForce(dir2 * (pullForce));
    34.            
    35.         }
    36.     }else{
    37.         pullList.Clear();
    38.    
    39.     }
    40.    
    41.     //when fired, disable collider to keep accuracy
    42. }
    43.  
    That's about all I can think of that would affect these objects. If there's anything else I might have forgotten that would help solve the problem, just let me know.
     
    Last edited: Jan 18, 2013
  4. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    I think the problem is more in the last script.

    What is "target"? Where does it reside in your script. Are you updating it? What affect does the "target"'s location have on your objects.

    In the video, you shot some of them. Then went and picked up more objects. You called them instantiated ones. What happesn if you pick up more from around the planet?

    If the same happens after you shoot, then you more than likely are keeping your "target" far out in front of your ship, and since it has something to do with your movement, it may affect your asteroids after you have shot your first one.
     
  5. samloeschen

    samloeschen

    Joined:
    Mar 22, 2010
    Posts:
    268
    "target" is just an empty transform that the objects are pulled to, and it is set in the inspector. It's a child of the player.

    I probably should clarify, all items that are currently held by the player are made children of the player...maybe that could have something to do with the problem?

    Basically, I can go and pick up any object that has been instantiated during runtime and it will behave just fine. The only time the behavior occurs is if the object was placed in the scene beforehand.
     
  6. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    It's best not to parent ridgidbodies to one another, weird stuff happens when you do that because then you have forces (gravity, momentum, constraints ect) acting on the parent that get applied to the children as non physical forces through the propagation of the transform hierarchy (as the ship moves, it moves the transform of everything else), then the children rigid-bodies have their own forces applied on top of that.

    I'm more surprised your current pickup code works at all.

    If you want to keep the parenting then I'd suggest flagging the rigidbodies as kinematic before setting the parent, then clearing it afterward the parent is removed (object fired). This should keep your physics state much more predictable and stop a lot of the weirdness. You'd need to animate them without physics at this point though so perhaps just don't re-parent anything and that might fix it too.

    Love the concept of the underlying game btw, best of luck with it. :)
     
    Last edited: Jan 19, 2013
  7. samloeschen

    samloeschen

    Joined:
    Mar 22, 2010
    Posts:
    268

    What is surprising you about the pickup code? If something is unclear I'd be happy to make it less so.

    I'll be trying setting them to kinematic first thing in the morning, hopefully that will fix the issue. I still don't understand while the instantiated ones behave just fine, as opposed to the ones who have been placed in the scene.

    And thank you! I'm a student that has been working on it off and on over the past year, and as I'm become more experienced with Unity it's starting to develop much more. Thanks for the encouragement.
     
  8. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    What's surprising about your code is that the parenting isn't messing it up more. I also don't see any need to keep the objects under physics control once they've been "picked up".
     
  9. unity_PupO1Im3IUhsRQ

    unity_PupO1Im3IUhsRQ

    Joined:
    Jul 6, 2022
    Posts:
    1
    Don't suppose you guys found a solution in the past 9 years? lol
     
  10. Mas_rig

    Mas_rig

    Joined:
    Jul 9, 2022
    Posts:
    1
    Haha im facing the sam issue