//Look at every object in the camera view and add it to the list if it is not already on it void dynamicAdd() { bool onList = false; foreach (GameObject obj in rootObjects) { if (isInView(obj)) { CollisionHull2D objHull = obj.GetComponent <CollisionHull2D>(); foreach (CollisionHull2D hull in colliders) { if (objHull != null && objHull.gameObject == hull.gameObject) { //they are equal onList = true; } } if (onList == false) { colliders.Add(objHull); } } } }
void FireCanons() { thisBullet = Instantiate(bulletPrefab, this.transform.position + CollisionHull2D.getRotatedPoint(new Vector3(0.0f, 0.5f, 0.0f), new Vector3(0.0f, 0.0f, 0.0f), theta), this.transform.rotation); Destroy(thisBullet, 3); thisBullet.GetComponent <BulletScript>().force = forwardVec; thisBullet.GetComponent <BulletScript>().startingRotation = theta; }
private void Update() { unCheckedObjs.AddRange(objs); foreach (CollisionHull2D otherObj in objs) { for (int i = 0; i < unCheckedObjs.Count; ++i) { CollisionHull2D currentObj = unCheckedObjs[i]; if (currentObj.GetInstanceID() == otherObj.GetInstanceID()) { continue; } bool isColliding = CollisionHull2D.TestCollision(currentObj, otherObj); currentObj.SetColliding(isColliding, otherObj); //j.SetColliding(isColliding, i); } //unCheckedObjs.RemoveAt(0); } unCheckedObjs.Clear(); }
// Start is called before the first frame update void Start() { worldTransformMatrix = new MadeMatrix4x4( 1.0f, 0.0f, 0.0f, transform.position.x, 0.0f, 1.0f, 0.0f, transform.position.y, 0.0f, 0.0f, 1.0f, transform.position.z, 0.0f, 0.0f, 0.0f, 1.0f ); worldTransformMatrix.calculateInv(); worldTranformInverseMatrix = new MadeMatrix4x4(); worldTranformInverseMatrix.matrix = worldTransformMatrix.invMatrix; torqueContainer.worldCenterOfMass = transform.position; torqueContainer.localCenterOfMass = Vector3.zero; SetMass(forces.startingMass); particle3DTransform.position = transform.position; Quaternion rot = gameObject.transform.rotation; Vector4 quatVals = new Vector4(rot.x, rot.y, rot.z, 1); particle3DTransform.rotation = new MadeQuaternion(quatVals.x, quatVals.y, quatVals.z); UpdateInertia(); colHull = this.gameObject.GetComponent <CollisionHull2D>(); }
// This function calculates Circle to OBB collisions public static CollisionInfo CircleToABBCollision(CollisionHull2D a, CollisionHull2D b) { // Find the closest point to the circle from the AABB Vector2 closestPointToCircle = new Vector2(Math.Max(b.GetMinimumCorner().x, Math.Min(a.GetPosition().x, b.GetMaximumCorner().x)), Math.Max(b.GetMinimumCorner().y, Math.Min(a.GetPosition().y, b.GetMaximumCorner().y))); // Get the distance between the closest point and the circle's position Vector2 distance = a.GetPosition() - closestPointToCircle; float distanceSquared = Vector2.Dot(distance, distance); // Calculate the penetration float penetration = a.GetDimensions().x - Mathf.Sqrt(distanceSquared); // Is the penetration a positive value if (penetration > 0) { // If yes, then inform the parents of the complex shape object (if applicable) ReportCollisionToParent(a, b); } else { // If no, return nothing return(null); } // Return full details of the Collision list if the two collide return(new CollisionInfo(a, b, penetration)); }
public void AddCollisionHull(CollisionHull2D col) { if (!collisionHulls.Contains(col)) { //collisionHulls.Add(col); } }
// This function computes AABB to AABB collisions public static CollisionInfo AABBToAABBCollision(CollisionHull2D a, CollisionHull2D b) { // Get the penetration values for both axes float penetration = 0.0f; // Calculate half extents along x axis for each object float a_extent = a.GetDimensions().x; float b_extent = b.GetDimensions().x; // Get the distance between a and b Vector2 n = (b.GetPosition() - a.GetPosition()); n = new Vector2(Mathf.Abs(n.x), Mathf.Abs(n.y)); // Calculate overlap on x axis float x_overlap = a_extent + b_extent - Mathf.Abs(n.x); // SAT test on x axis if (x_overlap > 0) { // Calculate half extents along x axis for each object a_extent = a.GetDimensions().y; b_extent = b.GetDimensions().y; // Calculate overlap on y axis float y_overlap = a_extent + b_extent - Mathf.Abs(n.y); // SAT test on y axis if (y_overlap > 0) { // Find out which axis is axis of least penetration if (x_overlap > y_overlap) { // If it is Y, then return Y's overlap penetration = y_overlap; } else { // If it is Y, then return X's overlap penetration = x_overlap; } } } // Do the two checks pass? if (penetration > 0) { // If yes, then inform the parents of the complex shape object (if applicable) ReportCollisionToParent(a, b); } else { // If no, return nothing return(null); } // Return full details of the Collision list if the two collide return(new CollisionInfo(a, b, penetration)); }
// This function calculates OBB to OBB colisions public static CollisionInfo OBBToOBBCollision(CollisionHull2D a, CollisionHull2D b) { // Compute the R hat and U hat for both collision hulls Vector2 ARHat = new Vector2(Mathf.Abs(Mathf.Cos(a.GetRotation())), Mathf.Abs(-Mathf.Sin(a.GetRotation()))); Vector2 BRHat = new Vector2(Mathf.Abs(Mathf.Cos(b.GetRotation())), Mathf.Abs(-Mathf.Sin(b.GetRotation()))); Vector2 AUHat = new Vector2(Mathf.Abs(Mathf.Sin(a.GetRotation())), Mathf.Abs(Mathf.Cos(a.GetRotation()))); Vector2 BUHat = new Vector2(Mathf.Abs(Mathf.Sin(b.GetRotation())), Mathf.Abs(Mathf.Cos(b.GetRotation()))); // Create a list of all penetrations on each axis List <float> overlaps = new List <float>(); // Do axis checks overlaps.Add(CheckOBBAxis(a, b, ARHat)); // Does the check pass? if (overlaps[0] == Mathf.Infinity) { // If no, return nothing return(null); } // Do axis checks overlaps.Add(CheckOBBAxis(a, b, AUHat)); // Does the check pass? if (overlaps[1] == Mathf.Infinity) { // If no, return nothing return(null); } // Do axis checks overlaps.Add(CheckOBBAxis(a, b, BRHat)); // Does the check pass? if (overlaps[2] == Mathf.Infinity) { // If no, return nothing return(null); } // Do axis checks overlaps.Add(CheckOBBAxis(a, b, AUHat)); // Do the axis checks pass? if (overlaps[3] != Mathf.Infinity) { // If yes, then inform the parents of the complex shape object (if applicable) ReportCollisionToParent(a, b); } else { // If no, return nothing return(null); } // Return full details of the Collision list if the two collide return(new CollisionInfo(a, b, CollisionResolution.GetFinalPenetration(overlaps))); }
public HullCollision2D(CollisionHull2D a, CollisionHull2D b, Vector2 contactNormal, float penetration) { this.a = a; this.b = b; this.restitution = Mathf.Min(a.restitution, b.restitution); this.contactNormal = contactNormal; this.penetration = penetration; }
public HullCollision2D(CollisionHull2D a, CollisionHull2D b) { this.a = a; this.b = b; this.restitution = Mathf.Min(a.restitution, b.restitution); this.contactNormal = a.position - b.position; this.penetration = 0; }
public static bool TestCollision(CollisionHull2D a, CollisionHull2D b) { CollisionHullType2D hullTypeA = a.type; CollisionHullType2D hullTypeB = b.type; if (hullTypeA == CollisionHullType2D.hull_circle) { if (hullTypeB == CollisionHullType2D.hull_circle) { collided = a.TestCollsionVsCircle(b.GetComponent <CirlceCollisionHull2D>()); } if (hullTypeB == CollisionHullType2D.hull_aabb) { collided = a.TestCollsionVsAABB(b.GetComponent <AABBCollisionHull2D>()); } if (hullTypeB == CollisionHullType2D.hull_obb) { collided = a.TestCollsionVsOBB(b.GetComponent <OBBCollisionHull2D>()); } } else if (hullTypeA == CollisionHullType2D.hull_aabb) { if (hullTypeB == CollisionHullType2D.hull_circle) { collided = a.TestCollsionVsCircle(b.GetComponent <CirlceCollisionHull2D>()); } if (hullTypeB == CollisionHullType2D.hull_aabb) { collided = a.TestCollsionVsAABB(b.GetComponent <AABBCollisionHull2D>()); } if (hullTypeB == CollisionHullType2D.hull_obb) { collided = a.TestCollsionVsOBB(b.GetComponent <OBBCollisionHull2D>()); } } else if (hullTypeA == CollisionHullType2D.hull_obb) { if (hullTypeB == CollisionHullType2D.hull_circle) { collided = a.TestCollsionVsCircle(b.GetComponent <CirlceCollisionHull2D>()); } if (hullTypeB == CollisionHullType2D.hull_aabb) { collided = a.TestCollsionVsAABB(b.GetComponent <AABBCollisionHull2D>()); } if (hullTypeB == CollisionHullType2D.hull_obb) { collided = a.TestCollsionVsOBB(b.GetComponent <OBBCollisionHull2D>()); } } return(collided); }
// This function gets the seperating velocity of two particles public static float CalculateSeparatingVelocity(CollisionHull2D shapeA, CollisionHull2D shapeB) { // Find all required values for calculation Vector2 differenceOfVelocity = (shapeA.gameObject.GetComponent <Particle2D>().velocity - shapeB.gameObject.GetComponent <Particle2D>().velocity) * -1; Vector2 differenceOfPosition = (shapeA.GetPosition() - shapeB.GetPosition()).normalized; // Return the dot product of both velocity and position return(Vector2.Dot(differenceOfVelocity, differenceOfPosition)); }
// This function gets the seperating velocity of two particles public static float CalculateSeparatingVelocity(CollisionHull2D shapeA, CollisionHull2D shapeB) { // Find all required values for calculation Vector2 differenceOfVelocity = (shapeA.gameObject.GetComponent <Particle2D>().velocity - shapeB.gameObject.GetComponent <Particle2D>().velocity) * -1; Vector2 differenceOfPosition = (shapeA.GetPosition() - shapeB.GetPosition()).normalized; // Return the dot product of both velocity and position // Since we are dealing with planes, there is no reason to check the X axis return(differenceOfPosition.y * differenceOfVelocity.y * COLLISION_AMPLIFIER); }
// This function reports two sets of collision hulls to their respective parents (if possible) public static void ReportCollisionToParent(CollisionHull2D shapeA, CollisionHull2D shapeB) { // If yes, then inform the parents of the complex shape object (if applicable) if (shapeA.transform.parent != null) { shapeA.GetComponentInParent <ParentCollisionScript>().ReportCollisionToParent(); } if (shapeB.transform.parent != null) { shapeB.GetComponentInParent <ParentCollisionScript>().ReportCollisionToParent(); } }
public static bool TestCollision(CollisionHull2D a, CollisionHull2D b, ref Collision c) { if (a.type == CollisionHullType2D.hull_circle) { if (b.type == CollisionHullType2D.hull_circle) { a.collisionStatus = a.collisionStatus || (a as CircleCollisionHull2D).TestCollisionVsCircle(b as CircleCollisionHull2D, ref c); } else if (b.type == CollisionHullType2D.hull_aabb) { a.collisionStatus = a.collisionStatus || (a as CircleCollisionHull2D).TestCollisionVsAABB(b as AABBCollisionHull2D, ref c); } else if (b.type == CollisionHullType2D.hull_obb) { a.collisionStatus = a.collisionStatus || (a as CircleCollisionHull2D).TestCollisionVsOBB(b as OBBCollisionHull2D, ref c); } } else if (a.type == CollisionHullType2D.hull_aabb) { if (b.type == CollisionHullType2D.hull_circle) { a.collisionStatus = a.collisionStatus || (a as AABBCollisionHull2D).TestCollisionVsCircle(b as CircleCollisionHull2D, ref c); } else if (b.type == CollisionHullType2D.hull_aabb) { a.collisionStatus = a.collisionStatus || (a as AABBCollisionHull2D).TestCollisionVsAABB(b as AABBCollisionHull2D, ref c); } else if (b.type == CollisionHullType2D.hull_obb) { a.collisionStatus = a.collisionStatus || (a as AABBCollisionHull2D).TestCollisionVsOBB(b as OBBCollisionHull2D, ref c); } } else if (a.type == CollisionHullType2D.hull_obb) { if (b.type == CollisionHullType2D.hull_circle) { a.collisionStatus = a.collisionStatus || (a as OBBCollisionHull2D).TestCollisionVsCircle(b as CircleCollisionHull2D, ref c); } else if (b.type == CollisionHullType2D.hull_aabb) { a.collisionStatus = a.collisionStatus || (a as OBBCollisionHull2D).TestCollisionVsAABB(b as AABBCollisionHull2D, ref c); } else if (b.type == CollisionHullType2D.hull_obb) { a.collisionStatus = a.collisionStatus || (a as OBBCollisionHull2D).TestCollisionVsOBB(b as OBBCollisionHull2D, ref c); } } if (a.lr) { a.setLineColor(a.collisionStatus); } return(a.collisionStatus); }
public CollisionInfo(CollisionHull2D shapeA, CollisionHull2D shapeB, Vector2 normal, float penetration) { RigidBodyA = shapeA.GetComponent <Particle2D>(); ShapeA = shapeA; RigidBodyB = shapeB.GetComponent <Particle2D>(); ShapeB = shapeB; RelativeVelocity = RigidBodyB.velocity - RigidBodyA.velocity; contacts[0].normal = normal; contacts[0].penetration = penetration; contacts[0].restitution = Mathf.Min(RigidBodyA.restitution, RigidBodyB.restitution); }
// This function is an event that gets triggered whenever the player is colliding with something public void HandleCollision(CollisionHull2D a, CollisionHull2D b) { // Check if the lander has landed correctly bool checkApproval = CheckForProperCollision(); // Has the lander landed correctly? if (!checkApproval) { // If yes, then shoot it up into the air particle.angularVelocity = 1000; } // Pass findings onto Game Manager GameManager.manager.ProcessLanderLandingStatus(checkApproval); }
public override HullCollision2D detectCollisionResponse(CollisionHull2D other) { if (other is CircleHull2D) { return(detectCollisionResponse(other as CircleHull2D, this)); } else if (other is AABBHull2D) { return(detectCollisionResponse(this, other as AABBHull2D)); } else if (other is OBBHull2D) { return(detectCollisionResponse(other as OBBHull2D, this)); } throw new System.Exception(); }
public override HullCollision2D detectCollisionResponse(CollisionHull2D other) { if (other is CircleHull2D) { return(detectCollisionResponse(this, other as CircleHull2D)); } else if (other is AABBHull2D) { return(detectCollisionResponse(this, other as AABBHull2D)); } else if (other is OBBHull2D) { return(detectCollisionResponse(this, other as OBBHull2D)); } throw new System.Exception(); //oops, looks like you added another collision type, thats a no no }
private void FixedUpdate() { // test each collision for (int outer = 0; outer < collisionHulls.Length; outer++) { collisionHulls[outer].setCollisionStatus(false); for (int inner = 0; inner < collisionHulls.Length; inner++) { // test each hull vs all others so all store colision data. if (inner == outer) { inner++; if (inner >= collisionHulls.Length) { break; } } var c = CollisionHull2D.getNewCollisionStruct(); CollisionHull2D.TestCollision(collisionHulls[outer], collisionHulls[inner], ref c); if (c.status) { collisionQ.Enqueue(c); } } } // resolve collisions //foreach (var c in collisionQ) //{ // // TODO: Multiple contact points // c.a.particle2D.setVelocity(-c.closingVelocity * c.contacts[0].restitution); while (collisionQ.Count > 0) { var c = collisionQ.Dequeue(); // do response. // relativeVel = a.velocity // relativeVel -= b.velocity; // seperatingVel = relativeVel*normal // if sepVel > 0 // newSepVel = -seperatingVel * restitution // deltaVel = newSepVel - seperatingVel // totalInverseMass = a.mass+b.mass // impulse = deltaVelocity / totalInverseMass; // ImpulsePerIMass = normal * impulse; // a.velocity = a.velocity+impulsePerIMass*a.inversMass c.a.getParticle2D().CollisionImpulse(c); } }
public override CollisionInfo CollisionTests(CollisionHull2D other) { switch (other.hullType) { case CollisionHull2D.PhysDetect.Circle: return(CollisionHull2D.CircleCircle(this, other as CircleCollision2D)); case CollisionHull2D.PhysDetect.AABB: return(CollisionHull2D.CircleAABB(this, other as AxisAllignedBoundingBoxCollision2D)); case CollisionHull2D.PhysDetect.OBB: return(CollisionHull2D.CircleOBB(this, other as ObjectBoundingBoxCollision2D)); default: break; } return(null); }
public override CollisionInfo TestCollision(CollisionHull2D other) { switch (other.HullType) { case CollisionHull2D.CollisionType.Circle: return(CollisionHull2D.CircleVSOBB(other as CircleHull, this)); case CollisionHull2D.CollisionType.AABB: return(CollisionHull2D.AABBVSOBB(other as AABBHull, this)); case CollisionHull2D.CollisionType.OBB: return(CollisionHull2D.OBBVSOBB(this, other as OBBHull)); default: break; } return(null); }
public override void OnCollision(CollisionHull2D withObject) { if (LunerGameManager.Instance.HasGameEnded) { return; } if (velocity.magnitude > maxVelocityMagnitudeOnLanding || rotation < -maxRotationOffsetOnLanding || rotation > maxRotationOffsetOnLanding) { LunerGameManager.Instance.ShowTransitionMessage("Game Over"); LunerGameManager.Instance.EndGame(); } else if (withObject is LunerPlatform) { if (velocity.magnitude > maxVelocityMagnitudeOnSafeLanding) { LunerPlatform collidedWith = withObject as LunerPlatform; LunerGameManager.Instance.addToScore(collidedWith.score); ResetAndShowMessage("Shakey landing, but there in one piece"); } else { LunerPlatform collidedWith = withObject as LunerPlatform; LunerGameManager.Instance.addToScore(collidedWith.score * 1.5f); fuel += collidedWith.fuelGained; ResetAndShowMessage("Clean Landing, gained fuel and bonus points"); } } //all collisions happen below, so if collision occured then lerp the rotation addForce(ForceGenerator2D.GenerateForce_Friction_Kinetic(withObject.transform.up, velocity, 2.0f)); if (rotation > 5.0f) { torque = -rotationCorrectionForce * (rotation / 360); } else if (rotation < -5.0f) { torque = rotationCorrectionForce * (-rotation / 360); } else { torque = -rotation * rotationCorrectionForce * Time.deltaTime; } }
void checkForCollisions() { for (int i = 0; i < colliders.Count; i++) { for (int j = i + 1; j < colliders.Count; j++) { if (colliders[i].gameObject.activeSelf == false || colliders[j].gameObject.activeSelf == false) { Debug.Log("One of the objects is inactive!"); //Don't update } else { if (CollisionHull2D.TestCollision(colliders[i], colliders[j], ref desc)) { if (shouldChangeColor) { CollisionHull2D.changeColor(colliders[i].gameObject, true); CollisionHull2D.changeColor(colliders[j].gameObject, true); } CollisionHull2D.resolveInterpenetration(ref desc); CollisionHull2D.updateCollision(ref desc, coefficientOfRestitution); //Kill the player GameObject.Find("CollisionManagerHost").GetComponent <GameManagerScript>().hitByAstroid = true; Debug.Log("Objects collided"); } else { if (shouldChangeColor) { CollisionHull2D.changeColor(colliders[i].gameObject, false); CollisionHull2D.changeColor(colliders[j].gameObject, false); } } } } } }
public override bool TestCollision(CollisionHull2D other) { switch (other.HullType) { case CollisionHull2D.CollisionType.Circle: return(CollisionHull2D.CircleVSCircle(this, other as CircleHull)); case CollisionHull2D.CollisionType.AABB: return(CollisionHull2D.CircleVSAABB(this, other as AABBHull)); case CollisionHull2D.CollisionType.OBB: return(CollisionHull2D.CircleVSOBB(this, other as OBBHull)); default: break; } return(false); }
// Start is called before the first frame update void Start() { UIMan = GameObject.Find("UI Manager"); SetMass(startingMass); position = transform.position; UpdateInertia(); colHull = this.gameObject.GetComponent <CollisionHull2D>(); // Give this Particle2D's colHull the list of other CollisionHull2D from list of Particles to check for collision //List<CollisionHull2D> otherColList = new List<CollisionHull2D>(); //for (int i = 0; i < otherColParticleList.Count; i++) //{ // otherColList.Add(otherColParticleList[i].colHull); //} // //colHull.otherColHullList = otherColList; }
public static bool TestCollision(CollisionHull2D a, CollisionHull2D b) { if (b.type == CollisionHullType2D.circle) { return(a.TestCollisionVsCircle(b as CircleCollisionHull2D)); } else if (b.type == CollisionHullType2D.aabb) { return(a.TestCollisionVsAABB(b as AxisAlignedBoundingBoxCollision2D)); } else if (b.type == CollisionHullType2D.obb) { return(a.TestCollisionVsObject(b as ObjectBoundingBoxCollisionHull2D)); } else if (b.type == CollisionHullType2D.penis) { print("I N T E R P E N E T R A T I O N"); } return(false); }
// This function computes circle to circle collisions public static CollisionInfo CircleToCircleCollision(CollisionHull2D a, CollisionHull2D b) { // Calculate the distance between both colliders Vector2 distance = a.GetPosition() - b.GetPosition(); float penetration = a.GetDimensions().x + b.GetDimensions().x *(a.GetDimensions().x + b.GetDimensions().x) - Vector2.Dot(distance, distance); // Are the Radii less than or equal to the distance between both circles? if (penetration > 0) { // If yes, then inform the parents of the complex shape object (if applicable) ReportCollisionToParent(a, b); } else { // If no, return nothing return(null); } // Return result return(new CollisionInfo(a, b, penetration)); }
// return a collision instead of a bool // or use ref to pass a collision public static bool TestCollision(CollisionHull2D a, CollisionHull2D b, out Collision collision) { switch (b.type) { case CollisionHullType2D.CIRCLE: { return(a.TestCollisionVsCircle((Circle)b, out collision)); } case CollisionHullType2D.AABB: { return(a.TestCollisionVsAABB((AABB_2D)b, out collision)); } case CollisionHullType2D.OBB: { return(a.TestCollisionVsOBB((OBB_2D)b, out collision)); } } collision = null; return(false); }
// This function intializes the collision info class based on given information public CollisionInfo(CollisionHull2D _a, CollisionHull2D _b, float _penetration) { // Is collision A's collision type have less priority to collision B? if (_a.collisionType > _b.collisionType) { // If yes, then switch their priorities a = _b; b = _a; } else { // If no, then keep them as so a = _a; b = _b; } // Based on collision hulls, calculate the rest of the values separatingVelocity = CollisionResolution.CalculateSeparatingVelocity(a, b); normal = (b.GetPosition() - a.GetPosition()).normalized; penetration = _penetration; }