Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question RigidBody Collision not working ( using Moveposition() )

Discussion in 'Physics' started by token_tony, May 2, 2024.

  1. token_tony

    token_tony

    Joined:
    Mar 17, 2022
    Posts:
    4
    Hi , i am starting on a small project and i am already having problems , I have a capsule object that i control the horizontal movement off using the Rigidbody function Moveposition() . I have included screenshots of the player Gameobject and the walls i am trying to collide with. The player capsule simply phases throught the wall regardless of the speed at wich i am going.

    • this is the inspector view of the Player GameObject
    upload_2024-5-1_23-38-46.png

    • This is how i am currently handling movement
    upload_2024-5-1_23-40-9.png


    • And this is the Inspector view of the walls i am trying to collide with upload_2024-5-1_23-41-44.png

    I assume i have missed something mundane so i apologize in advance but I did look for problems like this online and I cannot find what I'm looking for
     
  2. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,936
    Usually you don't want to have the player's collider be a trigger. Try unselecting "Trigger" on the player Capsule Collider.
    You also probably want the player's RigidBody to use gravity.
     
    arkano22 likes this.
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,589
    In 3D, MovePosition on a Dynamic body simply teleports it to the position so you'll get collision tunneling i.e. it acts like discrete collision detection. If you step too far or beyond the center of the wall, the solver will push it out the opposite side. MovePosition in 3D was designed entirely around moving Kinematic bodies.

    This doesn't apply to 2D physics btw.
     
  4. token_tony

    token_tony

    Joined:
    Mar 17, 2022
    Posts:
    4
    Oh my , that basically solved it ,Thank you! Now the only problem i have left is that, as MelvMay pointed out , it pushes the player the other side if the speed is too high , but for now this will do perfectly and i will probably look into better detection further down the road.
    Small follow up though : Is having two colliders so i can have one as trigger a good workaround for this?
     
  5. token_tony

    token_tony

    Joined:
    Mar 17, 2022
    Posts:
    4
    Yup i can see it now , i thickenned the wall and ,althought if you keep pushing forward , you end up on the other side ; if you stop in the middle , you get shoved out of it ! I will keep the speed at 10 for now , Thanks for the Info !

    (EDIT!!): Indeed the problem was using MovePosition for movement altogether , by simply changing the last line of code to this :

    rb.velocity =( moveDir*speed * Time.fixedDeltaTime);

    It works great ! (Using the rigidbody component's continuous Detection option on continuous)
     
    Last edited: May 2, 2024
  6. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,536
    A couple of notes here:

    First, remove Time.fixedDeltaTime from the calculation. Velocity is a time-independent magnitude that is later integrated by the solver. Simply set the value of "speed" to the value in m/s you want your object to move at.

    The proof of this is that if the time step is modified (Project Settings > Time > Fixed Timestep), then the velocity of the object in your game will change accordingly. If you remove Time.fixedDeltaTime from the calculation, then the velocity will be the same no matter the time step.

    Second, modifying rb.velocity means overriding the results of the physics solver, so it might cause other issues in the future. A more consistent way to set the velocity of the rigidbody is using Rigidbody.AddForce (or any of its variants) with the parameter ForceMode.VelocityChange. Simply applying the difference between the expected velocity and the current velocity will do it. In your code, it would be:
    Code (CSharp):
    1. rb.AddForce(moveDir * speed - rb.velocity, ForceMode.VelocityChange);
     
    MaximeDGoulet and MelvMay like this.
  7. token_tony

    token_tony

    Joined:
    Mar 17, 2022
    Posts:
    4
    Thank you , that bit of code is working wonders !