/// <summary> /// Called by PlayerManager every time the gun needs to be shot. /// Protects against shooting faster than firerate allows /// /// </summary> public void Shoot() { // Make sure we can't shoot until it's time if (!IsReadyToShoot) { return; } // Calculate the next time we can fire based on current time and the firerate nextTimeToFire = Time.time + 1f / fireRate; //Play gunshot sound PlayGunShotSound(); // Play the muzzle flash particle system muzzleFlash.Play(); // Create a raycast from fps camera position in the direction it is facing (limit raycast to 'range' distance away) // Get back the 'hit' value (what got hit) // If cast hit something... if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out RaycastHit hit, range)) { // Log what we hit //Debug.LogFormat("Gun: Shoot() hit object: {0}", hit.transform.name); // We expect game objects we are concerned about possibly hitting to be marked as targets (by our design) // Get the target that was hit (if any) ITarget target = hit.transform.GetComponent <ITarget>(); // If we hit a target... if (target != null) { // Make target take damage target.TakeDamage(damage, playerWhoOwnsThisGun.GetComponent <PlayerManager>()); } // Add force to rigid body of target // If target has rigidboy... if (hit.rigidbody != null) { // We can add a force either one of two possible directions: // 1) the direction we are looking // 2) the normal of the surface we hit // We'll use the normal (make sure it's negative so it's going backwards) hit.rigidbody.AddForce(-hit.normal * impactForce); } // Create a new impact effect (GameObject) // (Vector3) hit.point: where in space we our bullet landed // Quaternion.LookRotation(hit.normal): a rotation representing the normal of the surface that we hit GameObject impactGO = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal)); // Destroy the impact game object after 2 seconds so it doesn't clutter our game heirarchy during gameplay Destroy(impactGO, 2f); } }