Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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 AngryLyons · Dec 02, 2015 at 10:05 AM · scripting problemphysicsrigidbodyragdollkinematic

Tracking Force Added to Kinematic Rigidbody

Hello! =)

Short form: Is there anywhere I can see how much force has been added to a kinematic rigidbody over the course of the current frame?

Alternatively: Is there a way to catch or hook into AddForce() method invocations, so that whenever [some script] calls AddForce() on a particular rigidbody, I can execute some code that does something with the parameters of the call?

Long version: Ok, so what I'm attempting to achieve here is to 'ragdoll' a character when the force applied to it exceeds a threshold.

The (Non-humanoid) character consists of a regular Unity character controller and a collection of Kinematic rigidbodies, that are used as hitboxes for it's body and limbs.

I ragdoll the character using a script which deactivates the character controller and animator and sets the rigidbodies to non-kinematic. This works well enough, physics takes over and the character falls over as per the joints configured for the rigidbodies.

My problem lies in triggering the ragdoll state. I want the character to ragdoll upon losing it's balance. My approach is to add together the forces being applied to the character into an 'imbalance' vector, and if this vector's magnitude exceeds a threshold, the character is ragdolled and it falls over.

This is fine for collisions with physics controlled rigidbodies; I can simply calculate the force of the impact in OnCollisionEnter and add it to the running total, but I can't find any similar solution to forces caused by non-collisions.

This means that wind effects, explosions, or any force applied by a script don't contribute to triggering the ragdoll.

The only workable solution I can see at the moment is to modify every script I use that applies forces and add a check for the ragdoll'able character and apply the imbalance directly. This isn't ideal, it'd clutter up those scripts and introduce difficult to detect bugs where I forget a particular call, or don't account for the Forcemode by accident.

Where should I go from here? Is the ugly way my only option? Is there a better, smarter design that doesn't have this issue?

Comment
Add comment · Show 7
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 SpaceManDan · Apr 15, 2016 at 12:36 AM 0
Share

I am also looking into this. Working on an answer and will come back to this once I find it.

avatar image Kurdle_4855 · Apr 15, 2016 at 05:26 AM 0
Share

Didn't read the whole thing, but couldn't you just get the 'velocity' variable on the rigidbody? I'm not sure if this will work, but I hope it helps.

avatar image SpaceManDan Kurdle_4855 · Apr 15, 2016 at 05:32 AM 0
Share

wow I'm an idiot man. Yes you can because that is all the things I'm needing.

avatar image AngryLyons Kurdle_4855 · Apr 15, 2016 at 08:16 AM 0
Share

I'm not sure if it has changed in Unity 5, but in previous versions this did not work. Adding force does not immediately change the velocity variable, velocity only changes when the physics step occurs.

$$anonymous$$y rigidbody is kinematic, so its velocity is not affected by add force anyhow.

avatar image SpaceManDan Kurdle_4855 · Apr 15, 2016 at 06:57 PM 0
Share

@AngryLyons

Actually adding force does immediately change the target if you use forcemode.impulse.

For example: GetComponent().AddForce(0, 0, 10, Force$$anonymous$$ode.Impulse); using impulse will immediately apply 10 force on the z axis.

Example 2: GetComponent().AddForce(0, 0, 10, Force$$anonymous$$ode.Acceleration); using this method will apply force using drag and mass to ramp up to a force of 10.

Here is a link to unity manual on it: http://docs.unity3d.com/ScriptReference/Force$$anonymous$$ode.html

Also, what I needed to do was not applying a force but directly setting the velocity of my ridigbody to match that of the one impacting said object. This is not the best solution but it is a solution that works. Unity manual has this to say about setting velocities:

"In most cases you should not modify the velocity directly, as this can result in unrealistic behavior. Don't set the velocity of an object every physics step, this will lead to unrealistic physics simulation. A typical example where you would change the velocity is when jumping in a first person shooter, because you want an immediate change in velocity."

