/* * This method detects collision between a cannonball and a point on the string * If a collision is detected, the string moves away from the cannonball * NOTE: If the segment length of the string is larger than the collision radius of the cannonball, * than a collision may not be detected */ private void DetectAndMoveOnStringCollision() { foreach (GameObject cannonball in OperateCannons.activeCannonballs) // For each active cannonball { if (cannonball == null) { continue; } CannonballMotion motion = cannonball.GetComponent <CannonballMotion>(); // Get the CannonballMotion component of the cannonball Vector3 cannonballCenter = new Vector3(motion.GetXPosition(), motion.GetYPosition(), 0f); Vector3 centerToPoint; // The vector from the center of the cannonball to a point on the string float distance; // The distance between the center and the point // For each point of the string, except the point connected to the body for (int i = 1; i < NUM_STRING_POINTS; i++) { centerToPoint = cannonballCenter - currentStringPoints[i]; distance = centerToPoint.magnitude; // If the distance from the center of the cannonball to the point is less than or equal to the collision radius of the cannonball if (System.Math.Abs(distance) <= CannonballCollisionDetection.collisionRadius + COLLISION_BUFFER_ZONE) { // The point is inside the cannonball float error = CannonballCollisionDetection.collisionRadius + COLLISION_BUFFER_ZONE - distance; float direction; // The direction in which to correct the position of the string points // Set the direction to the direction the cannonball is moving if (motion.GetXVelocity() > 0) { direction = 1f; // Right direction } else { direction = -1f; // Left direction } // For the string point and every string point below it for (int j = i; j < NUM_STRING_POINTS; j++) { currentStringPoints[j].x += 2f * error * direction; // Correct the x position of the point currentStringPoints[j].y += 2f * error; // Correct the y position of the point (always upward) } } } } }
// Returns true if a cannonball has collided with the body private bool DetectBodyCollision() { foreach (GameObject cannonball in OperateCannons.activeCannonballs) // For each active cannonball { if (cannonball == null) { continue; // Do nothing if the cannonball is not active } CannonballMotion motion = cannonball.GetComponent <CannonballMotion>(); // Get the CannonballMotion component of the cannonball Vector3 cannonballCenter = new Vector3(motion.GetXPosition(), motion.GetYPosition(), 0f); Vector3 centerToCenter = cannonballCenter - bodyCenterPoint; // The vector from the center of the cannonball to the center for the body float distance = centerToCenter.magnitude; // The distance between the centers // If the distance is less or equal to the radius of collision of the cannonball combined with the radius of the biggest circle inscribed within a hexagon if (System.Math.Abs(distance) < CannonballCollisionDetection.collisionRadius + COLLISION_BUFFER_ZONE + BODY_SEGMENT_LENGTH * System.Math.Cos(System.Math.PI / 6)) { // The cannonball is inside the body return(true); // A collision occured } // For each point of the body for (int i = 0; i < NUM_BODY_POINTS; i++) { centerToCenter = cannonballCenter - currentBodyPoints[i]; distance = centerToCenter.magnitude; // If the distance from the center of the cannonball to the point is less than or equal to the collision radius of the cannonball if (System.Math.Abs(distance) <= CannonballCollisionDetection.collisionRadius + COLLISION_BUFFER_ZONE) { // The point is inside the cannonball return(true); // A collision occured } } } return(false); // No collision occured }
private CannonballMotion cannonballMotion; // The instance of the CannonballMotion class that is linked to the current cannonball game object // Start is called before the first frame update void Start() { cannonballMotion = gameObject.GetComponent <CannonballMotion>(); // Get the instance of the CannonballMotion class from the current cannonball game object }