void Shoot() { // check line of sight losClear = true; if (checkLOS == true) { if (Time.time >= lastLosCheck + losCheckInterval) { RaycastHit _hit; Vector3 _startPos = weapons[curWeapon].script.exits[weapons[curWeapon].script.curExit].transform.position; if (Physics.Linecast(_startPos, _target.position, out _hit)) { // recursively search parent of hit collider for target losClear = UtilityMF.RecursiveParentTransformSearch(_target, _hit.transform); } lastLosCheck = Time.time; } } // fire weapons if (losClear == true) { if (weapons[curWeapon].script.RangeCheck(_target) == true) { // if targeting script can mark targets, mark when firing if (targetingScript.isMarkingTarg == true) { if (weapons.Length > 0) { targetingScript.SetMarkedTime(weapons[curWeapon].script.GetTimeOfFlight(_target)); } } if (alternatingFire == true && weapons.Length > 1) // alternate fire bewteen weapons { weapons[curWeapon].script.platformVelocity = platformScript.velocity; // send velocity to weapon script if (fullBurst == true && bursting != null) { // based on weapons[0] cycle rate. for best results, all weapons should have the same cycle time float _delay = lastFire + (weapons[0].script.cycleTime / weapons.Length); if (weapons[curWeapon].script.ReadyCheck() == true) // needed to keep weapon cycle time in sync with delay in this script. (Make sure ShootBurst() is ready to be called) { if (Time.time >= _delay) { bursting = true; if (weapons[curWeapon].burst == false) { weapons[curWeapon].burst = true; weapons[curWeapon].script.ShootBurst(); curWeapon = MFmath.Mod(curWeapon + 1, weapons.Length); lastFire = Time.time; } } } } else { // based on weapons[0] cycle rate. for best results, all weapons should have the same cycle time if (Time.time >= lastFire + (weapons[0].script.cycleTime / weapons.Length)) { weapons[curWeapon].script.Shoot(); curWeapon = MFmath.Mod(curWeapon + 1, weapons.Length); lastFire = Time.time; } } } else // fire all weapons at once { for (int sw = 0; sw < weapons.Length; sw++) { weapons[sw].script.platformVelocity = platformScript.velocity; // send velocity to weapon script if (fullBurst == true && bursting != null) { bursting = true; if (weapons[sw].burst == false) { weapons[sw].burst = true; weapons[sw].script.ShootBurst(_target); } } else { weapons[sw].script.Shoot(_target); } } } } } }
void Shoot() { // check line of sight if (checkLOS == false || controller == ControlType.Player_Mouse || controller == ControlType.Player_Click) // always clear when not using LOS or under player control { losClear = true; } else { if (Time.time >= lastLosCheck + losCheckInterval) { RaycastHit _hit; losClear = false; Vector3 _startPos = weapons[curWeapon].script.exits[weapons[curWeapon].script.curExit].transform.position; bool _directLos = (turretScript.useGravity == false || alwaysDirectLos == true) ? true : false; if (_directLos == false) // use ballistic approximation los line { float? _shotSpeed = turretScript.shotSpeed; Vector3 _startDir = weapons[curWeapon].script.exits[weapons[curWeapon].script.curExit].transform.forward; Vector3 _startDirHoriz = new Vector3(_startDir.x, 0f, _startDir.z); int _factor = -Physics.gravity.y > 0 ? 1 : -1; float _aimAngle = MFmath.AngleSigned(_startDirHoriz, _startDir, Vector3.Cross(_startDir, Vector3.up)); if (_factor * _aimAngle > 0) // aiming up, find apex, use los to apex and then to target { float _ballRange = (float)((_shotSpeed * _shotSpeed) * Mathf.Sin(_factor * 2 * _aimAngle * Mathf.Deg2Rad)) / (_factor * -Physics.gravity.y); // compare range if ((_startPos - _target.position).sqrMagnitude <= _ballRange * _ballRange * .25) // squaring 1/2 _ballRange { _directLos = true; // if target before apex, just use direct los } else // continue to do ballistic los { Vector3 _midPos = _startPos + (_startDirHoriz.normalized * _ballRange * .5f); float _ballPeak = (float)((_startDir.y * _shotSpeed) * (_startDir.y * _shotSpeed)) / (-Physics.gravity.y * 2f); Vector3 _apexPos = _midPos + (Vector3.up * _ballPeak); // //Debug.DrawLine( _startPos, _startPos + ((_startDirHoriz).normalized * _ballRange), Color.cyan, .1f ); // Debug.DrawLine( _startPos, target.transform.position, Color.green, .1f ); // Debug.DrawLine( _startPos, _apexPos, Color.red, .1f ); // Debug.DrawLine( _apexPos, target.transform.position, Color.red, .1f ); // check los if (Physics.Linecast(_startPos, _apexPos, out _hit)) // check exit to apex // recursively search parent of hit collider for target { losClear = UtilityMF.RecursiveParentTransformSearch(_target, _hit.transform); } else if (Physics.Linecast(_apexPos, _target.position, out _hit)) // check apex to target // recursively search parent of hit collider for target { losClear = UtilityMF.RecursiveParentTransformSearch(_target, _hit.transform); } if (losClear == false) { if (losMayChangeArc == true) { turretScript.curArc = turretScript.defaultArc == MFnum.ArcType.Low ? MFnum.ArcType.High : MFnum.ArcType.Low; } } } } else // aiming downwards (already past apex) just use direct los { _directLos = true; } } if (_directLos == true) // use direct los line { if (Physics.Raycast(_startPos, _target.position - _startPos, out _hit, weapons[curWeapon].script.maxRange)) { // recursively search parent of hit collider for target losClear = UtilityMF.RecursiveParentTransformSearch(_target, _hit.transform); } } lastLosCheck = Time.time; } } // fire weapons if (losClear == true) { if (weapons[curWeapon].script.RangeCheck(_target) == true) { if (alternatingFire == true && weapons.Length > 1) // alternate fire bewteen weapons { weapons[curWeapon].script.platformVelocity = turretScript.velocity; // send velocity to current weapon script if (fullBurst == true && bursting != null) { // based on weapons[0] cycle rate. for best results, all weapons should have the same cycle time float _delay = lastFire + (weapons[0].script.cycleTime / weapons.Length); if (weapons[curWeapon].script.ReadyCheck() == true) // needed to keep weapon cycle time in sync with delay in this script. (Make sure ShootBurst() is ready to be called) { if (Time.time >= _delay) { bursting = true; if (weapons[curWeapon].burst == false) { weapons[curWeapon].burst = true; weapons[curWeapon].script.ShootBurst(); curWeapon = MFmath.Mod(curWeapon + 1, weapons.Length); lastFire = Time.time; } } } } if (fullBurst == false) { // based on weapons[0] cycle rate. for best results, all weapons should have the same cycle time if (Time.time >= lastFire + (weapons[0].script.cycleTime / weapons.Length)) { weapons[curWeapon].script.Shoot(); turretScript.curArc = turretScript.defaultArc; // reset default arc curWeapon = MFmath.Mod(curWeapon + 1, weapons.Length); lastFire = Time.time; } } } else // fire all weapons at once { for (int sw = 0; sw < weapons.Length; sw++) { weapons[sw].script.platformVelocity = turretScript.velocity; // send velocity to all weapon scripts if (fullBurst == true && bursting != null) { bursting = true; if (weapons[sw].burst == false) { weapons[sw].burst = true; weapons[sw].script.ShootBurst(); } } else { weapons[sw].script.Shoot(); turretScript.curArc = turretScript.defaultArc; // reset default arc } } } } } }