I'm trying to simulate a soccer game. I have a SCNPlane that simulates the court. I have imported a Soccer goal 3d model (.dae file) and also a ball model (.dae).
My ball has a dynamic physics body, the plane static and the goal is kinematic. I have set the categoryBitMask and contactTestBitMask for each one of the SCNNodes.
When I shoot the ball against the goal then sometimes the ball bounces and behaves as expected, but some other times the ball goes through the goal net and crosses it.
I have also assigned the SCNPhysicsContactDelegate and the didBeginContact is triggered when the ball bounces agains the goal but when the ball crosses it then the method is not called.
Do you know what might be happening?
Thank you!
Might be an issue with the ball moving too fast for the physics engine to calculate correctly. Try changing the "timeStep" value:
SceneKit processes the physics simulation and updates the state of all
physics bodies once per the time interval specified by this property.
The default value is 1/60 second (a rate of 60 Hz). A faster
simulation rate provides more accuracy in simulation results—such as
collisions between fast-moving objects—but at a higher cost in CPU
time (which may in turn slow down your app’s rendering frame rate).
Typically, you should set this property to match your target rendering
frame rate (as defined by the preferredFramesPerSecond property of the
SCNView object rendering your scene).
https://developer.apple.com/documentation/scenekit/scnphysicsworld/1512881-timestep
Instance property categoryBitMask defines which categories a physics body belongs to, and contactTestBitMask defines which categories of bodies cause intersection notifications with this physics body.
You need a collisionBitMask instance property that defines which categories of physics bodies can collide with this physics body.
var collisionBitMask: Int { get set }
When two physics bodies contact each other, a collision may occur. SceneKit compares the body’s collision mask to the other body’s category mask by performing a bitwise AND operation. If the result is a nonzero value, then the body is affected by the collision. Each body independently chooses whether it wants to be affected by the other body. For example, you might choose to avoid collision calculations that would make negligible changes to a body’s velocity.
The default value is all (a bit mask whose every bit is enabled), specifying that the body will collide with bodies of all other categories.
static var all: SCNPhysicsCollisionCategory { get }
all is default Type Property for a physics body’s collisionBitMask property.
Related
I import a 3D model into the ScenekKit, then change the Euler's angle of the limb and let the limbs do the action. However, at this time, clothes and limbs will penetrate. How can I handle this situation?
I think you have to use continuousCollisionDetectionThreshold instance property. This value gives you a minimum distance the body must travel for SceneKit to apply a more precise (but more CPU/GPU costly) algorithm to detect contacts with other bodies.
var continuousCollisionDetectionThreshold: CGFloat { get set }
SceneKit's physics engine can employ two kinds of collision detection:
With discrete collision detection, when SceneKit simulates physics before rendering each frame (see timeStep and SCNSceneRendererDelegate), it updates the position of each physics body based on the body's velocity during that time interval, then checks to see whether the body at its new position intersects other bodies.
With continuous collision detection, SceneKit calculates the volume that will be traversed by a body during each frame, then checks to see whether that volume intersects other bodies. This property's value defaults to 0.0, resulting in discrete collision detection at all times. When this value is nonzero, SceneKit applies continuous collision whenever the body travels more than the specified distance within one timeStep.
Discrete collision detection offers high performance, but can lead to inaccurate results for small, fast-moving bodies. Continuous collision detection has a performance cost and works only for spherical physics shapes, but provides more accurate results.
How do I make my player move left/right at a constant speed until the user touches the screen again, which will then make the player change direction right/left and run that way at a constant speed etc..
I have tried looking at other answers but can't figure out a working answer.
I've set linearDamping to 0 already.
There are two basic ways to apply velocity.
One is by applying forces to physics bodies, or giving them velocities.
Two is positional transformations, usually done with SKActions.
They're not compatible.
Since you're using physics, you need to either apply force or set a velocity.
I think you should probably take the time to read this entire page:
https://developer.apple.com/documentation/spritekit/skphysicsbody
Here's the setting velocity cherry from it:
First, you can control a physics body’s velocity directly, by setting
its velocity and angularVelocity properties. As with many other
properties, you often set these properties once when the physics body
is first created and then let the physics simulation adjust them as
necessary.
And here's the outline on forces:
You can apply a force to a body in one of three ways: A linear force
that only affects the body’s linear velocity. An angular force that
only affects the body’s angular velocity. A force applied to a point
on the body. The physics simulation calculates separate changes to the
body’s angular and linear velocity, based on the shape of the object
and the point where the force was applied.
I'm working for a small bouncing ball game using the SpriteKit physics engine. My problem is:
When I apply a huge impulse on the bouncing ball to have it fall on ground fast, sometimes it may pass through the ground (very thin, height=2).
I find this in the Apple document, but it doesn't work.
Specify High Precision Collisions for Small or Fast-Moving Objects
When Sprite Kit performs collision detection, it first determines the locations of all of the physics bodies in the scene. Then it determines whether collisions or contacts occurred. This computational method is fast, but can sometimes result in missed collisions. A small body might move so fast that it completely passes through another physics body without ever having a frame of animation where the two touch each other.
If you have physics bodies that must collide, you can hint to Sprite Kit to use a more precise collision model to check for interactions. This model is more expensive, so it should be used sparingly. When either body uses precise collisions, multiple movement positions are contacted and tested to ensure that all contacts are detected.
ship.physicsBody.usesPreciseCollisionDetection = YES;
You can set your sprite's node.physicsBody.usesPreciseCollisionDetection = YES; but this will not guarantee a collision flag all the time as your sprite's velocity could simply be just too high.
You should apply a speed limit to your nodes as to prevent them from going too fast. Something like this:
if(node.physicsBody.velocity.dx > 200)
node.physicsBody.velocity = CGVectorMake(200, node.physicsBody.velocity.dy);
The above code example will limit the right movement, dx, of your node to 200 while keeping the dy (up/down) velocity as is.
I have developed game something like coin dozer. And for the smooth movement of coin i have add one Physics Material to each coin but my game is very slow after doing that . Is there any alternative of that or how can i make coin movement smooth without use of Physics material . So can anybody help me to come out from this situation.
So the problem is physics calculation.
DO NOT use the mesh of the graphic as the collider to calculate coin's moving, especially when there are lots of triangles and verts on the mesh. You should choose a simpler collider, maybe something like prism would behavior similar as a coin and reduce a lot of calculation. You can use another simple prism mesh exported from 3d software and make a new game object with that mesh. Stripe off everything related to physics(rigid body, collider and physics material) from the origin coin. Then organize the visible coin without physics and the new added object(which handle all physics) to the same parent. Less triangles in a mesh collider means less calculation. Control the collider mesh triangles as few as possible. I suggest to use a box collider as a start point to check if the performance improves.
Another thing might help is changing the Solver Iteration Count in the Physics Setting. You can try to change it to a lower value (maybe 3 or 4 is enough for a coin game) from the default.
Limit the frame rate to a lower value alse can help, but it is the last way you should go.
You can add physics to the coins with delay. I mean add physics when coin is near to fall. Also you need to destroy every coin body when you are removing the coin out of the scene. If you are removing only sprite the there will be too many bodies on the scene.
Currently, each level has 3 layers :
background
collisions(walls, invisible walls, ground, etc)
foreground
My character sprite has 1 pixel to detect the collision.
In this character class, there is a Color[] contains every pixels of the collision layer.
I calculate the position of the Character's pixel detection, and obtain an int that i can use with the Color[] ("CharactersPixel")
if ( Color[CharactersPixel].A != 0 )
Then collision.
It works perfectly.
But the collision layer has to be used by every others objects like particles, monsters etc.
The collision layer has about 3.800.000 pixels. so the Color[] has the same.
If I add this Color[] to every objects, this will use too much RAM, right ?
You'd only add a reference to your collision layer to the objects. You are not copying the entire thing to each object. Adding a reference will not add much memory to your objects.
However, I would suggest making the collision available in some more general fashion by exposing some level data in a place accessible to any object. Perhaps you could add the data to your Game class as a property CurrentLevel with CollisionData as an accessible property.
Normally you keep the collision data separate from the actual rendering colours, and perform a more simplistic collision with boxes and the like instead that approximately match the shape of the collision data. This would in the end make it easier to calculate things like the angle which you impact the environment and calculation of appropriate physics. Pixel to pixel collisions are rare, and might also be problematic from a performance perspective.