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 orangeflame · Aug 22, 2020 at 11:26 PM · rigidbody2dvelocityphysics2dforce

How can I get 2 rigidbody2d objects to "share" physics?

In short, I want to make it so that if object A gets knocked back by an explosion, wind, bounces off a bouncy surface, smacked by a hammer, etc. the same forces will be applied to object B and vice versa. I have found that this ultimately creates an infinite feedback loop and I have to take actions to fight it. I have attempted a few method to do this but I run into an issue with each one. Below I have listed what I have tried and the issues:

Method 1

 //remove previously recorded velocities
             rB2B.velocity -= transferVel;
             masterRB2B.velocity -= sentVel;
 //record new changes in velocity
             transferVel = masterRB2B.velocity;
             sentVel = rB2B.velocity;
 //add new changes in velocity
             masterRB2B.velocity += sentVel;
             rB2B.velocity += transferVel;

This method works by adding the velocity, not force, from one object to the other and removing the previous update before adding again.

Issue:

This works but it doesn't account for changes in velocity between updates, like friction, and causes the object to start moving in the reverse direction, unless greater force is continued to be applied. Furthermore, it causes this currently unknown glitch where one object falls slowly while the other one is standing on the ground. I've been able to disable it by ignoring negative Y velocity during transfer but I feel like that will cause issues in the future.

Method 2

 masterRB2B.velocity = rB2B.velocity;

Object A's velocity will always equal object B's.

Issue

It does causes physics to sort of copy over but now object A is sort of immune to all physics apply to it except through the transfer. Furthermore, the communication is now one way.

Method 3

No Code

I make Object A a child of Object B.

Issue

This literally does nothing

Method 4

No Code

I join the 2 objects via a joint.

Issue

This is okay but, if Object A hits a wall Object B can't continue to move in the same direction as Object A is facing the wall. Additionally, if either object is in the air and the other in on the ground, the object remains stuck in the air. I would want it to fall but have the force of the fall still be transferred over.

Method 5

No Code

Write my code so that any time I apply force to object A, like when jumping, it, also, applies the same force to object B.

Issue

This is great in theory but it ignores all collision based physics and I have to remember this with EVERY addforce command I write.

Method 6

NoCode

I write my own physics engine that accounts for a true velocity and a player input velocity.

Issue

This could work but is far too labor intensive for the scope of this project.

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
2
Best Answer

Answer by Jack-Idealits · Aug 23, 2020 at 08:48 AM

If I understand your idea correctly, while the objects copy each other’s physics, this must not loop infinitely if they are subjected to the same force (otherwise, if they are both pushed towards the same direction by the same explosion, the shared physics would make it look as if the explosion were twice as strong).

Perhaps you could try the following:

Monitor the total force experienced by each object, using F=ma. Each time one object receives a significant acceleration (you can adjust this threshold to filter out small perturbations), the force is calculated and added to the other object. However, if both objects have very similar accelerations (similar amount and similar direction) at the same time, assume they are subject to the same force and don’t mirror the force.

Comment
Add comment · Show 8 · 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 orangeflame · Aug 24, 2020 at 10:59 AM 0
Share

I apologize if I did not fully understand what you suggested but you were able to help me figure out the answer. Code is copied below but, in short, I made a value that stores the previous shared force(actually velocity) and, if either object's velocity deviates from that value, it checks which objects did that, makes that value the new shared force, and passes it over to the other object. If both objects deviate from the normal, it just gets the average. I did try to update force instead of velocity but the physics immediately became very glitchy. I still have the one glitch where object A is on the ground which causes object B to float in the air but I decided to call this a feature.

code

     if (sharedForced.x + sharedForceBuffer < masterRB2B.velocity.x || sharedForced.x - sharedForceBuffer > masterRB2B.velocity.x ||
                         sharedForced.y + sharedForceBuffer < masterRB2B.velocity.y || sharedForced.y - sharedForceBuffer > masterRB2B.velocity.y)
                     {
                         if (sharedForced.x + sharedForceBuffer < rB2B.velocity.x || sharedForced.x - sharedForceBuffer > rB2B.velocity.x ||
                         sharedForced.y + sharedForceBuffer < rB2B.velocity.y || sharedForced.y - sharedForceBuffer > rB2B.velocity.y)
                         {
                             sharedForced = (rB2B.velocity + masterRB2B.velocity) / 2f;
                             masterRB2B.velocity = sharedForced;
                             rB2B.velocity = sharedForced;
                         } else
                         {
                             sharedForced = masterRB2B.velocity;
                             rB2B.velocity = sharedForced;
                         }
                     } else if (sharedForced.x + sharedForceBuffer < rB2B.velocity.x || sharedForced.x - sharedForceBuffer > rB2B.velocity.x ||
                         sharedForced.y + sharedForceBuffer < rB2B.velocity.y || sharedForced.y - sharedForceBuffer > rB2B.velocity.y)
                     {
                         sharedForced = rB2B.velocity;
                         masterRB2B.velocity = sharedForced;
                     }
 
