Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[2D] Colliding more than one edge causes shaking

Discussion in 'Physics' started by Estecka, Apr 4, 2017.

  1. Estecka

    Estecka

    Joined:
    Oct 11, 2013
    Posts:
    62
    I have a Camera with a BoxCollider2d, and an object with a huge EdgeCollider2d wrapped around my playfield to delineate away areas I don't want my camera to be able to see or cross. I then put a rigidBody2d on the camera and pull it toward the player by setting its velocity.

    Overall it works like intended, the camera will follow the player really smoothly and stop when hitting the border of the map.
    My problem arises when hitting a corner of the map : when the corner of the camera's is being pulled into a concave corner of the area, it will starts shaking for as long it's pulled there.
    I tried replacing the box collider with a circle collider, (thinking I could put some "bumpers" at the corners of my camera), but similarly, the camera will keep shaking when the circle collider is pulled into colliding two edges at once.

    Tried changing the interpolation mode. Each gives a somewhat different shaking, but none does solve it.
    I set the collision Detection mode to Continuous, this option fixed a different problem with convexe corners, but still, neither option fixes the concave ones.

    The material for every collider as 0 bounciness and 0 friction.

    In case, this is the bit of code involved in pulling the camera toward it's target.
    Code (CSharp):
    1. public class PullTowardTarget: MonoBehaviour {
    2.     public float Speed = 10;
    3.     public GameObject Target;
    4.     private Rigidbody2D bode;
    5.  
    6.     void Awake () {
    7.         bode = this.GetComponent<Rigidbody2D> ();
    8.     }
    9.  
    10.     void FixedUpdate () {
    11.         bode.velocity = (Target.transform.position-this.transform.position)*Speed ;
    12.     }
    13. }
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,266
    You're setting velocity directly. When you hit a collider the physics system attempts to modify the velocity but you stomp over it each fixed update. It's never going to be stable.

    If you want to move an object to a target, use the TargetJoint2D and set its target position instead.

    You can look at my GitHub project to see this working. Look at the TargetJoint2D_MouseFollow and TargetJoint2D_MouseDrag scenes.
     
  3. Estecka

    Estecka

    Joined:
    Oct 11, 2013
    Posts:
    62
    Thank for the suggestion. Joints definitely are some handy tools I should get myself to use...
    However, even when using Target Joints, the camera will shake a when being dragged into a corner. I made a tiny project from scratch that features the problem: just play the scene, and the joint will drag the rigidbody into a corner of the room.
    Still, I find it weird how dragging it against a single edge never causes shaking...
     

    Attached Files:

  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,266
    > However, even when using Target Joints, the camera will shake a when being dragged into a corner.
    If you check out my project, you'll see that there isn't any shaking of the objects so your shaking must be related to something else.

    NOTE: I forgot to say that I can see the shaking in your project. I take a further look today.
     
    Last edited: Apr 6, 2017
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,266
    In your case, if you turn down the frequency quite low to 0.75 to 1 then it goes away and the body sleeps which indicates its not vibrating. Critical damping of 1 is essential here.

    With high forces, high frequencies and no friction, you can end-up with the solver bounding between two surfaces with no real solution. The solver obviously isn't real physics, it's trying to be approximate but above all, fast. Sometimes, there's no solution.

    I think you'll need to balance the frequency very carefully. You can also increase the iterations in the 2D physics settings but I did manage to get a nice stable solution by just changing the frequency.

    If you want to move instantly into contact then you might consider using a simple BoxCast to find the contact point and simply move there.
     
    Estecka likes this.
  6. Estecka

    Estecka

    Joined:
    Oct 11, 2013
    Posts:
    62
    Aw, tweaking phisycs numbers... :/
    Playing around with the other fields, I found reducing the max force considerabling reduces the shaking without actually slowing the camera lower than I need it to go. The default was around 10,000? Only under 0.1 did I start to notice the loss in speed, and the shaking was almost completely gone.
    Though I don't actually need an instantly moving camera, turning down the frequency also considerably slows it down, so in the end I rather sacrificed a bit of the lack of friction to finish this off.

    Thanks for your help.
     
    MelvMay likes this.