Search Unity

I cannot connect bones together properly using a list. I'm baffled, could anyone please help?

Discussion in 'Scripting' started by reppeti, Oct 23, 2021.

  1. reppeti

    reppeti

    Joined:
    Jun 29, 2021
    Posts:
    44
    Hello everyone!
    So I'm trying to connect bones with a Spring joint using a script. so I don't have to manually do it.
    But for some reason I my script can only connect the elements that are before the bone I want to set the Joints for (or it can also connect it to itself).
    It's very weird, I cannot wrap my head around why it doesn't work, hwere is the code:
    [
    Code (CSharp):
    1.  
    2.         int counter = 0;
    3.         Component[] bones2 = GetComponentsInChildren < Transform > ();
    4.         List < Component > bones = bones2.ToList();
    5.         bones.RemoveAt(0); //Removes the first element that is for some reason the parent
    6.  
    7.         foreach(Component bone in bones) {
    8.  
    9.           if (bone.transform.childCount == 0) {
    10.             SpringJoint2D spring1 = bone.gameObject.AddComponent(typeof (SpringJoint2D)) as SpringJoint2D;
    11.             SpringSetter(spring1);
    12.             spring1.connectedBody = bones[counter - 1].GetComponent < Rigidbody2D > ();
    13.  
    14.           } else if (counter - 1 == -1) {
    15.             SpringJoint2D spring1 = bone.gameObject.AddComponent(typeof (SpringJoint2D)) as SpringJoint2D;
    16.             SpringSetter(spring1);
    17.             spring1.connectedBody = bones[counter + 1].GetComponent < Rigidbody2D > ();
    18.  
    19.           } else {
    20.             SpringJoint2D spring1 = bone.gameObject.AddComponent(typeof (SpringJoint2D)) as SpringJoint2D;
    21.             SpringSetter(spring1);
    22.             spring1.connectedBody = bones[counter - 1].GetComponent < Rigidbody2D > ();
    23.             SpringJoint2D spring2 = bone.gameObject.AddComponent(typeof (SpringJoint2D)) as SpringJoint2D;
    24.             SpringSetter(spring2);
    25.             spring2.connectedBody = bones[(counter + 1)].GetComponent < Rigidbody2D > (); //This line refuses to work! It always keeps it null
    26.             Debug.Log(bones[counter + 1].gameObject.name);
    27.           }
    28. counter++;
    29.         }
    30.  
    31.         private static void SpringSetter(SpringJoint2D spring1) {
    32.           spring1.frequency = 8 f;
    33.           spring1.dampingRatio = 0.8 f;
    34.         }
    Any help is apprechiated. This script simply refuses to get the bones[counter+1] element
     
  2. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    Trying to understand the point: 1st IF) if the bone has no children, connect it to the bone before it. 2nd IF) the first bone ( if(counter-1==-1) is just a funny way of saying if(counter==0)) connects to the one after it, else) otherwise connect to the ones before and after.

    I don't see what the "if it has no children" is for. Worse, if the first bone has no children it will crash (connecting to bone -1). The next part about bone 0 only connecting to bone+1, and not bone-1 which doesn't exist, is standard "don't go off the edge" stuff. But then you should check for the last bone so you don't go off that edge with bone+1.

    Beyond that stuff, you don't need joints both ways. If bone2 connects to bone3, you don't want bone3 to have another spring going back to bone2. Joints are 2-way (sure, Unity says they go on 1 thing and connect to another, but that's only because of how Unity works -- you can't have one Spring component on two bones at the same time. But the rest of the system knows springs are really between two things and affect both).
     
    reppeti likes this.
  3. reppeti

    reppeti

    Joined:
    Jun 29, 2021
    Posts:
    44
    Thanks!
    Yeah I knew about most of the problems, but yeah I guess only one joint is enough, thanks for the help! I don1t remeber why I have written counter-1 == -1 :D