avatar image Jack-Idealits · Aug 24, 2020 at 01:03 PM 2
Share

That glitch occurs because the two objects always try to have the same velocity. The floating object wants to fall, but the grounded object is kept stationary by the ground beneath, thus constantly nullifying the velocity of the other object, keeping it floating. I believe a similar thing would happen when the two objects are both pushed by a uniform wind; when one gets stuck after bumping into a wall, the other one also stops, as if it hits an invisible barrier.

This is why I initially recommended working with force and acceleration instead of velocity: since being stationary means an acceleration of zero, the grounded object would add a force of zero to the other object, which would not prevent it from falling.

I don’t expect there to be any glitches as long as there is a good buffering measure (like the one you currently have in your code) that filters out small perturbations and spasmodic movements. Still, I can’t be 100% sure as I haven’t coded a shared physics feature like this. I guess you could experiment with both methods and use the one that works best. Good luck!

avatar image orangeflame Jack-Idealits · Aug 25, 2020 at 12:12 AM 0
Share

I agree that it would be better to use force over velocity but I can't find a way to just get and set force. I can add force but I can't set it to a hard value. I tired to calculate force using mass and acceleration, which was calculated using velocity and Time, and then I set it by reversing the process and manually setting velocity but, the second velocity becomes anything other than 0, the objects begin to violently oscillate along the direction of the movement with increasing speed and distance of oscillation. Below was my code attempt

 acceleration = (rB2B.velocity - lastVelocity) / Time.fixedDeltaTime;
         lastVelocity = rB2B.velocity;
         masterAcceleration = (masterRB2B.velocity - masterLastVelocity) / Time.fixedDeltaTime;
         masterLastVelocity = masterRB2B.velocity;
 Vector2 masterForce = masterRB2B.mass * masterAcceleration;
                 Vector2 force = rB2B.mass * acceleration;
                 if (sharedForced.x + sharedForceBuffer < masterForce.x || sharedForced.x - sharedForceBuffer > masterForce.x ||
                     sharedForced.y + sharedForceBuffer < masterForce.y || sharedForced.y - sharedForceBuffer > masterForce.y)
                 {
                     if (sharedForced.x + sharedForceBuffer < force.x || sharedForced.x - sharedForceBuffer > force.x ||
                     sharedForced.y + sharedForceBuffer < force.y || sharedForced.y - sharedForceBuffer > force.y)
                     {
                         sharedForced = (force + masterForce) / 2f;
                         masterRB2B.velocity = ((sharedForced / masterRB2B.mass) * Time.fixedDeltaTime) + masterLastVelocity;
                         rB2B.velocity = ((sharedForced / rB2B.mass) * Time.fixedDeltaTime) + lastVelocity;
                     } else
                     {
                         sharedForced = masterForce;
                         rB2B.velocity = ((sharedForced / rB2B.mass) * Time.fixedDeltaTime) + lastVelocity;
                     }
                 } else if (sharedForced.x + sharedForceBuffer < force.x || sharedForced.x - sharedForceBuffer > force.x ||
                     sharedForced.y + sharedForceBuffer < force.y || sharedForced.y - sharedForceBuffer > force.y)
                 {
                     sharedForced = force;
                     masterRB2B.velocity = ((sharedForced / masterRB2B.mass) * Time.fixedDeltaTime) + masterLastVelocity;
                 }
avatar image Jack-Idealits orangeflame · Aug 25, 2020 at 09:37 AM 1
Share

As part of the buffering measure, you could calculate the acceleration over longer intervals. a = dv/dt; currently your dv and dt are both the change over one frame update, and you could increase it to, say, 5 frames instead. The method is still called once per frame, but each time it is called, it calculates the acceleration over a much longer duration, which should help filter out the spasms.

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

141 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 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 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 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 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 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 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

Maintaining the trajectory of a ball when manipulating its velocity in a Breakout/Arkanoid clone 1 Answer

Convert Force into Velocity for 2D Player Jump 0 Answers

Velocity not updating object position 1 Answer

How to not get velocity by the other objects?,How to not get force by other gameobjects? 0 Answers

How to get the speed of an object? 3 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