• 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
4
Question by Somian · Nov 11, 2011 at 03:23 PM · physics

make objects push away from each other

Hi there. I want to make some kind of shockwave that pushes objects away from one particular object emitting the shockwave. This works fine by using Rigidbody.AddExplosion(). however, it doesn't behave the way I want yet. The problem is, that the one object applying a force to another object should move a bit away from that object. I attached an illustration of it:

alt text

Imagine you're kicking a barrel, you apply a force to the barrel, the barrel falls over and since you're standing on the ground, you're still standing.

Now imagine, you're in zero-gravity, a space-station or something, there's a barrel floating in front of you. when you kick it, the barrel moves away from you, but since you're also not attached to anything, you move a bit away from the barrel (assuming that your mass is higher than the barrel's)

Do you ahve an idea how to accomplish in the unity physics engine? :)

Comment
Add comment · Show 2
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 syclamoth · Nov 11, 2011 at 03:25 PM 1
Share

Rigidbody.AddForce is, oddly, not quite correct in a Newtonian sense. If you want to do something like this, you'll have to hardcode the whole 'equal and opposite reaction' thing- so at every point where your object would add a force of some kind to an object, apply the same force inverted to the first object.

The static collider thing will be a bit tricky, I think. Static colliders can't really be treated like rigidbodies, so I think you'll just have to approximate that with a lot of raycasts.

avatar image Somian · Nov 11, 2011 at 04:01 PM 1
Share

Thanks :) The raycast thing is not a solution since i'm working on an iphone game with a lot of such things going on, so maybe i could just cheat by making my static colliders not really static but rigid bodies with a huge mass or something or hard-fix them by resetting their position.

would still be cool if thered be an already existing way to do something like this so i don't have to code this on my own :/

EDIT: ok, this might not work either, performance-wise but i might come up with a thesis-worthy way of baking the resolved directions an object would go in a vectorfield for every location of the level in a texture and loading it when the level is started o_º only works for small 2d levels, though, for memory reasons.

2 Replies

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

Answer by aldonaletto · Nov 11, 2011 at 10:59 PM

I think your heavy rigidbody idea is the best: since you're already applying AddExplosionForce to each hit rigidbody, add an extra line of code to apply AddExplosionForce to the exploding object as well: use the original explosion force multiplied by hit object mass * adjust factor, the hit object's position as the explosion center, and the original explosion radius - this will cheaply produce a very convincent reaction force.
This is an adaptation of the AddExplosionForce example:

var radius = 5.0; var power = 10.0; var reaction = 0.1; // adjust reaction factor

function Start () { // Applies an explosion force to all nearby rigidbodies var explosionPos : Vector3 = transform.position; var colliders : Collider[] = Physics.OverlapSphere (explosionPos, radius); for (var hit : Collider in colliders) { if (hit && hit.rigidbody){ // apply explosion force to the hit object: hit.rigidbody.AddExplosionForce(power, explosionPos, radius, 3.0); // apply reaction force proportional to the hit object's mass: rigidbody.AddExplosionForce(reaction power hit.rigidbody.mass, hit.transform.position, radius) } } }

EDITED: When the static object is long like a wall, you can find the reaction force origin using some geometry (case 1 in the drawing below): do a Linecast from the explosion to the object's center, project the vector hit point - explosion onto the surface normal to find the reaction vector, then add it to the explosion pos: this returns the reaction origin in the wall plane. But what if the explosion is beyond the wall (case 2)? To detect this, you can do a short raycast to the reaction origin plus a little distance (0.5m, for instance) - if wall hit, use the calculated reaction origin; if not, explosion is beyond the wall, thus use the wall center as reaction origin. All this geometry may seem complicated, but is cheap: only when a static object is found you must use one linecast and one raycast, both short and inexpensive.

alt text

Since the treatment for static and movable objects must be different, you must know who's who. The easiest way is to remove rigidbodies from the static objects: if the object hit has a rigidbody, AddExplosionForce to it (and the reaction force to the exploding object too, if you want); if no rigidbody, the object is static, thus just calculate the reaction origin and apply the reaction force.
This code considers static all objects without a rigidbody, and calculates the reaction origin like said above:

var pos : Vector3 = transform.position;
var colliders : Collider[] = Physics.OverlapSphere (pos, fieldRadius);
for (var hit : Collider in colliders) {
    if (hit){
        if (hit.rigidbody){ // movable object:
            hit.rigidbody.AddExplosionForce(...); // apply force to object hit
            // apply reaction force to exploding object as well, if you want
        } 
        else { // no rigidbody means static object:
            var pReact = hit.transform.position;
            var hitP: RaycastHit;
            Physics.Linecast(pos, pReact, hitP); // find the surface normal and hit point
            // calculate vector from explosion to wall surface
            var vReact = Vector3.Project(hitP.point - pos, hitP.normal);
            // check if not beyond wall end:
            if (Physics.Raycast(pos, vReact, vReact.magnitude + 0.5)){
                pReact = pos + vReact; // ok: reaction origin is here
            }        
            rigidbody.AddExplosionForce(fieldForce, pReact, fieldRadius, 0);
        }
    }
}
NOTE: If you need more control on which objects are static (and thus produce reaction) tag them as "Static" and check this in the else branch - this may be useful if you don't want reaction from the ground, for instance.
Comment
Add comment · Show 1 · 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 Somian · Nov 25, 2011 at 10:13 AM 0
Share

Thanks, this works, sorta :) i still need a lot more colliders than planned but the performance impact isn't that bad.

avatar image
0

Answer by Somian · Nov 12, 2011 at 05:27 PM

Thanks a lot. I updated it to take the mass ratio into account:

 var pos : Vector3 = transform.position;
 var colliders : Collider[] = Physics.OverlapSphere (pos, fieldRadius);
 for (var hit : Collider in colliders) {
     if (hit && hit.rigidbody){
         var myMass=rigidbody.mass;
         var hitMass=hit.rigidbody.mass;
         // apply explosion force to the hit object:
         hit.rigidbody.AddExplosionForce(fieldForce*(myMass/hitMass), pos, fieldRadius, 0.0);
         // apply reaction force proportional to the hit object's mass:
         rigidbody.AddExplosionForce(fieldForce*(hitMass/myMass), hit.transform.position, fieldRadius,0.0);
     }
 }

however, i encountered another problem. This solution works fine for spherical objects of the same size, but here's an illustration of a problem I have that makes the thing a bit more complicated :/

alt text

Comment
Add comment · Show 2 · 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 aldonaletto · Nov 12, 2011 at 09:14 PM 0
Share

Ouch! That's really a big problem! Let me think about this.

avatar image aldonaletto · Nov 13, 2011 at 10:03 AM 0
Share

I found a way to calculate V2, and check for static and movable objects. Take a look at my edited answer.

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

2D 360 degress platformer example needed 0 Answers

Punching a crate 0 Answers

Two Bone IK constraint with more than 2 bones on my arm. 0 Answers

HOW DO I USE RAYCASTHIT 2D???? 1 Answer

Is it possible to get rope physics? 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