• 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 x4637x · Mar 26, 2018 at 05:01 AM · collisionphysicsrigidbody

Rigidbody wall slide without velocity loss

I've some test scene set up like this, once unity enter play-mode sphere 1 & 2 will start moving forward using the same velocity. Sphere 1 will bump into some cubes along the way. The outcome I expect is both spheres will always have the same z position value, which means no speed loss during the collision for sphere 1.

Scene set up

Rigidbody of both sphere setting are : Mass = 1, Drag = 0, angular drag = 0, use gravity = false,is kinematic = false, Interpolate = Interpolate, Collision Detection = Continuous.

Physics material of both cubes and spheres are using :

Dynamic friction = 0, Static friction = 0, Bounciness = 0, Friction Combine = Minimum, Bounce Combine = Maximum.

I have been using following code to handle collision and velocity changes :

     private void OnCollisionEnter(Collision other)
     {
         Debug.Log(body.velocity);
         body.constraints = RigidbodyConstraints.FreezeRotation
                            | RigidbodyConstraints.FreezePositionY;
         body.velocity = Vector3.forward * 5f + Vector3.left * 5f;
         Debug.Log(body.velocity);
     }
 
     private void OnCollisionExit(Collision other)
     {
         body.constraints = RigidbodyConstraints.FreezeRotation
                            | RigidbodyConstraints.FreezePositionY
                            | RigidbodyConstraints.FreezePositionX;
         Debug.Log(body.velocity);
     }

According to the log message, the velocity of sphere 1 has been reduced most of the time when it collide with the cude in OnCollisionEnter(). log messages

As result, sphere 1's Z position is incremetally behind sphere 2.

Is there something I been missing out or did I missunderstood how velocity of a rigidbody work?

15220398521.png (27.6 kB)
1522036917.png (20.8 kB)
Comment
Add comment · Show 1
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 x4637x · Mar 26, 2018 at 05:15 AM 0
Share

$$anonymous$$inimum test package

test.zip (4.7 kB)

2 Replies

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

Answer by x4637x · Mar 26, 2018 at 10:47 AM

In case anyone has the same problem, I've managed to fix this with the following script :

 using UnityEngine;
 
 public class TestBoundaryCollision : MonoBehaviour
 {
     public float Speed;
     public bool Moving = false;
     private Rigidbody body;
     private SphereCollider sc;
     private RaycastHit castHit;
 
     // Use this for initialization
     void Start()
     {
         body = GetComponent<Rigidbody>();
         sc = GetComponent<SphereCollider>();
     }
 
     private void FixedUpdate()
     {
         if (!Moving)
         {
             return;
         }
 
         if (Physics.SphereCast(body.position,
                                 sc.radius + Speed * Time.fixedDeltaTime,
                                 transform.forward,
                                 out castHit,
                                 Speed * Time.fixedDeltaTime))
         {
             body.velocity = new Vector3(Mathf.Sign(castHit.normal.x) * Speed, 0f, Speed);
         }
         else
         {
             body.velocity = transform.forward * Speed;
         }
     }
 }

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
avatar image
0

Answer by Ramlock · Mar 26, 2018 at 05:33 AM

The problem is that you're freezing the X position whenever it's not colliding, so the instant it does collide, it has no option but to come to a stop, untill your OnCollisionEnter script enables it to move again. That's why the debug shows a low Y velocity combined with a zero X velocity first, then a correct velocity on both at the end of the method (in the second debug)

Try removing the FreezePositionX altogether, and instead OnCollisionExit just make it so body.velocity = Vector3.forward * 5f;

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 x4637x · Mar 26, 2018 at 06:07 AM 0
Share

Thanks for your reply, but I do start with what you are suggesting here, the vertical velocity after the collision is half of the velocity before the collision, a result as (-2.5, 0, 2.5). And this is not what I trying to achieve.

Even though the magnitude of the resulting velocity is incorrect, which I am expecting (-5.0, 0, 5.0).

avatar image Ramlock x4637x · Mar 26, 2018 at 06:19 AM 0
Share

That is to be expected from physics regardless of friction. The problem here is conservation of momentum. You're expecting the object to generate sideways movement without spending it's forward velocity.

The best you can do from what I see is to set your velocity in a FixedUpdate ins$$anonymous$$d of OnCollision. Perhaps this will work for you:

      private void OnCollisionEnter(Collision other)
      {
          colliding = true;
          Debug.Log("CollisionEnter");
      }
  
      private void OnCollisionExit(Collision other)
      {
          colliding = false;
          Debug.Log("CollisionExit");
      }
 
     private void FixedUpdate()
     {
          if(colliding) body.velocity = Vector3.forward * 5f + Vector3.left * 5f;
          else body.velocity = Vector3.forward * 5f;
     }
avatar image x4637x Ramlock · Mar 26, 2018 at 06:37 AM 0
Share

You just give me some idea to solve this, but first I need to point it out that both OnCollisionEnter() and OnCollisionExit() are called after fixedUpdate and physic simulation.(According to this unity doc page)

So what you paste up there will still be using a slower vertical velocity for a fixedUpdate. I might need to find a way to do my own collision detection before physic simulation.

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

170 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 avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Unity Physics Collision Execution Order Error? 1 Answer

Vibrating GameObjects 0 Answers

How do I "remove/disable" collision? 3 Answers

Collision detection for low relative velocity, high world velocity rigidbodies 2 Answers

Influence of the collision on the other object 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges