Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
1
Question by Hamesh81 · Jan 18, 2012 at 06:34 AM · rigidbodycharactercontrollertagcontrolpush

Why is my push rigidbody script not effected by mass?

I have this great script which allows a character controller to push rigidbodies around at a specified force. Anyone feel free to use this script for your purposes.

But it seems that the force pushing the rigidbodies does not take into account the mass of each rigidbody. So whether the rigidbody is a 2 kg cube or 1000 kg car the character controller still pushes it using the same force which obviously looks very unrealistic.

Is there a way to add the rigidbody mass into the push force calculation somehow?

I suppose it could be implemented using a tagging system; where the force is set to apply differently based on the tag of each rigidbody.

Here is the script:

 // Script added to a player for it to be able to push rigidbodies around.
 #pragma strict
 #pragma implicit
 #pragma downcast
 
 // How hard the player can push
 var LightpushPower = 0.5;
 var HeavypushPower = 0.1;
 
 // Which layers the player can push
 // This is useful to make unpushable rigidbodies
 var pushLayers : LayerMask = -1;
 
 // pointer to the player so we can get values from it quickly
 private var controller : CharacterController;
 
 function Start () {
     controller = GetComponent (CharacterController);
 
 }
 
 function OnControllerColliderHit (hit : ControllerColliderHit) {
     if(hit.gameObject.tag == "enemy") {
     var body : Rigidbody = hit.collider.attachedRigidbody;
     // no rigidbody
     if (body == null || body.isKinematic)
         return;
 
     // Only push rigidbodies in the right layers
     var bodyLayerMask = 1 << body.gameObject.layer;
     if ((bodyLayerMask & pushLayers.value) == 0)
         return;
         
     // We dont want to push objects below us
     if (hit.moveDirection.y < -0.3) 
         return;
     
     // Calculate push direction from move direction, we only push objects to the sides
     // never up and down
     var pushDir = Vector3 (hit.moveDirection.x, 0, hit.moveDirection.z);
     
     body.velocity = pushDir * LightpushPower ;
     }
 }

Comment
Add comment
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

2 Replies

· Add your reply
  • Sort: 
avatar image
4
Best Answer

Answer by ScriptGirl · Jan 18, 2012 at 12:58 PM

This is what the script should look like with hit.gameObject.tag == "enemy" used. Hope it helps!!

 // Script added to a player for it to be able to push rigidbodies around.
 #pragma strict
 #pragma implicit
 #pragma downcast
 
 // How hard the player can push
 var LightpushPower = 0.5;
 var HeavypushPower = 0.1;
 
 // Which layers the player can push
 // This is useful to make unpushable rigidbodies
 var pushLayers : LayerMask = -1;
 
 // pointer to the player so we can get values from it quickly
 private var controller : CharacterController;
 
 function Start () {
     controller = GetComponent (CharacterController);
 
 }
 
 function OnControllerColliderHit (hit : ControllerColliderHit) {
     if(hit.gameObject.tag == "enemy") {
     var body : Rigidbody = hit.collider.attachedRigidbody;
     // no rigidbody
     if (body == null || body.isKinematic)
        return;
 
     // Only push rigidbodies in the right layers
     var bodyLayerMask = 1 << body.gameObject.layer;
     if ((bodyLayerMask & pushLayers.value) == 0)
        return;
 
     // We dont want to push objects below us
     if (hit.moveDirection.y < -0.3) 
        return;
 
     // Calculate push direction from move direction, we only push objects to the sides
     // never up and down
     var pushDir = Vector3 (hit.moveDirection.x, 0, hit.moveDirection.z);
 
     body.velocity = pushDir * LightpushPower ;
     }
 }
Comment
Add comment · Show 5 · 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 Hamesh81 · Jan 18, 2012 at 01:09 PM 0
Share

Thanks heaps. Ok, I've updated the script. That works great but it only uses one tag. I've tried editing it to use a second or multiple tags as well but keep getting errors about things being repeated. The only way I got it to work is by duplicating the script changing out the variable and tag, and then attaching the original and duplicate to the character controller.

There must a more optimized approach though. Any ideas how to get multiple tags to work in one script?

avatar image ScriptGirl · Jan 18, 2012 at 01:47 PM 0
Share

There is :D You need to move your if statement down and make one for each of the tags you have defined. $$anonymous$$ake sense?

avatar image Hamesh81 · Jan 18, 2012 at 01:50 PM 1
Share

Legend! THAT'S the advice I needed. Thanks so much. It works perfectly.

avatar image ScriptGirl · Jan 20, 2012 at 03:44 PM 0
Share

Lol, no probs.

avatar image jasonoda · Oct 10, 2012 at 10:30 PM 0
Share

Quick note. For me to get this to work I had to say:

body.velocity = pushDir LightpushPower 100;

Not sure why I had to up it so much, but might help someone. AWESO$$anonymous$$E CODE!

avatar image
2

Answer by syclamoth · Jan 18, 2012 at 06:42 AM

Have you looked at how your script actually manages the Rigidbody calculations? Specifically this line, the one which determines the rigidbody's resultant force:

 body.velocity = pushDir * pushPower ;

Of course, rigidbody.velocity isn't affected by mass- only forces acting on the rigidbody are! In this, the rigidbody's velocity is being directly modified, so of course it doesn't take mass into account.

If you want to use actual forces, instead, use this line:

 body.AddForce(pusDir * pushPower, ForceMode.Impulse);

This way, heavier bodies will move less than light ones.

Be warned- you may want to include some kind of system for limiting the resultant velocity- very light objects may get shot off into the distance otherwise!

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 Hamesh81 · Jan 18, 2012 at 07:26 AM 1
Share

Thanks for your response. I didn't actually understand how the script worked until you pointed it out, I'm still learning, but what you said has made things clearer now. I've tested what you suggested and it works.

I'm now wondering though if having actual forces being calculated for every rigidbody would be too expensive and unnecessary? Would it be better to create lets say 2 or 3 "pushPower" variables:

eg.

LightpushPower = 0.5

HeavypushPower = 0.2

And use a tagging system to detect which objects receive which pushPower in the OnControllerColliderHit function?

avatar image syclamoth · Jan 18, 2012 at 07:50 AM 0
Share

You could do that as well, but if the objects are rigidbodies there's really no difference performance-wise.

avatar image Hamesh81 · Jan 18, 2012 at 08:35 AM 0
Share

Sure, thanks for clearing that up.

So I've updated the code in the question and tried implementing a tagging system with 2 variables. I think this system will allow for easier control of exactly how much each object is pushed. I'm getting the following error though:

BCE0019: 'CompareTag' is not a member of 'UnityEngine.ControllerColliderHit'.

Since apparently CompareTag can't be used with ControllerColliderHit. Could you please advise how else I can use tagging, would be it be "if tag = variable"?

Thanks again

avatar image ScriptGirl · Jan 18, 2012 at 10:48 AM 1
Share

You need to use: hit.gameObject.tag == "enemy" in the if statement. And get rid of the second closing bracket. Hope that helps!!

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

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to make camera position relative to a specific target. 1 Answer

Object push character controller? 1 Answer

Character Controller and Kinematic Collision 1 Answer

Making a Character Controller push another Character Controller 3 Answers

how to make character controller push rididbodies 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