I am developing a simple Golf game as shown in the below image.
I am facing below issues:
Even if I apply small amount of force, the ball continuous move along the grass? Grass friction is not stopping the ball.
Sometimes, the ball speed is increased after colliding with the walls instead the ball speed should decreased after collision with the walls. The walls are having box collider.
Sometimes, the ball reverses its direction after colliding with walls.
Code:
Physics properties of the ball:
ball.physicsBody.affectedByGravity = true;
ball.physicsBody.mass = 0.0450;
ball.physicsBody.restitution = 0.8;
ball.physicsBody.friction = 0.3;
ball.physicsBody.allowsResting = true;
Physics properties of the grass:
golf.physicsBody.friction = 0.8;
Physics properties of the walls:
leftWall.physicsBody.friction = 0;
leftWall.physicsBody.restitution = 0.8;
I have set the physics world gravity value to -9.8.
I am looking for suggestions to fix the above listed issue. Thank you.
To stop rolling, in a 3D physics world, you need angular damping, or linear damping, or a bit of both.
The friction component, when dealing with a rapidly spinning ball, can transpose to increased rate of movement, upon collisions.
A ball spinning in the reverse direction to its travel vector may have enough angular momentum to reverse its direction of travel when its friction is sufficient for it to gain traction on surfaces it collides with.
Related
I am developing a mini golf game in Scenekit. I have applied dynamic physics body to the ball and static physics body to the grass surface and the brick walls show in this image.
Issue:
When I apply the force to the ball, the ball’s linear and angular speeds change as shown in the graphs. The ball’s speeds don’t reduce to zero (so that the ball can stop) but remains constant after certain value.
Ball linear speed graph
Ball angular speed graph
Analysis Tests:
When I increase the values to both the rolling friction and the friction, the ball speed is reduced quickly but remains constant after certain value (similar to the above graphs).
When I increase the values of the linear damping and the angular damping, the ball speed behavior is same as the point #1.
When I set the gravity value to -9.8 m/s2, the ball’s linear speed remains constant after 0.1 m/s. If I reduce the gravity value to -5 m/s2, the ball’s linear speed remains constant after 0.05 m/s.
The friction, linear friction, linear damping and angular damping are same throughout the motion of the ball.
There is 1 millimeter overlapping between the ball and the surface of the golf course.
Questions:
From the analysis test #3, I think the gravity is causing the constant ball speed issue. Is my assumption correct? If yes, how can I fix the issue? I can’t remove the gravity field as without the gravity field the ball will not roll along the grass and it will slide.
Why the friction and the damping properties are not affecting the ball speed after certain value?
Are there any other physics properties can cause such issue?
From the analysis test #5, are there any chances that the ball is receiving upward push to correct the position of the ball?
Solutions:
After reducing the gravity value to -1 m/s2 and physics simulation speed to 4 (4 times fast physics simulation), the issue is fixed. However, I am worried that these settings will cause issues in further development of the game.
If I increase the physics timestep from 60 FPS to 200 FPS, the issue is resolved. How solution 2 can fix this issue?
I would appreciate any suggestions and thoughts on this topic. Thank you.
is there a way to trigger a function, when a node (e.g. a tossed ball) enters a certain bounding box (e.g. a basket) in SceneKit / ARKit? If not, how would you implement this problem?
The way I would probably approach this. After obtaining a basketball hoop 3D dae model.
https://3dwarehouse.sketchup.com/model/fa42320b3def2c6b4741187cebbc52b3/Basketball-Hoop
I would first setup up the physicsShapes for the different elements.... backboard, pole & ring/hoop, floor & ball. I would then work out the cylinder size to fit inside the ring.
Using:
let cylinder = SCNCylinder(radius: 1.0, height: 0.1)
This becomes the physicBody for the hoop.
hoopNode.physicsBody = SCNPhysicsBody(type: .static, shape: SCNPhysicsShape(geometry:cylinder))
I would then workout the collisions the ball has with each different basketball element/node.
Don’t forget to use the debug feature
SceneView.debugOptions = .showPhysicsShapes
This will help to visually debug the collisions with the physics shapes & make sure the physic shapes are accurately scaled and in the correct position.
How to do setup collisions has already been answered in a previous post here...
how to setup SceneKit collision detection
You probably want the ball to bounce off the backboard, pole and ring, but if it hits the hoop physic shape... you might want to make the ball disappear and create a nice spark/flame animation or something. You could then have a score that registers as well.
This Arkit game on github will give you a nice template for handling all those things, collisions, animations & scoring
https://github.com/farice/ARShooter
You have to implement it using the ball's world position and the basket world position + bounding box.
Calculate the size of the basket using it's bounding box:
var (basketBoundingBoxMin, basketBoundingBoxMax) = (basket?.presentation.boundingBox)!
let size = basketBoundingBoxMax - basketBoundingBoxMin
Use this size and the basket's world position to calculate:
Basket's minimum x,y,z
Basket's maximum x,y,z
Then check if ball's world position is inside the basket's minimum and maximum position.
I have a cube with dynamic physical body and a plane with kinematic physic body.When I place a cube above plane, it will fall onto plane and a bounce is expected.
The PROBLEM is: when the cube is small or light, it just go through plane.For instance, cube has 0.1*0.1*0.1 work fine but 0.05*0.05*0.05 sucks.In this case I still get physical body contacting notification.
this is my code for creating geometry:
//cube
//when dimension is 0.1 everything is fine
float dimension = 0.05;
SCNBox *cube = [SCNBox boxWithWidth:dimension height:dimension length:dimension chamferRadius:0];
cube.materials = #[material];
SCNNode *node = [SCNNode nodeWithGeometry:cube];
node.physicsBody = [SCNPhysicsBody bodyWithType:SCNPhysicsBodyTypeDynamic shape:nil];
node.physicsBody.mass = 1;
node.physicsBody.categoryBitMask = phsicBodyCategoryCube;
node.physicsBody.collisionBitMask = phsicBodyCategoryPlane;
node.physicsBody.contactTestBitMask = phsicBodyCategoryPlane;
//plane
self.planeGeometry = [SCNBox boxWithWidth:100 height:0.01 length:100 chamferRadius:0
plane.physicsBody = [SCNPhysicsBody bodyWithType:SCNPhysicsBodyTypeKinematic
shape: [SCNPhysicsShape shapeWithGeometry:self.planeGeometry options:nil]];
plane.physicsBody.categoryBitMask = phsicBodyCategoryPlane;
plane.physicsBody.collisionBitMask = phsicBodyCategoryCube;
plane.physicsBody.contactTestBitMask = phsicBodyCategoryCube;
I’m surprised you’re getting collisions at all. See the SCNPhysicsBodyType docs – the kinematic type is for bodies that you move (by setting their position, etc) to cause collisions, but that aren’t themselves affected by other bodies colliding with them.
If you set the floor’s type to static, you’ll probably see better results. A static body doesn’t move (either as a result of physics interactions, or by you setting its position), so the physics engine can more accurately check for other bodies colliding with it.
edit: Other things to look into:
Use a SCNPlane rather than a SCNBox for your floor. (Note that you can create physics bodies with shapes different from their visible geometry, if that helps.) I'm not sure about SceneKit's, but it's easier for a lot of physics engines to check "has some object passed this infinite boundary since the last frame?" than "is some object inside this finite region on this frame?"
Enable precise collision detection for your moving objects.
Finally I found this is all about SceneKit's physical simulation. If the cube falls too fast, It will make a large penetration with plane In physical simulation steps. In this case sceneKit just let it fall through plane instead of collision. When I change cube's velocity to a small value It collided with plane.
My solution is to give cube a upward velocity when large over-penetration happens, which is the 30% of fall velocity. The trick is adjusting cube's velocity until a collision happens.
Works only for spherical physics shapes
For this issue SCNPhysicsBody has special attribute: continuousCollisionDetectionThreshold
For example, in a game involving projectiles and targets, a small
projectile may pass through a target if it moves farther than the
target's thickness within one time step. By setting the projectile's
continuousCollisionDetectionThreshold to match its diameter, you
ensure that SceneKit always detects collisions between the projectile
and other objects.
I have a physics body that is uneven but not dynamic (the terrain) and a physics body (character) that is dynamic and is on top of the terrain, and I want this character to move along the terrain simulating kind of a "walking" action where it will keep going up the terrain but it won't fall back (or move back) like a ball because of gravity, and to set a maximum tilt so that it does not tip over.
My attempt was to add a force in the direction I want the character to move but this is causing the character to fall back due to gravity, and I don't want to disable gravity because then character won't fall down when going down the terrain.
Thank you very much
this is why using a physics engine for a platforming game is very difficult and not always a great approach..
you can try sprite.physicsBody.allowsRotation = false
might help
Create SKAction to move your character to destination point or dx and dy. Run that SKAction from your character node with the runAction. Like
SKAction.moveByX(...
When the action is finished, gravity will bring the character down.
If the movement is slow, play with the character's physicsBody friction and/or mass.
You can also change the the character's physicsBody.velocity = CGVectorMake(
And your terrain will be better with edgeLoop physicsBody which won't be dynamic.
And with uneven you mean inclined but smooth? If not smooth and with edges, your character may get held up at an edge depending on center of gravity of character and if you are allowing rotation.
I'm making a Breakout clone and having a little trouble with the ball-to-paddle collisions. I have a rectangle represent both the ball and the paddle and when they intersect, the Y vector representing the ball's velocity is negated (as shown below). That all works fine. The problem is when the paddle is moving to the right I want it to nudge the ball a little to the right (as opposed to it just reflecting off normally) and I want the same to happen in the opposite direction is the paddle is moving to the left. I'm not sure how to go about doing this and I've looked all over. Any help would be appreciated. Thanks.
if (paddleRectangle.Intersects(ballRectangle))
{
ballVelocity.Y *= -1;
collision.Play(); //a collision sound
}
EDIT: Basically I want to slightly change the angle at which the ball bounces off the paddle based on which direction the paddle is moving. If the paddle is not moving, then the ball will bounce normally (by inverting the Y component of the ball's velocity)
Add the paddle's velocity vector to the paddle's normal vector (this basically bends the normal in the direction the paddle is moving) and normalize the result. Use this as the collision normal for reflection.
Vector2 collisionNormal = Vector2.Normalize(paddleNormal + (paddleVelocity * desiredEffectAmount));
ballVelocity = Vector2.Reflect(ballVelocity, collisionNormal);
i did some grinding in my head... and here are results. to achieve that you will need, moving direction of paddle, speed of paddle, ball speed, ball direction. and then by some math function calucalte angle and speed of bounce.
i think this image (if bouncing is phisicaly correct) will give you idea how to create this. can't help you with function that will handle this but i would go and try that way as in image.
You want a little friction, but probably not real friction.
Try scaling the paddle speed down by some factor and adding it to the ball velocity.