public void borderCollision(Entity sender, Entity other, CollisionPair pair) { var enemy = other.Tag as Player; if (enemy != null) { if (!player.EnemyCollision) player.tank.Velocity = -player.tank.Velocity; player.EnemyCollision = true; } }
private static CollisionPair GetCollisionPair(GhostLSBody ghost, int ID2) { LSBody body2; if ((body2 = PhysicsManager.SimObjects[ID2]).IsNotNull()) { CollisionPair pair; if (!ghost.CollisionPairs.TryGetValue(body2.ID, out pair)) { pair = new CollisionPair(); ghost.CollisionPairs.Add(body2.ID, pair); pair.Initialize(ghost, body2); //Don't modify simulation object //body2.CollisionPairHolders.Add(body1.ID); } return(pair); } return(null); }
/* * ______________ Why do we need this function? * ______________ Try taking it out and see what happens */ void PositionalCorrection(CollisionPair c) { //If the shapes are in fact Colliding, push them apart the shortest distance direction (Away from the collision) //Check if The Mass of either Body is 0, and set their invMass to 0 if true //Otherwise it's 1/their respective Masses (or the Inverse, see where it went there?) const float percent = 0.2f; float invMassA, invMassB; if (c.rigidBodyA.mass == 0) { invMassA = 0; } else { invMassA = 1 / c.rigidBodyA.mass; } if (c.rigidBodyB.mass == 0) { invMassB = 0; } else { invMassB = 1 / c.rigidBodyB.mass; } //The position correction vector2 [x,y] //Basically, the (penetration of the collision/The combined Inverse Masses * percent) in the direction opposite of the collision Vector2 correction = ((collisions[c].penetration / (invMassA + invMassB)) * percent) * -collisions[c].collisionNormal; //Take the original position of the Rigidbody and add the correction to it Vector2 temp = c.rigidBodyA.transform.position; temp -= invMassA * correction; c.rigidBodyA.transform.position = temp; //Take the original position of the Rigidbody and add the correction to it temp = c.rigidBodyB.transform.position; temp += invMassB * correction; c.rigidBodyB.transform.position = temp; }
/* * This function updates the position of solids upon collision using the inverse mass as weights (as well as a * pre-defined fixed percentage) so that objects which collided are just a bit separated, instead of still penetrating * We need this function to give the effect that collision happens "instantly" - i.e.: in just one frame * otherwise, with velocities opposed, this could create the "illusion" that, in the second frame after dectecting collision, * despite having their velocities altered (and in the opposite direction), they are still colliding - which triggers * changing the direction of their velocities - and so objects would collide several times during several frames * - only separating when their final velocity accumulated (wrongly) so that they can tear themselves appart * <- Why do we need this function? * Ok, will make a movie out of this and submit alongside the project * <- Try taking it out and see what happens */ void PositionalCorrection(CollisionPair c) { const float percent = 0.2f; float invMassA, invMassB; if (c.rigidBodyA.mass == 0) { invMassA = 0; } else { invMassA = 1 / c.rigidBodyA.mass; } if (c.rigidBodyB.mass == 0) { invMassB = 0; } else { invMassB = 1 / c.rigidBodyB.mass; } Debug.Log("Correction: " + ((collisions[c].penetration / (invMassA + invMassB)) * percent)); Vector2 correction = ((collisions[c].penetration / (invMassA + invMassB)) * percent) * -collisions[c].collisionNormal; Debug.Log("Correction: " + correction.x); Vector2 temp = c.rigidBodyA.transform.position; temp -= invMassA * correction; c.rigidBodyA.transform.position = temp; temp = c.rigidBodyB.transform.position; temp += invMassB * correction; c.rigidBodyB.transform.position = temp; }
/// <summary> /// This function handles objects entering the selection zone for adapative interactions /// </summary> /// <param name="currentCollider"> This is the collider that our selection zone is intersecting with </param> void OnTriggerEnter(Collider currentCollider) { // WAYPOINT COLLISION if (currentCollider.gameObject.CompareTag("waypoint")) { Debug.Log("getting here"); Waypoint collidedWaypoint = currentCollider.gameObject.GetComponent <WaypointProperties>().classPointer; if (collidedWaypoint.id == "A0") { Debug.Log("destroy"); Destroy(collidedWaypoint.gameObjectPointer.GetComponent <SphereCollider>()); return; } if (!currentCollisions.Any(x => (x.waypoint == collidedWaypoint && x.type == CollisionType.WAYPOINT))) { //Debug.Log("A waypoint is entering the grab zone"); // We automatically default to the most recent waypointCollision mostRecentCollision = new CollisionPair(collidedWaypoint, CollisionType.WAYPOINT); ////Debug.Log("New mostRecentCollision is a waypoint - " + mostRecentCollision.waypoint.id); currentCollisions.Add(mostRecentCollision); } } // LINE COLLISION // We must have left a waypoint (and had our mostRecentCollision.type set to NOTHING) in order to switch to selecting a line else if (currentCollider.tag == "Line Collider") { // This is the waypoint at the end of the line (the line points back toward the path origin / previous waypoint) Waypoint lineOriginWaypoint = currentCollider.GetComponent <LineProperties>().originWaypoint; if (!currentCollisions.Any(x => (x.waypoint == lineOriginWaypoint && x.type == CollisionType.LINE))) { //Debug.Log("A line is entering the grab zone"); currentCollisions.Add(new CollisionPair(lineOriginWaypoint, CollisionType.LINE)); } } }
protected void BufferContactPoint(ref ContactPoint point) { if (_iContactPointCount == _iMaxContatPoints) return; // Angel buffers contact points, I don't know why. We don't. PhysicsActor pa1 = point.Shape1.Body.GetUserData() as PhysicsActor; PhysicsActor pa2 = point.Shape2.Body.GetUserData() as PhysicsActor; if (pa1 == null || pa2 == null) return; CollisionPair pair = new CollisionPair(pa1, pa2); if (!_currentTouches.ContainsKey(pair)) { pa1.OnCollision(pa2, ref point); if (Switchboard.Instance["CollisionWith" + pa1.Name] != null) { Switchboard.Instance.Broadcast(new Message("CollisionWith" + pa1.Name)); _currentTouches.Add(pair, true); } } pair = new CollisionPair(pa2, pa1); if (!_currentTouches.ContainsKey(pair)) { pa2.OnCollision(pa1, ref point); if (Switchboard.Instance["CollisionWith" + pa2.Name] != null) { Switchboard.Instance.Broadcast(new Message("CollisionWith" + pa2.Name)); _currentTouches.Add(pair, true); } } _iContactPointCount++; }
/// <summary> /// This method updates the mostRecentCollision, used for adaptive controller interactions /// </summary> private void CollisionsUpdate() { // Check if there are no objects in the selection zone if (currentCollisions.Count == 0) { // We note that there is nothing in the selection zone if (mostRecentCollision.waypoint != null || mostRecentCollision.type != CollisionType.NOTHING) { mostRecentCollision.waypoint = null; mostRecentCollision.type = CollisionType.NOTHING; //Debug.Log("There is nothing in the grab zone - " + mostRecentCollision); } } // Otherwise, we check if the lastSelected Object is still in the selection zone else if (!currentCollisions.Any(x => x.waypoint == mostRecentCollision.waypoint)) { // If the mostRecentCollision.waypoint isn't in the selection zone anymore, we need to grab the next most recent collision // We prioritize the most recent waypoint collision // Because we add to the end of the list, we need to grab the last waypoint on the list CollisionPair possibleWaypointCollision = currentCollisions.FindLast(collision => collision.type == CollisionType.WAYPOINT); if (possibleWaypointCollision != null) { mostRecentCollision = possibleWaypointCollision; //Debug.Log("New mostRecentCollision is a waypoint - " + mostRecentCollision.waypoint.id); } else { // If we did not find any waypoints, we look for the first line collision mostRecentCollision = currentCollisions[currentCollisions.Count - 1]; //Debug.Log("New mostRecentCollision is a line - " + mostRecentCollision.waypoint.id); } } }
public void TestAll() { for (int i = 0; i < collideableObjects.Count; i++) { for(int j = i + 1; j < collideableObjects.Count; j++) { Rectangle intersection = CollisionTest(collideableObjects[i], collideableObjects[j]); CollisionPair pair = new CollisionPair(collideableObjects[i], collideableObjects[j]); CollisionPair lastCollision = currentCollisions.Find(x => x == pair); if (intersection != Rectangle.Empty) { CollisionInfo infoA = new CollisionInfo(collideableObjects[j], intersection, intersection.Center.ToVector2()); CollisionInfo infoB = new CollisionInfo(collideableObjects[i], intersection, intersection.Center.ToVector2()); collideableObjects[i].OnCollision(infoA); collideableObjects[j].OnCollision(infoB); if (lastCollision.A == null) { currentCollisions.Add(pair); collideableObjects[i].OnCollisionEnter(infoA); collideableObjects[j].OnCollisionEnter(infoB); } } else { if (lastCollision.A != null) { currentCollisions.Remove(lastCollision); collideableObjects[i].OnCollisionExit(collideableObjects[j]); collideableObjects[j].OnCollisionExit(collideableObjects[i]); } } } } }
public CollisionPair Swap(CollisionPair s) { return(new CollisionPair(s.b, s.a)); }
/// <summary> /// Handles the impact of the cannonball against some other object. /// </summary> /// <param name="sender">The cannonball.</param> /// <param name="other">Other entity involved in the collision.</param> /// <param name="pair">Collision pair between the two entities.</param> public void HandleImpact(Entity sender, Entity other, CollisionPair pair) { //Only handle the impact if it was the first impact. if (Space != null) { //Query the physics engine's broad phase collision detection system to determine which entities have //bounding boxes that overlap the explosion volume. List<Entity> hitEntities = Resources.GetEntityList(); var explosionVolume = new BoundingSphere(sender.CenterPosition, ExplosionRadius); Space.BroadPhase.GetEntities(explosionVolume, hitEntities); foreach (Entity e in hitEntities) { var enemy = e.Tag as TriangleMesh; if (enemy != null) { Manager.RemoveCannonBall(this); // Terrain was hit! } var enemy2 = e.Tag as Player; if (enemy2 != null) { //enemy2.Life -= 10; enemy2.ReceiveDamage(5); // Player tank was was hit! } var enemy3 = e.Tag as Enemy; if (enemy3 != null) { enemy3.Life -= 1; enemy3.IsHited = true; if (enemy3.Life < 0) { enemy3.IsDead = true; Space.Remove(enemy3.Tank_box); } //Console.WriteLine("Hit" + enemy3.Life); } // enemy was hit var enemy4 = e.Tag as Wall; if (enemy4 != null && (e.IsDynamic == false)) e.BecomeDynamic(1f); var enemy5 = other.Tag as Building; if (enemy5 != null) { Explosion explosion2 = new Explosion(sender, 500, ExplosionRadius, Space, game); explosion2.Explode(); } var enemy6 = other.Tag as EntityModel; if (enemy6 != null) { Explosion explosion2 = new Explosion(sender, 500, ExplosionRadius, Space, game); explosion2.Explode(); } } Explosion explosion = new Explosion(sender, 500, ExplosionRadius, Space, game); explosion.Explode(); Manager.RemoveCannonBall(this); blast.Play(); } }
internal DirectEnumerationSolver(CollisionPair pair) { this.pair = pair; }
public override void Visit(ShipBulletCol b) { GameObject BulletChildren = (GameObject)Iterator.GetChild(b); CollisionPair.Collide(BulletChildren, this); }
public void CheckAndDistributeCollision() { if (!Active) { return; } if (_ranIndex < 0) { _ranIndex = PhysicsManager.RanCollisionPairs.Add(new PhysicsManager.InstanceCollisionPair(_Version, this)); } IsCollidingChanged = false; LastFrame = LockstepManager.FrameCount; CurrentCollisionPair = this; if (CullCounter <= 0) { GenerateCircleValues(); if (CheckHeight()) { bool result = CheckCollision(); if (result != IsColliding) { IsColliding = result; IsCollidingChanged = true; } if (CheckCollision()) { DistributeCollision(); } } Body1.NotifyContact(Body2, IsColliding, IsCollidingChanged); Body2.NotifyContact(Body1, IsColliding, IsCollidingChanged); if (IsColliding == false) { //A negative cull counter means a Body is preventing culling if (CullCounter >= 0) { if (PreventDistanceCull) { CullCounter = (short)( (LockstepManager.FrameCount - LastCollidedFrame) / PhysicsManager.CullTimeStep); if (CullCounter > PhysicsManager.CullTimeMax) { CullCounter = PhysicsManager.CullTimeMax; } } else { //Set number of frames until next collision check based on distance var distCull = ( ((FastDistance - FastDistanceOffset) >> FixedMath.SHIFT_AMOUNT) / PhysicsManager.CullDistanceStep + PhysicsManager.CullDistributor ); if (distCull > PhysicsManager.CullDistanceMax) { distCull = PhysicsManager.CullDistanceMax; } if (distCull < 0) { distCull = 0; } var timeCull = (LockstepManager.FrameCount - LastCollidedFrame) / PhysicsManager.CullTimeStep; if (timeCull > PhysicsManager.CullTimeMax) { timeCull = PhysicsManager.CullTimeMax; } CullCounter = (short)(timeCull + distCull); } } } else { LastCollidedFrame = LockstepManager.FrameCount; } } else { if (Body1.PartitionChanged || Body2.PartitionChanged) { //New partition so collision culling may not be calculated yet CullCounter = 0; CheckAndDistributeCollision(); } else { //Culled and counter 1 step closer until checking again CullCounter--; } } }
public void tankCollision(Entity sender, Entity other, CollisionPair pair) { var enemy = other.Tag as TriangleMesh; if (enemy != null) { // Terrain was hit! } var enemy2 = other.Tag as Player; if (enemy2 != null) { // Player tank was was hit! } var enemy3 = other.Tag as Enemy; if (enemy3 != null) { if (!player.EnemyCollision) player.tank.Velocity = -player.tank.Velocity; player.EnemyCollision = true; } // Enemy was hit var enemy4 = other.Tag as Wall; if (enemy4 != null && (other.IsDynamic == false)) other.BecomeDynamic(1f); var enemy5 = other.Tag as Building; if (enemy5 != null) { if (!player.EnemyCollision) player.tank.Velocity = -player.tank.Velocity; player.EnemyCollision = true; } var enemy6 = other.Tag as HardWall; if (enemy6 != null) { if (!player.EnemyCollision) player.tank.Velocity = -player.tank.Velocity; player.EnemyCollision = true; } }
/// <summary> /// Handles what happens when an entity enters the wall's hit volume. /// If it's an enemy, boom!! /// </summary> /// <param name="toucher">Entity touching the volume.</param> /// <param name="volume">Volume being touched.</param> public void EntityEntersVolume(Entity sender, Entity other, CollisionPair pair) { IsAlive = false; //Health -= 5001; //Remove the graphics too. // Space.Remove(sender); // Console.WriteLine("Touch!"); }
public bool Equals(CollisionPair other) { return((Object1.Equals(other.Object1) && Object2.Equals(other.Object2)) || (Object1.Equals(other.Object2) && Object2.Equals(other.Object1))); }
/// <summary> /// Constructs a new linear friction constraint. /// </summary> /// <param name="pair">Collision pair owning this friction constraint.</param> internal SlidingFrictionTwoAxisObsolete(CollisionPair pair) { this.pair = pair; }
/// <summary> /// Removes an existing callback function. You need to set the CollisionPair.PhysicsObject1 /// and CollisionPair.PhysicsObject2 so that it knows which collision callback to remove. /// </summary> /// <param name="pair">A pair of IPhysicsObject to detect collisions</param> public void RemoveCollisionCallback(CollisionPair pair) { collisionCallbacks.Remove(pair); }
/// <summary> /// Adds a collision callback function. You need to set the CollisionPair.PhysicsObject1 /// and CollisionPair.PhysicsObject2, but you shouldn't set other properties of CollisionPair. /// Other properties of CollisionPair are set automatically when it's returned from the /// CollisionCallback delegate/callback function. /// </summary> /// <remarks> /// You can't add more than one collision callback function for the same collision pair. /// </remarks> /// <param name="pair">A pair of IPhysicsObject to detect collisions</param> /// <param name="handler">The callback function to be called when the pair collides</param> public void AddCollisionCallback(CollisionPair pair, CollisionCallback handler) { if (!collisionCallbacks.ContainsKey(pair)) { collisionCallbacks.Add(pair, handler); } }
/* * Check collisions betweem all the objects in the scene */ void CheckCollisions() { foreach (PhysicsRBody bodyA in rigidBodies.GetRange(0, rigidBodies.Count - 1)) { foreach (PhysicsRBody bodyB in rigidBodies.GetRange(rigidBodies.IndexOf(bodyA), rigidBodies.Count - rigidBodies.IndexOf(bodyA))) { if (bodyA != bodyB) { /* * builds the collision pair just before analysing if collision really happened */ CollisionPair pair = new CollisionPair(); pair.rigidBodyA = bodyA; pair.rigidBodyB = bodyB; Vector2 distance = bodyB.transform.position - bodyA.transform.position; Vector2 halfSizeA = (bodyA.aabb.tRight - bodyA.aabb.bLeft) / 2; Vector2 halfSizeB = (bodyB.aabb.tRight - bodyB.aabb.bLeft) / 2; Vector2 gap = new Vector2(Mathf.Abs(distance.x), Mathf.Abs(distance.y)) - (halfSizeA + halfSizeB); // Seperating Axis Theorem test if (gap.x < 0 && gap.y < 0) { //Debug.Log("Collided!!!"); //Debug.Log(bodyA.gameObject.name); //Debug.Log(bodyB.gameObject.name); /* * Removes data from a "previous" collision between those two objects */ if (collisions.ContainsKey(pair)) { collisions.Remove(pair); } CollisionInfo colInfo = new CollisionInfo(); if (gap.x > gap.y) { Debug.Log("GapX - collision is happening in the x Axis"); if (distance.x > 0) { /* * In this case the collision is happening like this: * B to the left of A */ colInfo.collisionNormal += new Vector2(1, 0); } else { /* * In this case the collision is happening like this: * A to the left of B */ colInfo.collisionNormal += new Vector2(-1, 0); } colInfo.penetration = gap.x; Debug.Log("Penetration: " + gap.x); } else { Debug.Log("GapY"); if (distance.y > 0) { colInfo.collisionNormal += new Vector2(0, 1); } else { colInfo.collisionNormal += new Vector2(0, -1); } colInfo.penetration = gap.y; } collisions.Add(pair, colInfo); } else if (collisions.ContainsKey(pair)) { /* Removes data from a collision between those two objects that is happening no more */ //if(pair.rigidBodyA.IsGrounded() && pair.rigidBodyA.mass > 0){ //pair.rigidBodyA.grounded = false; //} //if(pair.rigidBodyB.IsGrounded() && pair.rigidBodyB.mass > 0){ //pair.rigidBodyB.grounded = false; //} Debug.Log("Removed - Collision happens no more"); collisions.Remove(pair); } } } } }
static void ResolveCollision(CollisionPair pair) { if (pair.a == null || pair.b == null || pair.a.gameObject == null || pair.b.gameObject == null) { return; } NumberInfo a = pair.a; NumberInfo b = pair.b; if (a.transform.parent == b.transform.parent && b.transform.parent != null) { return; } // don't combine from same generator // if (a.transform.parent.GetComponent<AISpikeyGenerator>() && b.tran if (a.destroyedThisFrame || b.destroyedThisFrame) { return; } if (a.GetComponent <SoapedNumber>() && b.GetComponent <SoapedNumber>()) { return; } // soaped number don't combine with each other. if (a.GetComponent <TemporaryPreventCombine>() || b.GetComponent <TemporaryPreventCombine>()) { return; } // numbers chopped with sword won't recombine. This behavior is destoyed on player pickup. if (a.GetComponent <BlobNumber>() || b.GetComponent <BlobNumber>()) { // if (a.GetComponent<MonsterSnail>() || b.GetComponent<MonsterSnail>()) { return; } // blob monsters if (a.GetComponent <BlobNumber>() && b.GetComponent <Rigidbody>() && !b.GetComponent <Rigidbody>().isKinematic) { a.Eat(b); } else if (b.GetComponent <BlobNumber>() && a.GetComponent <Rigidbody>() && !a.GetComponent <Rigidbody>().isKinematic) { b.Eat(a); } } else if (a.GetComponent <MonsterAISpikey1>() || b.GetComponent <MonsterAISpikey1>()) { if (a.GetComponent <MonsterAISpikey1>() && b.GetComponent <MonsterAISpikey1>()) { return; } // spikey' dont eat each other else if (!a.GetComponent <Rigidbody>() || !b.GetComponent <Rigidbody>()) { return; } // spikeys dont interact with non rigidbodies else if (a.GetComponent <Rigidbody>() && a.GetComponent <Rigidbody>().isKinematic) { return; } // spikeys dont eat kinematics. else if (b.GetComponent <Rigidbody>() && b.GetComponent <Rigidbody>().isKinematic) { return; } // spikeys dont eat kinematics. else if (a.GetComponent <MonsterAISpikey1>() && !b.GetComponent <MonsterAISpikey1>()) { a.Eat(b); } // spikeys eat regular num else if (!a.GetComponent <MonsterAISpikey1>() && b.GetComponent <MonsterAISpikey1>()) { b.Eat(a); } } else if (a.fraction.numerator == -b.fraction.numerator && a.fraction.denominator == b.fraction.denominator) { // DestroyedFX(a.transform,b.tran); // b.DestroyedFX(); a.ZeroFX(a.transform.position); a.GemFX(); b.ZeroFX(b.transform.position); b.GemFX(); Destroy(a.gameObject); //if (a.myShape == NumberShape.Cube) NumberPool.inst.DestroyOrPool (a); // else Destroy(a.gameObject); Destroy(b.gameObject); //if (b.myShape == NumberShape.Cube) NumberPool.inst.DestroyOrPool (b); // else Destroy(b.gameObject); SMW_FX.CreateSmallPurpleExplosion(a.transform.position); //,1.5f,.5f); SMW_FX.CreateWhiteFlash(a.transform.position); //,20f,.3f); SMW_FX.CreateShards(a.transform.position); SMW_FX.CreateTextEffect(a.transform.position, "zero"); a.destroyedThisFrame = true; b.destroyedThisFrame = true; // a.DestroyedFX(); // AudioManager.inst.PlayNumberShatter(a.transform.position); return; } else if (a.myShape == NumberShape.Cube && b.myShape == NumberShape.Sphere) { a.Eat(b); } else if (a.myShape == NumberShape.Sphere && b.myShape == NumberShape.Cube) { b.Eat(a); } else if (a.myShape == NumberShape.Cube && b.myShape == NumberShape.Cube) { if (a.gameObject.GetComponent <Rigidbody>() && !b.gameObject.GetComponent <Rigidbody>()) { b.Eat(a); } else if (b.gameObject.GetComponent <Rigidbody>() && !a.gameObject.GetComponent <Rigidbody>()) { a.Eat(b); } } else if (a.gameObject.GetComponent <Rigidbody>() && a.gameObject.GetComponent <Rigidbody>().isKinematic) { a.Eat(b); } else if (b.gameObject.GetComponent <Rigidbody>() && b.gameObject.GetComponent <Rigidbody>().isKinematic) { b.Eat(a); } else if (a.neverEats) { b.Eat(a); } else if (b.neverEats) { a.Eat(b); } else if (a.combineLayer > b.combineLayer) { a.Eat(b); } else if (a.combineLayer < b.combineLayer) { b.Eat(a); } else if (a.gameObject == PlayerGadgetController.inst.thrownNumber) { b.Eat(a); } else if (b.gameObject == PlayerGadgetController.inst.thrownNumber) { a.Eat(b); } else if (a.GetComponent <SoapedNumber>() && !b.GetComponent <SoapedNumber>()) { a.Eat(b); } else if (b.GetComponent <SoapedNumber>() && !a.GetComponent <SoapedNumber>()) { b.Eat(a); } else if (a.gameObject.GetComponent <Rigidbody>() && b.gameObject.GetComponent <Rigidbody>()) { float velA = a.gameObject.GetComponent <Rigidbody>().velocity.sqrMagnitude; float velB = b.gameObject.GetComponent <Rigidbody>().velocity.sqrMagnitude; if (velA < velB) { a.Eat(b); } else { b.Eat(a); } } else if (Fraction.AbsGreater(a.fraction, b.fraction)) { a.Eat(b); } else if (Fraction.AbsGreater(b.fraction, a.fraction)) { b.Eat(a); } }
public void tankCollision(Entity sender, Entity other, CollisionPair pair) { var enemy = other.Tag as TriangleMesh; if (enemy != null) { // Terrain was hit! } var enemy2 = other.Tag as Player; // Player tank was was hit! if (enemy2 != null) { if (!enemy2.EnemyCollision) enemy2.tank.Velocity = -enemy2.tank.Velocity; enemy2.EnemyCollision = true; } var enemy3 = other.Tag as Enemy; if (enemy3 != null) { } // Enemy was hit var enemy4 = other.Tag as Wall; if (enemy4 != null && (other.IsDynamic == false)) other.BecomeDynamic(1f); }
void CheckCollisions() { //Check each PhysicsRBody against Every other PhysicsRBody //check to make sure they aren't the Same PhysicsRBody //Build a CollisionPair called pair //Build a CollisionInfo called colInfo //Distance is a Vector2 [(bodyB.x -bodyA.x), (bodyB.y -bodyA.y)] //halfSizeA is a Vector2 [Half the length of the top/bottom, Half the length of the sides] //halfSizeB is a Vector2 [Half the length of the top/bottom, Half the length of the sides] //Kinda Like a Radius, but fer a square //then line ____ happens.. Vector2 gap = // foreach (PhysicsRBody bodyA in rigidBodies.GetRange(0, rigidBodies.Count - 1)) { foreach (PhysicsRBody bodyB in rigidBodies.GetRange(rigidBodies.IndexOf(bodyA), rigidBodies.Count - rigidBodies.IndexOf(bodyA))) { if (bodyA != bodyB) { CollisionPair pair = new CollisionPair(); CollisionInfo colInfo = new CollisionInfo(); pair.rigidBodyA = bodyA; pair.rigidBodyB = bodyB; Vector2 distance = bodyB.transform.position - bodyA.transform.position; Vector2 halfSizeA = (bodyA.aabb.tRight - bodyA.aabb.bLeft) / 2; Vector2 halfSizeB = (bodyB.aabb.tRight - bodyB.aabb.bLeft) / 2; Vector2 gap = new Vector2(Mathf.Abs(distance.x), Mathf.Abs(distance.y)) - (halfSizeA + halfSizeB); //// Seperating Axis Theorem test if (gap.x < 0 && gap.y < 0) { //Check if the the two objects overlay on both the x AND y axis Debug.Log("Collided!!!"); if (collisions.ContainsKey(pair)) { //If the collisions list contains this "pair", remove it from the list //Removed cuz They Collided, so we don't need to check em any more collisions.Remove(pair); } if (gap.x > gap.y) { if (distance.x > 0) { //So There is space between the x positions, hmm? //// ... Update collision normal } else { //So There is ain't a space between the x positions //// ... Update collision normal } //The Magic gap.x Calcuation is added to the penetration member of colInfo colInfo.penetration = gap.x; } else { if (distance.y > 0) { //So There is space between the y positions, hmm? //// ... Update collision normal } else { //So There is ain't a space between the y positions //// ... Update collision normal } //The Magic gap.y Calcuation is added to the penetration member of colInfo //Completing it's Might! colInfo.penetration = gap.y; } //Adding this pair, alomg with the colInfo to the Collisions list collisions.Add(pair, colInfo); } else if (collisions.ContainsKey(pair)) { //If the collisions list contains this "pair", remove it from the list //Removed cuz They Collided?***********, so we don't need to check em any more Debug.Log("removed"); collisions.Remove(pair); } } } } }
/// <summary> /// Constructs a new linear friction constraint. /// </summary> /// <param name="pair">Collision pair owning this friction constraint.</param> internal SlidingFrictionOneAxisConstraint(CollisionPair pair) { this.pair = pair; }
/// <summary> /// Handles what happens when an entity enters the wall's hit volume. /// If it's an enemy, boom!! /// </summary> /// <param name="toucher">Entity touching the volume.</param> /// <param name="volume">Volume being touched.</param> public void EntityEntersVolume(Entity sender, Entity other, CollisionPair pair) { var enemy = other.Tag as TriangleMesh; if (enemy != null) { // Terrain was hit! } var enemy2 = other.Tag as Player; if (enemy2 != null) { if (enemy2.Life < 100) // Player tank caught heath package! { space.Remove(body); game.Components.Remove(this); Random rand = new Random(0); ; enemy2.Life = Math.Min(100, enemy2.Life + (int)((float)rand.NextDouble() * 30f + 20f) ); } } var enemy3 = other.Tag as Enemy; if (enemy3 != null) // Enemy caught heath package! { if (enemy3.Life < 150) { space.Remove(body); game.Components.Remove(this); Random rand = new Random(0); enemy3.Life = Math.Min(150, enemy3.Life + Math.Min(150, enemy3.Life + (int)((float)rand.NextDouble() * 30f + 30f))); } } var enemy4 = other.Tag as Wall; if (enemy4 != null && (other.IsDynamic == false)) other.BecomeDynamic(1f); var enemy5 = other.Tag as Building; if (enemy5 != null) { } // Church was hit, not nice }
void CheckCollisions() { foreach (PhysicsRBody bodyA in rigidBodies.GetRange(0, rigidBodies.Count - 1)) { foreach (PhysicsRBody bodyB in rigidBodies.GetRange(rigidBodies.IndexOf(bodyA), rigidBodies.Count - rigidBodies.IndexOf(bodyA))) { if (bodyA != bodyB) { CollisionPair pair = new CollisionPair(); CollisionInfo colInfo = new CollisionInfo(); pair.rigidBodyA = bodyA; pair.rigidBodyB = bodyB; Vector2 distance = bodyB.transform.position - bodyA.transform.position; Vector2 halfSizeA = (bodyA.aabb.tRight - bodyA.aabb.bLeft) / 2; Vector2 halfSizeB = (bodyB.aabb.tRight - bodyB.aabb.bLeft) / 2; Vector2 gap = new Vector2(Mathf.Abs(distance.x), Mathf.Abs(distance.y)) - (halfSizeA + halfSizeB); // Seperating Axis Theorem test if (gap.x < 0 && gap.y < 0) { Debug.Log("Collided!!!"); if (collisions.ContainsKey(pair)) { collisions.Remove(pair); } if (gap.x > gap.y) { if (distance.x > 0) { //Update collision Normal... gap.Normalize(); pair.rigidBodyA.currentVelocity = new Vector2(0, 0); pair.rigidBodyA.obeysGravity = false; //pair.rigidBodyB.currentVelocity = new Vector2 (0, 0); //pair.rigidBodyB.obeysGravity = false; } else { //Update collision Normal... gap.Normalize(); pair.rigidBodyA.currentVelocity = new Vector2(0, 0); pair.rigidBodyA.obeysGravity = false; //pair.rigidBodyB.currentVelocity = new Vector2 (0, 0); //pair.rigidBodyB.obeysGravity = false; } colInfo.penetration = gap.x; } else { if (distance.y > 0) { //Update collision Normal... gap.Normalize(); pair.rigidBodyA.currentVelocity = new Vector2(0, 0); pair.rigidBodyA.obeysGravity = false; //pair.rigidBodyB.currentVelocity = new Vector2 (0, 0); //pair.rigidBodyB.obeysGravity = false; } else { //Update collision Normal... gap.Normalize(); pair.rigidBodyA.currentVelocity = new Vector2(0, 0); pair.rigidBodyA.obeysGravity = false; //pair.rigidBodyB.currentVelocity = new Vector2 (0, 0); //pair.rigidBodyB.obeysGravity = false; } colInfo.penetration = gap.y; } collisions.Add(pair, colInfo); } else if (collisions.ContainsKey(pair)) { Debug.Log("removed"); collisions.Remove(pair); } } } } }