Unity physics about collision and energy - unity3d

I have been working on a Unity ping pong game using the Leap Motion. I use rigidbody.MovePosition() to move the paddle. However, when I hit the ball (which uses gravity), the paddle launches it too far. Even when I change the masses of both, it doesn't do anything.
What variable should I change to reduce this energy going into the ball?

From the following link.
"MovePosition will put your object at the target location, no matter what. It may push aside other objects in a realistic way, or may blast them out of the way, or may just pass right through them. But it will gladly move you through a solid wall or a mountain.
If you're using MovePosition on a rigidbody to add from where you currently are, it looks like AddForce. With AddForce, the physics step does all the work: applies your velocity, sees the collision and handles the bounce. With MovePosition, the physics step sees you're mysteriously overlapping a solid object. If it isn't too much, it will bounce you apart."
You won't need to use MovePosition. Instead, you can figure out the direction of the shot (based on the position of the ball relative to the paddle). Then you can add an impulse force in that direction to the ball.
Pseudo-code (from the following link):
Vector3 shootDir = ballPosition - paddlePosition; // Calculate direction of the shot
shootDir.Normalize(); // Normalize the shot vector
ball.AddForce(shootDir * speed, ForceMode.Impulse); //Add impulse force in correct direction.
Credit due to Owen Reynolds and Tim Michels.

Related

Unity 3D object with Rigidbody sliding

I have a cube with Rigidbody attached to it would slide slightly whenever I pressed the play button. If I leave it for awhile, it would slide to other side of the screen.
Anyone know how to solve this problem without using the "freeze position"? I don't know what I messed up in my project...
This is what the object looks like:
Note: I need to use the gravity.
Thank you!
Heh! The solution here is:
You had a rigidbody on the floor :)
You don't do that :) Never.
If the "floor" surface is flat, then,
it will not slide.
You've got something strange going on, such as
"floor" is NOT flat
a feature like "Wind" turned on
perhaps other objects invisible in the scene you have forgotten about are nudging it
PhysX does not have a "mind of it's own". There is some simple reason it is moving.
Let's say the "floor" is indeed on an angle, so it SHOULD move, but you WANT it to NOT move.
What you obviously do:
Just as in the real world, put something there to stop it moving.
A small invisible wall will do the trick. That's PhysX!
Usually rigidbody sliding happens when a lower rigidbody has lower mass than a higher rigidbody (forcing down the lower rigidbody). Typical problem with player having say mass 80 jumping on a cube with mass 1. In this case the collision is so violent that the cube will probably fly out (not only slide).
The situation is very similar to the real world. Try to stay on a box of milk if you have 120 kg (ok, ok, 80 :) ).
When you try to eliminate this behavior, you need either increase the mass of the lower object or decrease the mass of the higher one or set the lower rigidbody to kinematic.
The solutions above is not proper way of solving the problem. Unity has more features of physics than mass. If you get sliding on movement or because of other objects you should add proper drag value on your rigidbody. For example , lets say you have blocks spawning over top of other blocks and this creates horizontal sliding. In my case I add drag of 1 to the objects which has mass of ~ 1 kg. It depends on the scene and you should try different values on your case. Do not use bigger values and angular drag if it is not important.

SpriteKit move node with physics rather than updating position

My main character moves by touching and holding him and then moving your finger left or right to move the character. To do this I just simply update the node's x position (walks left and right on a flat surface) in touchesMoved() with the x position of the touch location, and apply an animation depending on the direction he's moving.
I want to kind of take this to the next level and accomplish the same effect, but using physics, so that when I'm done moving him and release my finger, he may slide a little bit in the direction he was moving given the speed I was moving him at, if that makes sense. Does anyone know how I can accomplish this effect?
Would I have to do as I'm currently doing and update the position as it moves, but also apply a force/impulse at the same time? Kind of confused on how to approach this
Moving the physics body via force, impulse, or velocity will automatically update the player position.
So you will have to play around with the correct way to accomplish your goal. But based on this, what I would suggest is replace your .position code with .physicsBody!.velocity code in your touchesMoved. Then, on your touchesEnded, you can apply a bit of an impulse to give the player that little bit of an "on ice" effect to keep them going a tad.
You will need to experiment with how much velocity you want to get the character to move at the correct speed, and then you will need to play with the impulse figures as well to get it just right.
This could get a bit tricky though, in touchesMoved... because at some point you will want to reset the velocity to 0 (so they stop moving when your finger stops).
To do that, you will need to to use the .previousLocation from your touch object, and compare the distance of X moved. if the distance X moved is >0 (or some deadzone threshold) then apply the velocity; if the deltaX is 0, then set the velocity to 0.
This may actually be more complicated than just using .position to move the character, then having the character slide a bit with physics on touchesEnded.
You will have to play with it to get it right.

