Box2d - Giving an object attraction / gravity - iphone

I am using Box2d to simulate a top-down space like environment. I have an object that has an impulse applied and will be flying (through space) near to a "planet". The world itself has no gravity but I would like to set up Planets and Stars with individual gravity such that other dynamic objects will fall / be pulled in towards them. How can I achieve this?

If you have small count of bodies/stars you can just apply gravity forces to your bodies each time before calling Step() function.
But I think it will become really slow if the system gets big. If your stars and planets are not moving you are able to precalculate the total gravity force in each point of 2D space. Store this precalculated values of gravity in some 2D array (with some step) and then apply the forces from this lookup table

Related

Universal joint physics simulation in unity

I‘m trying to create real physics simulation of the universal joint in unity. In my case universal joint is in vertical position. The whole mechanism consists of four objects: white ceiling, green shaft, blue universal joint and red shaft. All parts have Rigidbody component, with specific mass (ceiling – 1kg, green shaft – 0,05 kg, blue universal joint - 0,01 kg, red shaft – 0,05 kg). The mass of center of the parts are represented in the pictures. All objects dimensions are NOT scaled and represent the real dimensions of an object in cm. The Box Colliders or Mesh Colliders were not added to the objects.
Green shaft center of mass point, Blue universal joint center of mass point, Red shaft center of mass point
The parameters for all objects are represented in the pictures: Green shaft parameters, Blue universal joint parameters and Red shaft parameters. To the ceiling object only Rigidbody component was added with an “Is Kinematic” option, without the “Use Gravity” option. One Fixed Joint and two Hinge Joints are used for objects. My aim is to create realistic physics behavior of this universal joint in simulation. For example, while playing the scene I want to be able to move the red shaft end, let go it and see how because of gravity and friction red shaft swings back to initial position. I want to do this with object components and project settings, not with a script if possible. If I succeed with universal joint physics I will later plan to add a point on the red shaft object end, which would have Constant Force component and would pull the red shaft end on demand with force to the certain direction. But the force which would pull the red shaft end would be based on real measurements.
The problem that I’m currently facing right now is with the object swinging back to initial position. If I leave Rigidbody and Hinge Joint parameters as it is represented in pictures and try to move red shaft end in scene play mode, the red shaft and blue joint swings back to initial position very very slowly. Like it would have no mass or would have very high friction. But if I turn on red shaft and blue Use Spring parameter in the Hinge Joint and set Spring value for example to 0.2 the shaft as expected goes back to initial position much faster. I also noticed that if I increase object Scale parameters (increase object size) for example from 1 to 100 it swings faster without the spring parameter turned on.
My first question which component or project parameters have the most impact on pulling object down in gravity direction?
Is where more friction friction parameters about which I should know while creating this universal joint model? Because so far I have changed only Drag, Angular Drag to 0, I have created a PhysicMaterial with almost no friction and added it to Default Material field in Project Settings->Physics. I have increased Default Solver Iterations and Default Solver Velocity Iterations almost to the maximum.
My third question would be, is it even possible to create a realistic universal joint shaft swinging without Spring option turned on in the Hinge Joint? Or should I better write the script that would define the red shaft swinging with gravity behavior?
First, Unity physics are not real physics, they are real-looking physics.
Second, Unity units are typically assumed to be in meters. When you set a position to <1, 0, 0> you should assume your object is at 1 meter in x.
Third, Unity physics uses colliders to determine volumes, for the purposes of moments of inertia.
So, when you say that
The mass of center of the parts are represented in the pictures. All objects dimensions are NOT scaled and represent the real dimensions of an object in cm. The Box Colliders or Mesh Colliders were not added to the objects.
It makes me think that (1) you are using the wrong scaling, like 1 = 1 centimeter instead of the assumed 1 = 1 meter, and (2) you're preventing Unity from being able to really run the physics calculations correctly because you're not providing volumetric information to the physics engine (which again is done via the collider volumes).
Also, your masses seem very, very, very small. You've got the universal joint at 10 grams, which is really not much at all.
You're seeing better results when you add a spring because the spring is adding a force, where your weights are small and your missing colliders are failing to do much with physics.
I would suggest adding mesh colliders and increasing the weights to get the behavior you want to see.

Why a big moving attractor object gives a slingshot to other object with using gravity formula rather than holding it?