What I've done is very similar. It is an impulse force I need not an acceleration. Here is how I implemented it.

 private Vector3 impactVelocity;

 private bool doImpact;

 private void OnCollisionEnter(Collision col)
 {
     if (this.GetComponent<Rigidbody>().is$$anonymous$$inematic)
     {
         if (col.relativeVelocity.sqr$$anonymous$$agnitude > 6)
         {
             impactVelocity = col.transform.GetComponent<Rigidbody>().velocity;
                 
             doImpact = true;
         }
     }
 }

 private void FixedUpdate()
 {
     if (doImpact)
     {
         this.GetComponent<Rigidbody>().is$$anonymous$$inematic = false;
         this.GetComponent<Rigidbody>().velocity = impactVelocity;

         doImpact = false;
     }
 }

You will likely need to adapt this to your specific needs but this is the basic principal of what I am doing to solve this issue and it is working perfectly for me.

avatar image AngryLyons SpaceManDan · Apr 15, 2016 at 07:16 PM 0
Share

Unfortunately, my question operates on a lower level to what you describe. I mean that velocity does not change within a single frame

ie:

 void FixedUpdate () {
         step++;
         Rigidbody rb = GetComponent<Rigidbody>();
         print("Step" + step + ": " + rb.velocity );
         rb.AddForce(Vector3.up*10,Force$$anonymous$$ode.Impulse);
         print("Step" + step + ": " + rb.velocity );
     }

Both of the above print statements produce the same output. rb.AddForce does not affect the value of the velocity attribute.

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by SpaceManDan · Apr 15, 2016 at 07:04 PM

Thought I'd throw this in the answer section in-case you decide it works for you too.

 private Vector3 impactVelocity;

 private bool doImpact;

 private void OnCollisionEnter(Collision col)
 {
     if (this.GetComponent<Rigidbody>().isKinematic)
     {
         if (col.relativeVelocity.sqrMagnitude > 6)
        {
             impactVelocity = col.transform.GetComponent<Rigidbody>().velocity;
              
             doImpact = true;
         }
     }
 }

 private void FixedUpdate()
 {
     if (doImpact)
     {
         this.GetComponent<Rigidbody>().isKinematic = false;
         this.GetComponent<Rigidbody>().velocity = impactVelocity;

         doImpact = false;
     }
 }


In my case, I'm using a ragdoll that has several rigidbodies that are set to isKinematic all attached to a parent. I need them all to switch at once so I suggest you use something like this to do that.

 public void SetKinematic(bool newBool)
 {
     Rigidbody[] rigidBodies = GetComponentsInChildren<Rigidbody>();

     foreach (Rigidbody rb in rigidBodies)
     {
         rb.isKinematic = newBool;
     }
 }


Call this method like this:

 SetKinematic(false);

or

 SetKinematic(true);
Comment
Add comment · Show 4 · 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 AngryLyons · Apr 15, 2016 at 07:22 PM 0
Share

Unfortunately, this isn't really relevant. $$anonymous$$y question calls out collisions with other rigidbodies as the easy part:

This is fine for collisions with physics controlled rigidbodies; I can simply calculate the force of the impact in OnCollisionEnter and add it to the running total, but I can't find any similar solution to forces caused by non-collisions.

$$anonymous$$y question relates to factoring in other forces, such as explosions, wind or magnetism

This means that wind effects, explosions, or any force applied by a script don't contribute to triggering the ragdoll

This part seems to be significantly harder, as these forces are generally applied by other scripts. I can't figure out a way to react to those forces, without modifying those other scripts.

avatar image SpaceManDan AngryLyons · Apr 15, 2016 at 07:33 PM 0
Share

AH ok, I'm on the same page as you. I think you can do this in a simple way. Gimmie a few $$anonymous$$utes.

avatar image SpaceManDan SpaceManDan · Apr 15, 2016 at 07:36 PM 0
Share

Any reason you can't just create your own float to watch for this.

 private float ragTripThresh;

 private void Update()
 {
     if(ragTripThresh >= 100f)
     {
         doRagdollTrip();
     }
 }

Now anytime you apply a force to the object you add a little to "ragTripThresh" until it is over 100?

Show more comments

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.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Disable ragdoll without changing Kinematic boolean? 2 Answers

How can I make character become a ragdoll with isKinematic? 1 Answer

Problems with ragdolls and no gravity 0 Answers

Projectile collides, freezes, but flips to weird angle. Help! 0 Answers

Switch off Kinematic for a Rigidbody in response to an explosion or impact? 1 Answer


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