Daniel dos Santos
Daniel dos Santos

Reputation: 271

How to addforce to a single Ragdoll limb in unity?

I'm trying to make a Ragdoll that can move each limb individually. However when I try testing this on the Ragdoll's right leg, I get this error.

error CS1061:'CharacterJoint' does not contain a definition for 'AddForce' and no accessible extension method 'AddForce' accepting a first argument of type 'CharacterJoint' could be found (are you missing a using directive or an assembly reference?)

I tried switching AddForce with SwingAxis which didn't change anything. I looked up the methods for Character Joint but couldn't find any that would make the leg bend at the joint.

public class rightLeg_movement : MonoBehaviour
 {
     public CharacterJoint cj;
     public float forwardForce = 2000f;

     void FixedUpdate()
     {
         if( Input.GetKey("m") )
         {
             cj.AddForce(forwardForce, 0, 0);
         }
     }
 }

All of the tutorials I looked up use an animation instead. However I plan on implementing an ai to do basic tasks with the Ragdoll(like learning to picking itself up, or learning to walk).

Upvotes: 1

Views: 1808

Answers (1)

Ruzihm
Ruzihm

Reputation: 20249

CharacterJoints don't have support for driving the joints built-in. You would be better off using ConfigurableJoints instead. Once you configure the limits on the joints, you can use ConfigurableJoint.angularXDrive to configure the maximum angular force it can apply and then ConfigurableJoint.targetAngularVelocity to configure the target angular velocity.

Also, it's recommended to call Input methods in Update instead of FixedUpdate where possible. From the documentation:

Note also that the Input flags are not reset until Update. It is suggested you make all the Input calls in the Update Loop.

Altogether, these changes might look like this for something like a knee joint that can only move around the local x axis:

public class rightLeg_movement : MonoBehaviour
{

    public ConfigurableJoint cj;

    public float forwardForce = 2000f;
    public float backwardForce = 1000f;
    public float holdForce = 5000f;

    public float forwardVelocity = 2f;
    public float backwardVelocity = 1f;

    private bool isInputForward = false;
    private bool isInputBackward = false;

    void Start()
    {
        SetForwardJointMovement(holdForce, 0f);
    }

    void Update()
    {
        isInputForward = Input.GetKey("m");
        isInputBackward = Input.GetKey("n");

        if (isInputForward)
        {
            SetForwardJointMovement(forwardForce, forwardVelocity);
        }
        else if (isInputBackward)
        {
            SetForwardJointMovement(backwardForce, -backwardVelocity);
        }
        else
        {
            SetForwardJointMovement(holdForce, 0f);
        }
    }

    void SetForwardJointMovement(float force, float velocity)
    {
        JointDrive drive = new JointDrive();
        drive.maximumForce = force;
        drive.positionDamper = 1e10f;
        cj.angularXDrive = drive;

        cj.targetAngularVelocity = Vector3.left * velocity;
    }
}

The documentation for ConfigurableJoint is currently in very poor condition so apologies if something is off.

Upvotes: 2

Related Questions