public static Vector3 VectorAfterNormalForce(Vector3 force, Vector3 normal) { Vector3 output; Vector3 rejectionVector = BasicRigidBody.Rejection(force, normal); Vector3 projectionVector = BasicRigidBody.Projection(force, normal); float dot = BasicRigidBody.Dot(force, normal); float direction = dot / Mathf.Abs(dot); if (direction <= 0.0f) { output = rejectionVector; return(output); } else { output = rejectionVector + projectionVector; return(output); } }
public bool SphereSphereCollision(BasicRigidBody other, out Vector3 newDist, out Vector3 newNormal) { //Difference vector Vector3 vecd = position - other.position; float r1 = radius; float r2 = other.radius; //Length is computed //sqrmag is 6x faster than vector3.distance on mobile float dist = Mathf.Sqrt(vecd.x * vecd.x + vecd.y * vecd.y + vecd.z * vecd.z); float squareMag = vecd.sqrMagnitude; if (dist < r1 + r2) { //We have a collision if (dist == 0) { Vector3 normal = Normalize(new Vector3(1, 1, 1)); newDist = position + normal / radius / 10.0f; newNormal = Normalize(position - newDist); } else { newDist = (position * r1 + other.position * r2) / (r1 + r2); newNormal = Normalize(position - newDist); } return(true); } else { //No collision newDist = new Vector3(0, 0, 0); newNormal = new Vector3(0, 0, 0); return(false); } }
public bool CheckCollisions() { bool hasCollided = false; for (int i = 0; i < otherRigidBody.Count; i++) { BasicRigidBody other = otherRigidBody[i]; Vector3 point; Vector3 normal; if (SphereSphereCollision(other, out point, out normal)) { hasCollided = true; Vector3 newVelocity = PhysicsManager.VectorAfterNormalForce(velocity, normal); Vector3 lostVelocity = velocity - newVelocity; Vector3 o_newVelocity = PhysicsManager.VectorAfterNormalForce(other.velocity, -normal); Vector3 o_losVelocity = other.velocity - o_newVelocity; Vector3 avgLostVelocity = (lostVelocity + o_losVelocity) / 2.0f; velocity = newVelocity * physManager.friction + avgLostVelocity; other.velocity = o_newVelocity * physManager.friction + avgLostVelocity; Vector3 differenceVector = point - position; float squareMag = differenceVector.sqrMagnitude; float dist = Mathf.Sqrt(squareMag); Vector3 offset = normal * (radius - dist); position += offset; other.position -= offset; } } for (int i = 0; i < otherColliders.Count; i++) { BoxCollider other = otherColliders[i]; Vector3 point; Vector3 normal; if (SphereAABBCollision(other, out point, out normal)) { if (other.gameObject.CompareTag("Axis_Y_Win")) { if (playerWin == 1) { ruleManager.AddPlayerScore(); } else if (playerWin == 2) { ruleManager.AddOtherScore(); } playerWin = 3; } hasCollided = true; //Vector3 newVelocity = PhysicsManager.VectorAfterNormalForce(velocity, normal); //velocity = newVelocity * physManager.friction; // For temp solution this is fine but not ideal in the most case if (other.gameObject.CompareTag("Axis_Y_PlayerSideTable")) { PlayerSideBounce.Play(); velocity.y = -velocity.y; } else if (other.gameObject.CompareTag("Axis_Y_OtherSideTable")) { AISideBounce.Play(); velocity.y = -velocity.y; } else if (other.gameObject.CompareTag("Axis_Z_PlayerBat")) { BatHit.Play(); ruleManager.ChangeToBlue(); if (!addPoint) { ruleManager.AddRallyCount(); addPoint = true; } Vector3 destination = new Vector3(ruleManager.GetCurrentAim().x, ruleManager.GetCurrentAim().y, ruleManager.GetCurrentAim().z); Vector3 heading = (destination - transform.position);//.normalized; velocity = heading; velocity = new Vector3(velocity.x, velocity.y + Y_VelocityAddition, velocity.z - Z_VelocityAddition); playerWin = 1; } else if (other.gameObject.CompareTag("Axis_Z_OtherBat")) { addPoint = false; BatHit.Play(); ruleManager.ChangeToRed(); Vector3 destination = new Vector3(Random.Range(-6.15f, -7.73f), PlayerSideZone.transform.position.y, PlayerSideZone.transform.position.z); Vector3 heading = (destination - transform.position);//.normalized; velocity = heading; velocity = new Vector3(velocity.x, velocity.y + Y_VelocityAddition, velocity.z + (Z_VelocityAddition + 0.3f)); playerWin = 2; } else if (other.gameObject.CompareTag("Axis_X")) { velocity.x = -velocity.x; } Vector3 differenceVector = point - position; float squareMag = differenceVector.sqrMagnitude; float dist = Mathf.Sqrt(squareMag); Vector3 offset = normal * (radius - dist); position += offset; velocity -= normal * Dot(velocity, differenceVector); } } return(hasCollided); }