public static bool isHitFromAbove(float sourceMaxY, ChipmunkBody target, ChipmunkArbiter arbiter) { /// The collision normal is the direction of the surfaces where the two objects collided. /// Keep in mind that the normal points out of the first object and into the second. /// If you switch the order of your collision types in the method name, it will flip the normal around. // came from above? if (target.velocity.normalized.y < -COS_45) { // check collision points to be all above collider's height for (int i = 0, c = arbiter.contactCount; i < c; ++i) { if (sourceMaxY > (arbiter.GetPoint(i).y - arbiter.GetDepth(i))) { return(false); } } return(true); } return(false); }
public static bool beginCollisionWithScenery(ChipmunkArbiter arbiter) { ChipmunkShape shape1, shape2; // The order of the arguments matches the order in the function name. arbiter.GetShapes(out shape1, out shape2); Player player = shape1.GetComponent <Player>(); /*if (player.isDying()) * return false; // stop collision with scenery since this frame*/ player.exitedFromScenery = false; // avoid ground penetration (Y axis) // NOTE: to solve this Chipmunk has the property collisionBias and/or minPenetrationForPenalty Vector2 thePos = player.body.position; float depth = arbiter.GetDepth(0); thePos.y -= depth; player.body.position = thePos; // if isn't a grounded surface then stop velocity and avoid getting inside the object if (GameObjectTools.isWallHit(arbiter)) { // get sign direction to know what offset apply to body player.signCollision = -Mathf.Sign(player.transform.position.x - shape2.transform.position.x); // set moving velocity close to 0 so player can't move against the wall but can change direction of movement player.walkVelocity = 0.001f; // move back to the contact point and a little more thePos = player.body.position; thePos.x += player.signCollision * (depth - 0.01f); player.body.position = thePos; } // Returning false from a begin callback means to ignore the collision response for these two colliding shapes // until they separate. Also for current frame. Ignore() does the same but next frame. return(true); }