I have a big spherical Gameobject which moves forward in 3D with constant velocity. I have other spherical objects that other big object needs to attract to itself. I am using Newton's law of universal gravitation formula to attract other objects, but as expected, other objects are doing a slingshot movement much like the space shuttles doing when needed with other planets' orbits to accelerate.
I actually want a magnetic effect that without taking the masses into account, all other objects will be catched by the big object. How can I do that? Do I need a different formula? Or do I need to change the movement behavior of the objects altogether?
If I got it right you expect to have something like this: https://www.youtube.com/watch?v=33EpYi3uTnQ
You can do a spherical raycast or have an sphere collider as trigger to detected the objects that are inside of your magnetic field.
Once you know those objects you can calculate the distance from each of them to the magnetic ball.
You can make an inverse interpolation to know how much strength/"magnetism" is getting into that object.
Then you can apply some force on the attracted object towards the magnetic ball's center.
Something like this algorithm:
var objectsInsideField = ListOfObjects;
foreach (o in objectsInsideField) {
var distance = (o.position - center.position).magnitude;
var strength = distance / fieldRadius; // fieldRadius == spherical radius
o.AddForce(dir: o.position - center.position, strength: strength)
}
Of course, you need to do some adjustments and probably add some multipliers to make the force to be meaning.
The final result should be: for each sequential frame, if the object is inside the magnetic field it moves towards the center a bit. The next frame it should be even close to the center so the strength is even bigger.. and so and so.
First of all, since the big objects is moving with constant velocity, a coordinate frame with axes parallel to the axes of the original coordinate system will be moving uniformly with constant velocity, so this new moving coordinate system is also inertial and you can write all your equations of motion in it, calculate everything with respect to it, and at the end you add the uniform movement to the results. The benefit is that the big object is stationary in this coordinate system, so simpler physics applies.
The slingshot effect occurs most likely because your objects are treated as mass-points, rather than bigger 3D entities (like spheres), for which the centers of mass never get too close enough. Hence maybe some sort of collision detection may eliminate this problem, especially if you decrease significantly or kill completely the elastic collision resolution.
All of what I am saying is a bit speculative as I have no access to details.

How to change game speed in mid development without touching the Timescale in Unity (2D)?

I have a game similar to Sand balls and I was wondering how can I speed up the game a bit without touching the timescale? A nice and somehow correct approach would be to scale down all my objects so gravity can also "affect" the drop movement. I already tested that and works as expected, except I have to apply that for 100+ levels... and would break some prefabs (a mass level editor to scale by bounding box would work but that's another story)
On the other hand, I have timescale but feels like it's the incorrect approach since it also affects animations and leads to unwanted behaviors.
So... do you know any other ways to speed up the game?
If objects is falling down, you can increase gravity. Or without touching timescale, you can just create a public speed multiplier variable and set it to 1 at start.
If you only move balls (Assumed from give sand balls reference), just multiply speed variable of ball with public speed multiplier variable. When you want to change the speed, just change the variable. As an example:
var ballSpeed = baseBallSpeed * speedMultiplier;

How do I make a SKSpriteNode avoid another SKSpriteNode?

I am working on an AI mode for a SpriteKit game I am making in Xcode. I have dynamic physics bodies which can be launched towards the AI. I want to make it so that when one of these bodies is within a certain radius of the AI, the AI tries to dodge it. I have started working through different routes and got decent results.
1st method (pseudocode): Check AI.position.x and AI.position.y and compare to incomingSprite.position.x and incomingSprite.position.y. Break this comparison into quadrants if both x and y are within radius. (i.e. incomingSprite is bottom left relative to AI, bottom right, etc). Based on this info move the AI's position to move away from it.
cons:
-lots of code and calculations in update function to account for multiple incoming sprites
-depending on dx and dy of incoming sprite, the AI often make illogical decision
2nd method (pseudocode): Calculate distance from AI to incomingSprite. Then check dx and dy of incomingSprite and set dx and dy to go in reverse direction of incomingSprite. This seems logical. I am a little rusty on reversing vectors to do this. I feel like this might be possibly a good idea though.
Is there a better method to accomplish this? Perhaps a force field on the magnet I could use to repel the AI at a certain strength so that if the incomingSprite is fast enough it will override and still collide anyway? Im concerned about memory as most of the AI logic is in the update function, which can cause big problems if I'm not careful.
Edit: I decided to use the electric field and gave the incoming sprites a positive charge so that they are repelled by the AI. This makes things accurate/lightweight and more interesting. If the incoming sprites are fast enough, they will break through the electric field and still collide with AI. This also gives room as an additional difficulty parameter in my game (the stronger the field, the harder it is to get the incoming sprites to collide with the AI).

Buoyancy with Box2D on iPhone

I was wondering if anyone can give me pointers on how to achieve the following using Box2D on the iphone:
1) I have a Box2D world with normal gravity of -9.8
2) The bottom half of the screen is a body of water
So when my sprite hits the body of water, I want him to react with buoyancy (similar to what's going on in this video: http://www.youtube.com/watch?v=0uX-1GXYIss)
Is the best way to achieve this to
1) simply calculate the y position of the main character sprite and then switch the gravity variable accordingly
or 2) is there a specific feature built into Box2D that will allow me to set my "water" sprite to behave as water in my world and "push" my main character sprite up (while still respecting the world gravity of 9.8)
Any info would be appreciated
The buoyant force is equal to the density of the fluid times the volume of the fluid displaced (which gives you the mass of the fluid displaced) times the acceleration due to gravity. The volume of fluid displaced can be costly to compute however. I would suggest making a simple estimate of the volume displaced based on the size of the object and how far it is submerged in the liquid.
Another very important force in fluid is the drag force. This is what makes it more difficult to move objects at high velocity through thick fluids. The drag force can easily be estimated by simply damping the velocity by some constant value: Force_drag = -b * v where b is your damping value and v is the object's velocity.