Unity 2D Bounce Back moving object when colliding with another object

I have an object that, after receiving its respective input, it moves this way:
mov = new Vector3((Input.GetAxis("Horizontal") * vel), 0, 0);
transform.position += mov;
But, I want it to bounce back, once it collides with an object.
I´ve made the procedures already (OnCollisionEnter2D(Collsion2D col){bla bla...}), but I need help with what happens on the collision (bouncing back the object)....
I´ve tried giving the collided object a bouncing material, but it just slows it a bit, my guess is that because of the constant force given by the acceleration.
Greetings.
If you move the object with transform.position what you are doing is basically a "teleport" so it will ignore the bouncing material. If you want it to bounce you have to write the physics code to detect a collision and change the movement or you can do addforce to move the object and it will detect collisions and react automatically.
you are teleporting the object at the current time. instead you should use the Rigidbody.addForce this will add a force in the specified direction thus if you do the opposite direction will "bounce" of the object. Another option would be to create a physics material then not bother with the code.
You are not using materials, right?
See if the content of this post may help you, the OP is using a formula using Raycast and the answer guides him to use the Raycast with Layers Maks:
2D bouncing formula doesn't work properly
There is this one also with fixed angles (like Pong), but it uses material (with values: friction: 0, bounciness: 1):
https://gamedev.stackexchange.com/questions/70294/get-gameobject-to-bounce-of-colliders
But if nothing makes sense and you are going crazy and might want to start from zero, there is this official video tutorial on bouncing and sliding in 2D:
https://unity3d.com/learn/tutorials/modules/beginner/2d/sliding-bouncing-2d

Slope limit on player movement

I use Unity3D and I have a player with a rigidbody. I add force tto the body for moving the player. My player walks over a terrain but is able to walk up mountains that are to steep to climb. I want to limit the player so it cannot walk up a slope that is to steep.
I know there is a CharacterController component that has this functionality, but I have to use the rigidbody, so I want the same but on my rigidbody.
I can get the normal of the triangle I am standing on, and calculate its angle, but I cannot seem to make the player stop moving up the slope. Only make the player stop moving (which makes the player unmovable once it hits a angled slope)
Any ideas how to solve this problem?
It's difficult to answer without more details on how you're using the physics engine. How/Are you using friction? What angle are you applying the force? Is it always horizontal or at the angle of the floor? Does the player have a mass?
Anyway I can think of a few ways to solve this
Go the pure physics route. Using player mass, friction, force angle, gravity, etc. Get the physics to handle these situation for you. This may take a fair amount of time and programming.
Keep the rigid body but fake the forces. Scale the force you are applying to the body of the player with the angle of the triangle the player is on. You can either use trigonometry to work out what you should apply or your own mapping. By your own mapping I mean set an angle where 0 force is applied (say 45 degree) and do a linear(or non linear) scale on the force applied so on flat ground force is 1 and at 45 force is 0.
Don't use rigid bodies. There is a reason most games don't use rigid bodies to control characters. It's hard and complicated and most of the time not worth the time it would take. Of course I don't know the details of your project so if this isn't an option, fine.
Hope that gives you some things to think about.

Physics vs graphics fighting each other (box2d)

so I have a ball (sprite subclass) that can be dragged around the screen and updates it body to tell the world its position.
The problem is, when I apply a force to the ball while the ball is being touched (thus being controlled by a finger), I have two pieces of code fighting against each other to update the sprite's visual position.
The world stepper is trying to follow through the physics and update the ball's position. The touch methods however are also trying to update the ball's body and graphic position. Ideally, when touched I would like to kill off any physics affecting the ball.
So what exactly should I be trying to do to consolidate this? This is also creating issues for collisions and filtering. Any help appreciated. Thanks
Do you want the ball to have an accurate physics simulation? If not, you could always use the SetTransform method of the b2body class like this.
CGPoint ballLocation = ;//use the touched location for this
b2Vec2 vecBallLocation = b2Vec2(ballLocation.x / 32, ballLocation.y / 32);//calculate this on your own
b2Body * ballBody = ;//replace this variable with your ball's b2Body;
ballBody->SetTransform(vecBallLocation, ballBody->GetAngle());
Do not set the ball sprite's position manually. Leave this up to the physics simulation. Your code will get really messy over time if you have to keep track of what sprites you set the position of manually and which ones use the physics simulation to update their positions. This way is also much easier.
When the physics object is being dragged, set its velocity and angular velocity to 0,0 before running the physics step simulation. You may also want to temporarily get the physics object's position, then step, then set the body's position back, then apply whatever touch dragging offset you got from moving the finger to the body.