Hello I have a physics body created within sprite kit editor, here are the settings I've set for it:
The problem is, it isn't acting "static". If another physics body bumps into it "weirdly" (for lack of a better description) it often glitches, flying all over the screen, or when I had it pinned, rotating around the pinned location. -Shouldn't this act static and never move, unless it is explicitly moved in code? I need it to have an alpha mask physics body and stand completely still (it is the ground in my scene).
Related
I have a node with a cube attached which represents for example a door. The physicsbody type is .static. If i animate the node up, rotate it and animate it down to the orignial position of the physicsbody stays in the upper position.
In the debug mode the color of the phyisicsbody is first grey (i asume grey = .static), after the translation up, the physicsbody stays at the bottom. As soon as I rotate the node in the upper position, the physicsbody becomes green and moves up to the nodes position. After I translate the node down to the original position, the physicsbody stays in the upper position. Why is this behaviour? Is this because the type is .static?
I know if I set the physicsbody type to .kinematic (shown red in debug) mode it works as expected. The physicsbody adapts the translations and rotations. But with .static type I can place more objects before the fps drops than with .dynamic.
From the documentation for SCNPhysicsBodyTypeStatic we learn that it is
A physics body that is unaffected by forces or collisions and cannot move
However you can use resetTransform to explicitly tell the engine that the node has moved and that the physics body needs to be updated:
If you change the position or orientation of a node with an attached
static or dynamic physics body, call this method afterward to ensure
that the physics simulation incorporates the change. You need not call
this method for kinematic bodies.
Note that dynamic and physics bodies
are designed to be moved only by the physics simulation or not at all.
You may use this method to move them regardless of this restriction,
but at a cost to performance.
So in my Space Invaders game, all collisions were working perfectly until I added a physics body created from a edgeChainFromPath which is a single line to represent the ground (an SKShapeNode created from 2 points). Now my invader bombs (which move via SKAction) notify when they hit the ground but my invaders (moved in update() by manually updating their positions) do not. My ship missiles (also moved by SKAction) DO notify when contacting an invader.
Question : if a physicsBody is moved manually and comes into contact with another physicsBody, is didBeginContact not called? (All physics interactions - bitMasks, delegates etc - are set correctly). I'm thinking the answer is 'No it's not' because that's the only explanation and makes sense picturing how Sprite/Kit probably works. I.e. A contact occurs when the SK engine itself moves a node and realises that it's physicsBody is being drawn on top of another physicsBody.
Edit - just realised that I have other physicsBodies in my scene that are stationary and that the invaders DO collide with, so it's not an SKAction thing. The difference might be that the new node I've added is an edge-based body belonging to an SKShapeNode, rather than a volume-based body for a SKSPriteNode, but nothing in the documentation that I can find states that this shouldn't work.
New question : Do volume-based bodies being moved manually not collide with stationary edge-based bodies?
Ok - my bad. The invaders' physicsBodies had dynamic=false. Every other sprite was dynamic, so all other collisions were working. My new shape was an edge-based body which also are dynamic=false.
Made that one change and all is Ok. I need to update my checkPhysics() routine to test for this.
Edit: I really should have seen this earlier - checkPhysics() was not printing that invader notifies when contacting ground, which I just put down to a glitch that I'd fix later. Whereas checkPhysics() deliberately doesn't report on nodes with dynamic=false. I think that when I wrote the function, I assumed that you'd set dynamic=false deliberately to not be involved in collision/contact detection. I should change it to print a warning.
I'm working on a game in which I have a objects that are "static" on screen so they don't react to gravity and at the same time, objects can fall from the top and collide with them. That part is all good. However, I want the collision to result in the static objects rotating based off speed/angle of the collision but not respond in any other way like flying off the screen.
Is there a way to stop the static objects bouncing away and instead just rotate in position?
Your static objects still have collision events. So you can catch those events and rotate you objects by yourself.
The other way is: use dynamic body. But when add body to them set bounce to 0; so they won't bounce. And about Gravity, you can set gravityScale to 0 to make them don't react to gravity
Remember: static objects can't move or rotate by physics. You must do it yourself. And you can stop dynamic objects from bouncing or falling with gravity by setting 'gravityScale' and 'bounce' attributes
And more, if you don't want it to get pushed, catch collision event with right phase ( belongs to yours situation ) and set it linearVelocity to (0,0)
I haven't tried it before, but maybe you can make it a dynamic object but link to a static object ( likes a wheel link to a post ). So it can't move but still rotate when collision
P/S: I did a test and it worked. Make your objects like dynamic-balls and link them to static objects. They now can't move but rotate when collision.
Here is the code for setting the characters physics body.
character.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:character.size];
It works fine, I mean it stays where I want it to but as you can see it displays the character's physics body in the bottom left of the screenshot (which is the grey box).
Is this a bug or can this be fixed?
I had a similar problem which may or may not solve yours.
It looks like you are using some sort of viewport system. Perhaps with a node called world and one called camera? If this is the case then you must be moving your world node every frame in order to center the content correctly? When drawing physics, you need to move the world node at -didEvaluateActions instead of -didSimulatePhysics
I'm working on a game in which the user should be able to trigger 'rods' that come out from the edge of the screen to displace elements on screen (balls). These projectiles roughly resemble pool-cues. Or perhaps pinball plungers, except that they start from the 'loaded' position (mostly offscreen), and when triggered, they eject out, then quickly retreat.
I'm unclear how I should build these with Sprite Kit.
The game uses the PhysicsEngine, and the onscreen balls should be effected both by gravity AND they should be displaced when they collide with the rods. However the rods should neither be effected by gravity, not displaced when they collide with the balls -- they should simply retreat regardless of whether they've made contact with the balls.
I realize I can set the affectedByGravity property for the rods. However because they will still displace slightly when they collide with the balls. How can I 'fix' or 'peg' them in place? Do I need to use an SKPhysicsSlidingJoint? If so, has anyone encountered any examples online? Is there a simpler way to do this?
A related physics engine, Box2D distinguishes static, kinematic, and dynamic bodies.
Kinematic bodies can move and will collide with other objects, but they are themselves not affected by dynamic bodies or forces like gravity. Thus, consider setting rod.dynamic = NO; but animate it with actions. See also here in the reference for SKPhysicsBody.