How does SpriteKit physics move bodies? - sprite-kit

How does SpriteKit's physics engine (Box2d) move bodies and apply gravity to them?
is it just the standard:
velocity = velocity + gravity
position = position + velocity * deltaTime
or is there a more complex equation.
I ask this because I am trying to calculate the trajectory of the body and plot it.

Simplified, this is correct. However there can be other forces acting on a body (collisions, joints) and thresholds (ie stop moving if velocity below threshold, etc) and floating point rounding errors can add up.
So if you're looking for a forward calculation it depends on how precise it needs to be.
The most precise option would be to actually run the simulation to advance it to see where bodies will be - however since SK doesn't give you the Box2D sources this can't be done, ie you can't copy the world state and advance it manually in a copy of the current world.

Related

How to make object pull another in Unity 2D

So I'm trying to simulate orbital mechanics in Unity 2D. I have a ship and Moon model in scene. I calculated the sphere of influence, and if the distance between the Moon and ship is smaller than sphere of influence, the gravity will effect. Problem is;
I can't get gravity affect working.
I've tried using AddForce method, but since it requires Vector2 elements and I calculate my force as float (I use Newton's law of gravitation formula and I get a float), I don't know how to include my float force in Vector2 force.
force = (GravitationalConstant * ((planetMass * ship.GetComponent<Rigidbody2D>().mass)/Mathf.Pow(Vector3.Distance(ship.transform.position,transform.position),2)))/(realityConstant * forceReducer);
if (Vector3.Distance(transform.position,ship.transform.position) < SOI/realityConstant){
ship.GetComponent<Rigidbody2D>().AddForce(new Vector2((float)force,0f));
}
This code makes Moon pull the ship to itself only from left side. When ship passes Moon, it keeps pushing it to right. Not to itself.
I need a fix, that makes Moon pull the ship to itself everytime, with a specific force. How do i make this happen?
Any idea would be helpful.
Thanks a lot!
Force is applied using a vector. You have the magnitude of your vector but not its direction. You can calculate a direction by subtracting moon position from the ship position:
ship.GetComponent<Rigidbody2D>().AddForce((Moon.transform.position -
ship.transform.position).normalize * force);

Get path points on applied impulse

I added impulse to GameObject like
rigidbody.Addforce( SomeVector3, ForceMode.Impulse);
and my gravity multiplier is 4. How to calculate points of my path before I apply that impuls on body ?
I have all data like mass, gravity multipiler and so on and I would like to draw that path before apply impulse so I need number of points.
Using common physics you are of course able to predict the path the object will go. The problem is, your formulas, ticking etc. will most likely not exactly be the same as the ones Unity uses internally, so your results won't be exact.
Only thing I can think off is having a second, invisible, version of your GameObject and apply the impulse to it and track its position, then display the resulting path for your visible GameObject. You might consider accelerating Unity's time using Time.timeScale during prediction, so you don't have to wait too long for the simulation's results.

How to make Gravity for multiple planets in Unity3d

What i'm looking to do is something similar to our solar system, where you are gravitically drawn to one planet till you leave it's pull, and then once you're on another planet be drawn to that gravity.
I have found many entries online about how to create gravity for a single planet, but none i've found work for multiple sources.
Any help would be GREATLY appreciated.
Projects I've already looked at were mainly for single planet gravity.
unity 3.3, create local gravity on object
http://answers.unity3d.com/questions/13639/how-do-i-make-a-small-planet-with-gravitational-pu.html
http://answers.unity3d.com/questions/701618/how-could-i-simulate-planetary-gravity-that-has-an.html
This could be done easily by adding a normal force relative to the planet on the surrounding objects.
According to physics of Universal gravitational force you can calculate the gravitational force. Then calculated the normal force at the moment and add the force.
void FixedUpdate(){
// Do the Force calculation (refer universal gravitation for more info)
// Use numbers to adjust force, distance will be changing over time!
forceSun = G x (massPlanet x massSun)/d^2;
// Find the Normal direction
Vector3 normalDirectionSun = (planet.position - sun.position).normalized;
// calculate the force on the object from the planet
Vector3 normalForceSun = normalDirection * forceSun;
// Calculate for the other systems on your solar system similarly
// Apply all these forces on current planet's rigidbody
// Apply the force on the rigid body of the surrounding object/s
rigidbody.AddForce(normalForceSun);
// .... add forces of other objects.
}
With various m1, m2 values you will be able to make the system more realistic. As an example make the object move/accelerate towards the planets with higher mass.

Unity physics about collision and energy

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.

How many pixels is an impulse in box2d

I have a ball that you blow on with air. I want the ball to be blown more if it is close to the blower and blown less if it is farther away from the blower. I am using box2d and I am using the impulse function."body->ApplyLinearImpulse(force, body->GetPosition())". I can't seem to find a formula or a way to accomplish this. If I want the ball to blow to a total distance of 300 pixels right, how could I accomplish this? Please help.
If you want to calculate the distance before simulation you have to take a look at box2d sources. When simulating the velocity of the body is modified according to gravity, extra applied forces, linear damping, angular damping and possibly something more. Also velocity relies on velocity iterations.
But I think if you want a really smooth motion (like from a blow) you'd better use applyForce function instead of impulse. But be sure you are applying the force each simulation step.
EDIT:
Also you can simulate the air resistance as:
Fa = -k*V*V. I've simulated movement in the pipe this way. Worked great.
So each step you can make something like this:
BlowForce = k1 / distance; // k1 - coefficient
Resistance = -k2 * V * V; //k2 - another coefficient
TotalForce = BlowForce + Resistance;
body->ApplyForce(TotalForce);
I am not a box 2d expert but what i would do is create a small box which is actually invisible and let the ball hit the box...if the blower is blowing more i would give more speed to the box in opposite direction. As far as 300 pixel length is concerned you have to adjust the forces and velocity such that the ball goes
300/<your_rendering_window_to_physics_world_ratio>
in physical world.
Force = mass * acceleration, so take the mass you set your body to, calculate the acceleration you want (remember to divide 300px by PTM_RATIO) and then multiply the two together.