• 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 /
  • Help Room /
avatar image
0
Question by UrusVerra · Jan 08, 2018 at 11:57 AM · movement2d-platformerrigidbody2dkinematicmoveposition

Kinematic 2D Rigidbody movement: Rigidbody2D.MovePosition vs Rigidbody2D.position problem

I'm trying to use 2D physics and character controller solution from this Unity live training (parts 3--6).

Basic idea is that script, which describes any moving object's behaviour is inherited from PhysicsObject script, that handles gravity and collisions.

However, this solution uses Rigidbody2D.position in FixedUpdate to move the object, which causes visible lag whenever there are moving objects other than the player. Basically, when player stands still, everything else moves smoothly, but when player moves, only player moves smoothly, everything else moves jerky.

After running a few simple tests (moving two objects at the same time using different methods) I found that only two solutions give smooth results: -moving objects WITHOUT rigidbody through transform.position in Update -moving object with Kinematic Rigidbody2D with Interpolation set to Interpolate via Rigidbody2D.Moveposition in FixedUpdate.

So I'm trying to change the script according to second variant. However, when I replace line

 rb2d.position = rb2d.position + offset;

with

 rb2d.MovePosition(rb2d.position + offset);

Character and objects stop moving on horizontal axis. Character still responds to input (animation plays correctly), and he can jump, but he doesn't change position.

But! If I replace offset with any new Vector2() the objects glide along x axis without any problems.

I checked through Debug.Log if offset variable is being calculated correctly, and it is, however, nothing changes.

The MovePosition line is placed inside the method Movement(), which, in turn, is inside FixedUpdate().

The question is, why isn't RigidBody2D.MovePosition() working with calculated variables?

The FixedUpdate and Movement methods:

 void FixedUpdate ()
     {
         targetVelocity = Vector2.zero;
         ComputeVelocity();                     //velocity input
 
         velocity = velocity + gravityModifier * Physics2D.gravity * Time.deltaTime; // gravity
         velocity.x = targetVelocity.x;
         
         grounded = false;
         Vector2 deltaPosition = velocity * Time.deltaTime;
         Vector2 moveAlongGround = new Vector2(groundNormal.y, -groundNormal.x);
 
         Vector2 move = moveAlongGround * deltaPosition.x;
         Movement(move, false);
 
         move = Vector2.up * deltaPosition.y;
         Movement(move, true);
     }
 
 protected void Movement (Vector2 move, bool yMovement)
     {
         float distance = move.magnitude;
         if (distance > minMoveDistance)
         {
             int count = rb2d.Cast(move, contactFilter, hitBuffer, distance + shellRadius);
             hitBufferList.Clear();
             for (int i = 0; i < count; i++) {
                 hitBufferList.Add(hitBuffer[i]);
             }
             for (int i = 0; i < hitBufferList.Count; i++)
             {
                 //------------HANDLING SLOPES-------------------
                 Vector2 currentNormal = hitBufferList[i].normal;
                 if (currentNormal.y > minGroundNormalY)
                 {
                     grounded = true;
                     if (yMovement) 
                     {
                         groundNormal = currentNormal;
                         currentNormal.x = 0;
                     }
                 }
                float projection = Vector2.Dot(velocity, currentNormal);
                 if (projection < 0)
                 {
                     velocity = velocity - projection * currentNormal;
                 }
                 //----------------------
                 float modifiedDistance = hitBufferList[i].distance - shellRadius;
                 distance = modifiedDistance < distance ? modifiedDistance : distance;
             }
         }
 
         Vector2 offset = move.normalized * distance;
 
         //rb2d.position = rb2d.position + offset;      //This line works with jagged movement
 
         rb2d.MovePosition(rb2d.position + offset); //This line doesn't work at all
 
     }

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

Answer by Krackd · Apr 22, 2018 at 12:42 AM

I got the exact same issue. The MovePosition method is used to register a desired position. The actual position will be computed next frames using interpolation. So we need to call MovePosition only once.

MovePosition is called twice in this code. Meaning that the first call (x movement) is overriden with the second call (y movement). So you need to modify a little to first compute the desired position, then call MovePosition at the end of fixed update.

 public class PhysicsObject : MonoBehaviour
 {
 
     // ...
     private Vector2 desiredPos;
     // ...
 
     void FixedUpdate()
     {
         // ...
 
         desiredPos = rb2d.position;
 
         Movement(move, false);
 
         move = Vector2.up * deltaPosition.y;
 
         Movement(move, true);
 
         rb2d.MovePosition(desiredPos);
     }
 
     void Movement(Vector2 move, bool yMovement)
     {
         // ...
 
         Vector2 offset = move.normalized * distance;
         desiredPos = desiredPos + offset;
     }
 
 }
Comment
Add comment · 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

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

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

How can I move a Kinematic Rigidbody2d along the x-axis? 1 Answer

Mouse determines direction player moves, W makes them go that direction. 0 Answers

How do I keep rigidbodies from pushing each other? 2 Answers

Cant get dash attack working 0 Answers

Move RigiBody2d character to mouse (touch) position 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