private void ClimbOverObstacles() { if (Collider.FarseerBody.ContactList == null || Math.Abs(movement.X) < 0.01f) { return; } //check if the collider is touching a suitable obstacle to climb over Vector2?handle = null; FarseerPhysics.Dynamics.Contacts.ContactEdge ce = Collider.FarseerBody.ContactList; while (ce != null && ce.Contact != null) { if (ce.Contact.Enabled && ce.Contact.IsTouching && ce.Contact.FixtureA.CollisionCategories.HasFlag(Physics.CollisionWall)) { Vector2 contactNormal; FarseerPhysics.Common.FixedArray2 <Vector2> contactPos; ce.Contact.GetWorldManifold(out contactNormal, out contactPos); //only climb if moving towards the obstacle if (Math.Sign(contactPos[0].X - Collider.SimPosition.X) == Math.Sign(movement.X) && (handle == null || contactPos[0].Y > ((Vector2)handle).Y)) { handle = contactPos[0]; } } ce = ce.Next; } if (handle == null) { return; } float colliderBottomY = GetColliderBottom().Y; //the contact point should be higher than the bottom of the collider if (((Vector2)handle).Y < colliderBottomY + 0.01f || ((Vector2)handle).Y > Collider.SimPosition.Y) { return; } //find the height of the floor below the torso //(if moving towards towards an obstacle that's low enough to climb over, the torso should be above it) float obstacleY = GetFloorY(GetLimb(LimbType.Torso)); if (obstacleY > colliderBottomY) { //higher vertical velocity for taller obstacles Collider.LinearVelocity += Vector2.UnitY * (((Vector2)handle).Y - colliderBottomY + 0.01f) * 50; onGround = true; } }
/// <summary> /// wakes any contacting bodies. Useful when creating a fixture or changing something that won't trigger the bodies to wake themselves /// such as Circle.center. /// </summary> protected void WakeAnyContactingBodies() { Body body = this.GetComponent <FSRigidBody>().Body; FarseerPhysics.Dynamics.Contacts.ContactEdge contactEdge = body.ContactList; while (contactEdge != null) { FarseerPhysics.Dynamics.Contacts.Contact contact = contactEdge.Contact; if (contact.FixtureA == _fixture || contact.FixtureB == _fixture) { contact.FixtureA.Body.IsAwake = true; contact.FixtureB.Body.IsAwake = true; } contactEdge = contactEdge.Next; } }
public FSCollisionShape SetRestitution(float restitution) { _fixtureDef.Restitution = restitution; if (_fixture != null) { _fixture.Restitution = restitution; Body body = this.GetComponent <FSRigidBody>().Body; FarseerPhysics.Dynamics.Contacts.ContactEdge contactEdge = body.ContactList; while (contactEdge != null) { FarseerPhysics.Dynamics.Contacts.Contact contact = contactEdge.Contact; if (contact.FixtureA == _fixture || contact.FixtureB == _fixture) { contact.ResetRestitution(); } contactEdge = contactEdge.Next; } } return(this); }