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
0
Question by StickFigs · Mar 29, 2014 at 10:25 PM · 2dphysicsrigidbodybox2d

rigidbody2d.AddForceAtPosition Doesn't Add Horizontal Movement?

I have a simple rigidBody2D object in my scene. When I click on the screen I do a ray cast from the bottom of the screen to the top at the x-position of where my mouse click was. If the ray cast hits the rigidbody then the rigidBody does this:

 rigidbody2D.AddForceAtPosition(Vector2.up * 100.0f, impactPoint);

Where impactPoint is the point where the ray cast hit the collider. What I want is this to act like a bullet was fired straight upwards, hitting the rigidBody and imparting velocity and angular velocity on it. So when the ray cast hits the far right edge of the collider I want the rigidbody to move upwards, to the left, and to spin counter-clockwise.

However the actual result of AddForceAtPosition is just that the object moves perfectly straight upwards and starts spinning around its center.

Why isn't the rigidbody moving to the left or right? Is AddForceAtPosition not able to simulate being hit by a very small, very fast traveling object?

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

1 Reply

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

Answer by gfoot · Mar 29, 2014 at 10:45 PM

If you apply an upwards force, then the body will only move upwards. If you want it to move sideways you need to apply a sideways force as well. The "at position" bit doesn't change this, it just make it add a torque as well.

In reality the end result of this kind of collision depends hugely on the bounce angle of the bullet, assuming it bounces off at all. It's probably not worth you worrying about the maths though. You will probably get a good result if you calculate a normal vector from the bullet towards the target object, and apply an impulse to the target object in that direction, scaled by the dot product of the bullet's incoming velocity with this direction vector.

This will apply the maximum impulse when the bullet his the target squarely from below, with a sideways component if it doesn't hit it squarely, and the magnitude of the impulse will decay to zero as the bullet's impact gets more tangential.

Something like this:

 var direction = (target.position - bullet.position).normalized;
 var magnitude = MaxImpulse * Vector3.Dot(direction, bullet.rigidbody.velocity.normalized);

then apply an impulse of direction*magnitude.

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 StickFigs · Mar 29, 2014 at 11:09 PM 0
Share

$$anonymous$$y new code looks like this:

 var direction = ((Vector2)transform.position - impactPoint).normalized;
 var magnitude = 100.0f * Vector2.Dot(direction, Vector2.up);
 
 rigidbody2D.AddForceAtPosition(direction * magnitude, impactPoint);

The effect is close to what I want now, except now I lost the torque!

Another side-effect is that with a rectangular object that is wider than it is tall then sometimes if I hit a far edge I get a downwards force?

avatar image gfoot · Mar 29, 2014 at 11:31 PM 0
Share

Yes, I assumed your targets were circular.

Generally the direction should be the surface normal at the contact point, for a perfect bounce with no friction. This will also cause torques again, for non-circular objects, which it sounds like you do want.

The other thing that will cause torque is if you add a vertical frictional force to whatever you calculate, maybe just a constant one.

avatar image StickFigs · Mar 30, 2014 at 01:01 AM 0
Share

Generally the direction should be the surface normal at the contact point, for a perfect bounce with no friction. This will also cause torques again, for non-circular objects, which it sounds like you do want.

@gfoot I would like both angular and linear velocity imparted on the collided object. Not just one or the other.

The other thing that will cause torque is if you add a vertical frictional force to whatever you calculate, maybe just a constant one.

How do I implement this?

avatar image gfoot · Mar 31, 2014 at 09:24 AM 0
Share

To begin with, for non-circular shapes use the surface normal vector from the RayCastHit2D object ins$$anonymous$$d of calculating a vector from the hit point towards the object's centre. That will fix the problem with the downward force, and might give the effect you're looking for.

Then on top of that experiment with adding an additional force upwards at the contact point - play with the magnitude of this force and see if it helps you achieve the result you want.

 var direction = -rayCastHit.normal;
 var magnitude = 100.0f * Vector2.Dot(direction, Vector2.up);

 rigidbody2D.AddForceAtPosition(direction * magnitude + ConstantUpwardsForce * Vector2.up, impactPoint);

Start with ConstantUpwardsForce set to zero, get a feel for the behaviour, then start increasing it and see if you like the result better.

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

21 People are following this question.

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

Related Questions

Continuously moving rigidbody 2 Answers

Rotating my character only while moving in a 2D plane 3 Answers

where to trigger which collision event? 1 Answer

How do I make this kind of follow script? 1 Answer

Spinning rigidbody platform in 2D 0 Answers


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