Hey everyone.
So I’ve been messing around with the SurfaceEffector2D. I tried a little experiment. My scene has two game objects - one is a cube with a Rigidbody2D (cube01) and another is a cube with the SurfaceEffector2D (cube02). Rigidbody2D and SurfaceEffector2D still have their default values.
I set the Speed value of the SurfaceEffector2D to 2, ForceScale to 1 and set cube01 above cube02 so that when I play the game cube01 will fall on cube02 and come in contact with the effector. I also wrote a script to measure the velocity of cube01’s Rigidbody2D. When I played the game and cube01 landed on cube02 and started moving, the velocity on the X Axis showed 1.92… I assumed that maybe because gravity was affecting it, the velocity on the X axis wasn’t 2. Then I unchecked Use Friction on the SurfaceEffector2D, and ran the game again. This time the velocity on X axis was 2. cube01 and cube02 don’t have a Physics Material 2D attached to them.
So why does having Use Friction checked still affect the speed of the Rigidbody2D?
If you don’t specify a PhysicsMaterial2D on a Collider2D and you also don’t specify a global one in the Physics2D settings then the defaults are Friction = 0.4 / Bounce = 0.
Oh, I see. Thanks for that.
I also have a doubt about ForceScale. So I understand that ForceScale scales the force that is applied when the effector attempts to attain the specified speed along the surface. I tested this out. Speed = 2, ForceScale = 1. The velocity on the X axis was 2. I took the ForceScale down to 0.1, and it started at 1.8… and gradually increased to 2, and then remained at 2.
Then I took it further down, to 0.01, and something different happened. The velocity on the X axis started at 0.2… and gradually kept increasing, but when it reached to 1.8…, it slowed back down to around 0.2… and then started gradually increasing again. And the process just keeps repeating. I paused the game and went frame by frame and found out it wasn’t going down to 0.2, it was going down to 0.
Why is this happening?
Force Scale is just that; when the impulse force has been calculated, it is scaled by this value.
You should understand that the Speed the SurfaceEffector2D is trying to maintain on anything contacting its collider will cause target objects to either speed-up or slow-down depending on their current speed.
When ForceScale left at 1, you can guarantee that the force applied will move the speed of the target object closer to the desired speed but not past it. When you scale-up the force, you can cause it to ‘overshoot’ so go slightly faster/slower and potentially oscillate and never quite reach the speed.
This is what you seem to be describing however you’re talking about scaling down the force i.e. a force below 1 so I have no idea why you’d see that.
Here’s the code that scales the impulse-force so as you can see it’s a simple scaling.
// Calculate the required target impulse force.
b2Vec2 targetImpulseForce = desiredTangentVelocity - targetTangentVelocity;
targetImpulseForce *= m_ForceScale * targetBody->GetMass ();
// Calculate force target.
const b2Vec2 forceTarget = m_UseContactForce ? worldManifold.points[0] : targetBody->GetWorldCenter ();
// Apply impulse force to target.
targetBody->ApplyLinearImpulse (targetImpulseForce, forceTarget, true);
The only things that could conceivably cause the effect you describe is if something else was also appying a force or changing the velocity of the target or telling the effector to apply the force at the contact point (which causes rotation) also can cause that effector.
So, just a side question…I’ve never used the → so after seeing your code I did some research and found out it is used with unsafe code. I was wondering, why make use of unsafe code? I’ve never tried it so I don’t know.
Back to the topic, I don’t wanna further complicate things but I tried increasing the ForceScale to 0.1, 0.5 and even 0.9. In all cases, the velocity on the X axis went upto 2, but after a few seconds the velocity changed to 0, and then started gradually increasing again, and then process repeated again and again.
If you’d like to recreate the scene, all you need to do is create a Quad and add a BoxCollider2D and SurfaceEffector2D, set it’s scale on the X axis to 200 so that it’s quite long. Then create another Quad and add a BoxCollider2D and Rigidbody2D, and position it so it is above the Quad that has the SurfaceEffector2D. Write a small script to measure the Rigidbody2D’s velocity.
SurfaceEffector2D values:-
UseColliderMask = false
Speed = 2
SpeedVariation = 0
ForceScale = 0.1
UseContactForce = false
UseFriction = false
UseBounce = false
You’re done.
If you’d like I can create a Bug case.
I get that ForceScale scales the force, meaning depending on the value it may or may not take a certain amount of time to reach the Speed. What I don’t get is why it keeps going back to 0 every few seconds.
The code I posted is C++. It’s a snippet of the native C++ code that is part of the SurfaceEffector2D component.
I tried your settings and I don’t get that at all. I get what I expected which is the object falling onto the surface then slowly moving to 2 then staying there. Sounds like something else is slowing/stopping the Rigidbody2D.
I would say if you can create a simple reproduction case, stick it in a bug report and give me the case number then I can take a look at it for you.
Okay, I just created another project, to recreate the scene. But this time the velocity didn’t go down to zero. It rose up to the Speed value and just stayed there. The project I was working in previously is the project that I created to test out 2D Physics features. I had been playing around with some values from Physics2D, Time, etc. settings for testing out stuff. I could be wrong, but that could be what was causing my problem. My bad, should’ve tried another project. My apologies for wasting your time.
One last doubt. In the new project I noticed that the velocity on the X axis does gradually increase to Speed value, but in certain cases, stops short by a tiny amount and stays there. Like 0.000001, 0.000002, 0.000003, etc. So if Speed is 2, and ForceScale is 0.01, the velocity on the X axis might stop at 1.999994 or something like that, instead of 2. However, if ForceScale is 0.1, the velocity on the X axis reaches 2 eventually. This is totally random.
Speed 3, ForceScale 0.1, Velocity X axis 2.999999.
Speed 4, ForceScale 0.1, Velocity X axis 3.999999.
Speed 5, ForceScale 0.1, Velocity X axis 4.999998.
Speed 6, ForceScale 0.1, Velocity X axis 5.999998.
Speed 7, ForceScale 0.1, Velocity X axis 6.999998.
Any idea why that might be happening?
Just looks like single-precision floating-point errors; those are very small values and not something to worry about. Indeed, that velocity difference is 1 micrometer/second (50 times smaller than a human hair) to the physics system which is way below its movement threshold.
Thanks @MelvMay !