Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How To Add Forces To Ragdolls?

Discussion in 'Physics' started by HumphreyGames, Oct 2, 2020.

  1. HumphreyGames

    HumphreyGames

    Joined:
    May 5, 2020
    Posts:
    40
    Hi all! I am making a combat system in my game and i want it so that when my enemy gets punched, he get thrown backwards a bit and turns into a ragdoll. I don"t really know how to go about doing this. I have made a ragdoll for the enemy using the ragdoll wizard and have made it so that when he collides with the players hand (Using overlapSphere), the ragdoll gets turned on. Thanks!

    Josh :)

    My Code For The Enemy ragdoll turning on:

    Code (csharp):
    1.  private Rigidbody rb;
    2.  
    3.     void Start()
    4.     {
    5.         rb = GetComponent<Rigidbody>();
    6.  
    7.         setRigidbodyState(true);
    8.         setColliderState(false);
    9.         GetComponent<Animator>().enabled = true;
    10.     }
    11.  
    12.     public void die()
    13.     {
    14.         GetComponent<Animator>().enabled = false;
    15.         setRigidbodyState(false);
    16.         setColliderState(true);
    17.     }
    18.  
    19.     void setRigidbodyState(bool state)
    20.     {
    21.  
    22.         Rigidbody[] rigidbodies = GetComponentsInChildren<Rigidbody>();
    23.  
    24.         foreach (Rigidbody rigidbody in rigidbodies)
    25.         {
    26.             rigidbody.isKinematic = state;
    27.         }
    28.  
    29.         GetComponent<Rigidbody>().isKinematic = !state;
    30.  
    31.     }
    32.  
    33.  
    34.     void setColliderState(bool state)
    35.     {
    36.  
    37.         Collider[] colliders = GetComponentsInChildren<Collider>();
    38.  
    39.         foreach (Collider collider in colliders)
    40.         {
    41.             collider.enabled = state;
    42.         }
    43.  
    44.         GetComponent<Collider>().enabled = !state;
    45.  
    46.     }
    47.  
    48.  
    49. My code for the player attack:
    50.  
    51.  
    52. if (Input.GetKeyDown(KeyCode.Return))
    53.         {
    54. animatorSetTrigger("Attack")
    55.             attack();
    56.  
    57.     public void attack()
    58.     {
    59.         Collider[] hitEnemiesLeftHand = Physics.OverlapSphere(attackPointLeftFoot.position, attackRange,          enemyLayers);
    60.  
    61.         foreach (Collider enemy in hitEnemiesLeftHand)
    62.         {
    63.             enemy.GetComponent<Enemy>().die();
    64.         }
    65.     }
    66.  
     
    Last edited: Oct 2, 2020
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
  3. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,068
    So you want to have active ragdoll.
    Well let me warn you, I also wanted.
    Now I'm stuck with still unfinished active ragdoll after two years of development.
     
  4. HumphreyGames

    HumphreyGames

    Joined:
    May 5, 2020
    Posts:
    40
    Ok So how do i apply a force in the direction of the contact normal (sorry i'm new to this sort of thing)
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Always best to start with the API docs because they often contain example code showing key functionality.

    If you raycast,

    https://docs.unity3d.com/ScriptReference/RaycastHit.html

    If you collide,

    https://docs.unity3d.com/ScriptReference/Collision.html

    to add a force, there are many choices. Here is one:

    https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html

    Those are 3D versions. If you're in 2D there are equivalent 2D versions.

    If you are unfamiliar with the physics system, a ragdoll is about the most complicated place you can start, so I recommend you try bipping some simple Rigidbodies around first, get a feel for how collision and /or raycast works.
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Ragdolls have a LOT of ways to go wrong. Start with something simpler. Get comfortable bipping balls and blocks around. Then connect two of them with a hinge like you might find in a ragdoll, learn that. Iterate, iterate, iterate... don't try and build a freakin' space shuttle or an international space station as your very first spaceship.
     
  7. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,068
    I have already released one game (middle size).
    After this I tried to improve, I decided to go with physics.
    But it is so difficult when physics go against you.
     
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Sure, but ragdoll stuff is about a 8/10 as far as physics difficulty goes, regardless of how many non-physics games you made.

    Realtime physics simulation are a very special subset of software engineering and quantitative analysis.

    But if you want to try and build a space shuttle system as your first spaceship, be my guest!
     
  9. HumphreyGames

    HumphreyGames

    Joined:
    May 5, 2020
    Posts:
    40
    Hi i have figured it out for me by adding this line of code when my enemy gets hit:

    Code (csharp):
    1.  
    2.      foreach (Rigidbody rb in rigidbodies)
    3.         {
    4.             rb.AddExplosionForce(50, attackPoint.position, 50f, 70f, ForceMode.Impulse);
    5.         }
    6.  
    thanks for the help!
     
  10. suleymanbucuk

    suleymanbucuk

    Joined:
    Mar 13, 2019
    Posts:
    11
    Ok, this is a bit old topic but may be someone needed this code to apply force on opposing direction of collision contact. So i used this and worked:

    Code (csharp):
    1.  
    2.  
    3.  private void OnCollisionEnter(Collision collision)
    4.     {
    5.        
    6.        Vector3 dir = collision.contacts[0].point - transform.position;
    7.        //Debug.Log("dir bf normalized: " + dir);
    8.        dir = -dir.normalized; // normalize on contrariwise to push back the character          
    9.        dir.y = 0f; // dont apply for on y axis
    10.        Debug.Log("dir aft normalized: " + dir);
    11.        _rb.AddForce(dir * 20, ForceMode.Impulse);
    12.        
    13.     } // OnCollisionEnter
    14.  
    15.  
     
    Oelson and MikeCoderMore like this.
  11. cyanspark

    cyanspark

    Joined:
    Mar 12, 2022
    Posts:
    57
    Joints seem to override a lot of the physics engine. If you raycast an object with joints, it can't be detected.

    If you apply constant force like 1000 the ragdoll doesn't move.

    Joints alos OVERRIDE TRANSFORM POSITION!!!!
    My ragdoll parent is currently falling to 237854 378943 64382 until floating point accuracy makes him erratic.
    except that... He isn't moving, he is right in the middle of the screen not moving, just rotating around weightless like a zero gravity puppet in the middle of camera, while the transform values are change by 1342 every frame. If I slide the transform values and add 20 onto 378999, the puppet goes up by only 20, so the editor transform value is many thousands discordant from what is on display and dialled in using mouse arrows on the transform position values.

    If you tack one piece of the ragdoll using glue to a wall, the arms and legs continue falling as normal. If the object was coded using unity concordant physics, the child objects would stay near the parent objects.

    so if you are going to do new things with it you'll have to write a new physics engine based on ragdolls, not a few lines to add forces.

    judging by this experiment, with raycast not working, transform being 38,000 higher in editor than in fixed update or whatever, joints are not actually inside the physics engine, joints are somewhere beyond the API and editor code.
     
  12. sadpanders

    sadpanders

    Joined:
    Jan 22, 2023
    Posts:
    12
    prob firgured out now but its simple. if its not working you have something messing with it . like i noticed box colliders fk with them, animator, etc. turn em off on death or hit or whatever then reactivate if needed.
     
  13. StephenWebb

    StephenWebb

    Joined:
    Feb 3, 2013
    Posts:
    11
    invert the normal [so it points opposite the impact normal] - there should be a rigid body on both fist and target, as well as a collider. you can use on collision enter and get the contact point, then apply force as an impulse.
     
  14. angeldevelopment

    angeldevelopment

    Joined:
    Sep 28, 2022
    Posts:
    236
    What? I had ragdoll physics setup in my game is less than an hour.

    1. Import any armature
    2. Use ragdoll wizard to setup initial colliders/joints/rigidbodies
    3. Apply any adjustments
    4. Write a script that disables/enables the rigidbodies (isKinematic)

    Done.
     
  15. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,068
    Ragdoll != Active Ragdoll

    With active ragdoll you control your character and all it's limbs with forces or motors on joints.
     
  16. angeldevelopment

    angeldevelopment

    Joined:
    Sep 28, 2022
    Posts:
    236

    Ahh I see, thank you for the clarification.