private void ManageHits(RaycastHit[] hits, float bulletPower, Vector3 bulletDirection, float forceToRigidBodys, float damage, float bulletSpeed, float bulletTrailExitForce /*if it has rigidbody*/, GameObject trailPrefab, Transform trailExitPosRot, Vector3 bulletDir, LayerMask bulletMask ) { #region No Hit Fake Shot-return GunAtt gunAtt = GetComponent <GunAtt>(); if (hits.Length == 0) // Fake shot when nothing is hit { if (trailExitPosRot && trailPrefab) { Vector3 exitPos = trailExitPosRot.position; GameObject trail; trail = Instantiate(trailPrefab, exitPos, Quaternion.LookRotation( /*-plAtts.target.position + exitPos*/ /*trailExitPosRot.forward*/ bulletDir )) as GameObject; trail.transform.SetParent(decals.transform, true); if (trailPrefab.GetComponent <Rigidbody>()) { trail.GetComponent <Rigidbody>().velocity = -trail.transform.forward * bulletTrailExitForce; } } return; } #endregion No Hit Fake Shot-return int hitIndex = 0; GameObject tempBulletTrail = null; float thisBulletPower = bulletPower = bulletPower <= 0 ? .01f : bulletPower; // make sure we hit a collider foreach (RaycastHit hit in hits) // all raycast hits { GameObject decal = null, fx = null, hitSound = null; float thisPierceDecrease = 0; float timeToTravel = 0; Vector3 exitPos = transform.position; if (thisBulletPower <= 0) // if bullet have no power to hit next collider - raycast back & exit foreach { #region Destroy trail & Backward raycast // Find the time needed to get to last hit point timeToTravel = Vector3.Distance(hits[hitIndex - 1].point, exitPos) / bulletSpeed; // Destroy bullet trail if bullet lost power on last collider hit StartCoroutine(gunAtt.DestroyCoroutine(timeToTravel, tempBulletTrail)); // BW raycast if (hitIndex > 0) { RaycastHit[] hitsBW = Physics.RaycastAll(hits[hitIndex - 1].point, -bulletDirection, Vector3.Distance(hits[0].point, hits[hitIndex - 1].point), bulletMask); if (hitsBW.Length > 1) { gunAtt.SortArray(ref hitsBW); foreach (RaycastHit hitBW in hitsBW) { decals.GetAllNormalShot(hitBW.transform.tag, ref decal, ref fx, ref hitSound, ref thisPierceDecrease); // Instantiate them delayed float timeToTravelBW = Vector3.Distance(hitBW.point, exitPos) / bulletSpeed; if (decal != null) { StartCoroutine(gunAtt.InstantiateCoroutine( timeToTravelBW, decal, hitBW.point + (hitBW.normal * .04f), Quaternion.LookRotation(hitBW.normal) * Quaternion.Euler(new Vector3(0, 0, Random.Range(0, 360))), hitBW.transform)); } if (fx != null) { StartCoroutine(gunAtt.InstantiateCoroutine( timeToTravelBW, fx, hitBW.point + (hitBW.normal * .07f), Quaternion.LookRotation(hitBW.normal) * Quaternion.Euler(new Vector3(0, 0, Random.Range(0, 360))), hitBW.transform, true)); } if (hitSound != null) { StartCoroutine(gunAtt.InstantiateCoroutine(timeToTravelBW, hitSound, hitBW.point, Quaternion.identity, hitBW.transform, true)); } } } } #endregion Destroy trail & Backward raycast break; } #region Forward raycast decals.GetAllNormalShot(hit.transform.tag, ref decal, ref fx, ref hitSound, ref thisPierceDecrease); // to look realistic Instantiate them delayed timeToTravel = Vector3.Distance(hit.point, exitPos) / bulletSpeed; if (decal != null) { StartCoroutine(gunAtt.InstantiateCoroutine( timeToTravel, decal, hit.point + (hit.normal * .04f), Quaternion.LookRotation(hit.normal) * Quaternion.Euler(new Vector3(0, 0, Random.Range(0, 360))), hit.transform, true)); } if (fx != null) { StartCoroutine(gunAtt.InstantiateCoroutine( timeToTravel, fx, hit.point + (hit.normal * .07f), Quaternion.LookRotation(hit.normal) * Quaternion.Euler(new Vector3(0, 0, Random.Range(0, 360))), hit.transform, true)); } if (hitSound != null) { StartCoroutine(gunAtt.InstantiateCoroutine(timeToTravel, hitSound, hit.point, Quaternion.identity, hit.transform, true)); } // bullet trail at first hit if (trailExitPosRot && trailPrefab && hitIndex == 0) { Vector3 trailExitPos = trailExitPosRot.position; GameObject trail; trail = Instantiate(trailPrefab, trailExitPos, Quaternion.LookRotation(bulletDir)) as GameObject; if (trailPrefab.GetComponent <Rigidbody>()) { trail.GetComponent <Rigidbody>().velocity = trail.transform.forward * bulletTrailExitForce; } tempBulletTrail = trail; trail.transform.SetParent(decals.transform, true); } // add force to objects that bullet hit, if they have rigidbody StartCoroutine(gunAtt.AddBulletForceToRigidbodys(timeToTravel, hit, forceToRigidBodys * thisBulletPower / bulletPower, bulletDirection)); // Apply damage StartCoroutine(gunAtt.ApplyingDamageDelayed(timeToTravel, hit.collider.gameObject, damage * thisBulletPower / bulletPower, bulletDirection, hit.point, forceToRigidBodys * thisBulletPower / bulletPower)); #endregion Forward raycast hitIndex++; thisBulletPower -= thisPierceDecrease; } }
public void SecFire ( Transform owner, Transform target, Vector3 firingToPos, ref float _weaponBodyBob, ref float _randomHandTwistSign, Quaternion xq, LayerMask bulletMask ) { if (!SecFireGp) { return; } GunAtt gunAtt = GetComponent <GunAtt>(); SecFireGp.currentClipCapacity -= 1; float xSpread = 0, ySpread = 0, bodySpread = 0; bodySpread = SecFireGp.bodySpread; xSpread = (float)(Random.value - 0.5) * (SecFireGp.spreadAmount - spreadDecreaser); ySpread = (float)(Random.Range(.35f, 1f) - 0.5) * (SecFireGp.spreadAmount - spreadDecreaser); if (SecFireGp.fireSounds.Count > 0) { int randFireSound = Random.Range(0, SecFireGp.fireSounds.Count); GameObject fireSound = Instantiate(SecFireGp.fireSounds[randFireSound], transform.position, transform.rotation) as GameObject; if (fireSound) { fireSound.transform.SetParent(transform); AudioEventMonoB audioEventMonoB = fireSound.GetComponent <AudioEventMonoB>(); if (audioEventMonoB) { audioEventMonoB.owner = owner; } } } if (SecFireGp.animator) { SecFireGp.animator.SetTrigger("Fire"); } // empty shell if (SecFireGp.emptyShellPosition && SecFireGp.EmptyShellPrefab) { Vector3 randomEmptyShellForce = new Vector3(Random.Range(SecFireGp.emptyShellMinForce.x, SecFireGp.emptyShellMaxForce.x), Random.Range(SecFireGp.emptyShellMinForce.y, SecFireGp.emptyShellMaxForce.y), Random.Range(SecFireGp.emptyShellMinForce.z, SecFireGp.emptyShellMaxForce.z)); GameObject goEmptyShell = Instantiate(SecFireGp.EmptyShellPrefab, SecFireGp.emptyShellPosition.position, SecFireGp.emptyShellPosition.rotation) as GameObject; goEmptyShell.GetComponent <Rigidbody>().AddForce(SecFireGp.emptyShellPosition.rotation * randomEmptyShellForce, ForceMode.Impulse); goEmptyShell.transform.SetParent(decals.transform, true); } // muzzle flash if (SecFireGp.muzzleFlashPrefab) { GameObject goMuzzle = Instantiate(SecFireGp.muzzleFlashPrefab, SecFireGp.muzzleFlashPosRot.position, SecFireGp.muzzleFlashPosRot.rotation) as GameObject; goMuzzle.transform.SetParent(gunAtt.transform, true); } #region Raycast Fire if (!SecFireGp.isFiringProjectile) { if (!SecFireGp.isShotGun) { Vector3 bulletDir = xq * (firingToPos - SecFireGp.spawn.position).normalized; RaycastHit[] hits = Physics.RaycastAll(gunAtt.spawn.position, bulletDir, gunAtt.maxBulletDistance, bulletMask); // raycastAll - get hits gunAtt.SortArray(ref hits); // sort raycast hits by distance ManageHits(hits, SecFireGp.bulletPower, bulletDir, SecFireGp.bulletForceToRigidbodys, SecFireGp.damage + (SecFireGp.currentProjectilePrefab.GetComponent <RaycastBullet>().damage), SecFireGp.bulletSpeed, SecFireGp.bulletTrailExitForce, SecFireGp.bulletTrailPrefab, SecFireGp.bulletTrailExitPosRot, bulletDir, bulletMask); } else { for (int i = 0; i < SecFireGp.shrapnelCount; i++) { Vector3 bulletDir = xq * Quaternion.Euler(Random.Range(-SecFireGp.maxshrapnelSpread, SecFireGp.maxshrapnelSpread), Random.Range(-SecFireGp.maxshrapnelSpread, SecFireGp.maxshrapnelSpread), 0) * (firingToPos - SecFireGp.spawn.position).normalized; //Debug.DrawRay(gunAtt.spawn.position, bulletDir * 55, Color.red); RaycastHit[] hits = Physics.RaycastAll(SecFireGp.spawn.position, bulletDir, SecFireGp.maxBulletDistance, bulletMask); // raycastAll - get hits gunAtt.SortArray(ref hits); // sort raycast hits ManageHits(hits, SecFireGp.bulletPower, bulletDir, SecFireGp.bulletForceToRigidbodys, SecFireGp.damage + (SecFireGp.currentProjectilePrefab.GetComponent <RaycastBullet>().damage), SecFireGp.bulletSpeed, SecFireGp.bulletTrailExitForce, SecFireGp.bulletTrailPrefab, SecFireGp.bulletTrailExitPosRot, bulletDir, bulletMask); } } } #endregion Raycast Fire #region Projectile Fire else { //if (SecFireGp.firesCurClipObject && SecFireGp.curClipObject.GetComponent<Projectile>()) //{ // gunAtt.curClipObject.SetParent(null); // gunAtt.curClipObject.forward = xq * (firingToPos - gunAtt.spawn.position).normalized; // gunAtt.curClipObject.GetComponent<Projectile>().EnableProjectile(); //} //else { Instantiate(SecFireGp.projectilePrefab, gunAtt.spawn.position, xq); } } #endregion Projectile Fire // Apply Spreads after Fire target.localPosition = new Vector3(xSpread, ySpread, 0) + target.localPosition; _weaponBodyBob = bodySpread; _randomHandTwistSign = Random.Range(-1, 1); }