public static float?BallisticIteration(Vector3 exitLoc, float?shotSpeed, float aimRad, MFnum.ArcType arc, Transform target, Vector3 targetVelocity, Vector3 platformVelocity, Vector3 aimLoc_In, out Vector3 aimLoc_Out) { float?_ballAim = null; aimLoc_Out = aimLoc_In; // find new flight time float?_flightTime = MFball.BallisticFlightTime(aimLoc_In, exitLoc, (float)shotSpeed, aimRad, arc); float _effectiveShotSpeed = Vector3.Distance(exitLoc, aimLoc_In) / (float)_flightTime; // find intercept based on new _effectiveShotSpeed Vector3?_intAim = MFcompute.Intercept(exitLoc, platformVelocity, _effectiveShotSpeed, target.position, targetVelocity); if (_intAim == null) { _ballAim = null; } else { aimLoc_Out = (Vector3)_intAim; // modify target aim location // re-calculate ballistic trajectory based on intercept point _ballAim = MFball.BallisticAimAngle(aimLoc_Out, exitLoc, (float)shotSpeed, arc); } return(_ballAim); }
public override Vector3 AimLocation() { // intercept and ballistics if ( _target ) { Vector3 _targetVelocity = Vector3.zero; targetLoc = _target.position; if ( useIntercept == true && shotSpeed != null ) { // target velocity if (targetRigidbody) { // if target has a rigidbody, use velocity _targetVelocity = targetRigidbody.velocity; } else { // otherwise compute velocity from change in position _targetVelocity = ( targetLoc - lastTargetPosition ) / Time.deltaTime; lastTargetPosition = targetLoc; } } if ( useGravity == true && Physics.gravity.y != 0 && shotSpeed != null ) { // ballistic aim int _factor = -Physics.gravity.y > 0 ? 1 : -1; // find initial aim angle float? _ballAim = MFball.BallisticAimAngle( targetLoc, exitLoc, (float)shotSpeed, curArc ); if ( _ballAim == null ) { target = null; } else { if ( useIntercept == true && playerControl == false ) { // ballistic + intercept // iterate for better ballistic accuracy when also using intercept int bi = 0; int biMax; if ( curArc == MFnum.ArcType.High ) { biMax = highArcBallisticIterations; } else { biMax = ballisticIterations; } while ( _target && bi++ < biMax ) { // _ballAim = BallisticIteration ( exitLoc, (float)shotSpeed, (float)_ballAim, _targetVelocity ); _ballAim = MFball.BallisticIteration ( exitLoc, (float)shotSpeed, (float)_ballAim, curArc, _target, _targetVelocity, velocity, targetLoc, out targetLoc ); if ( _ballAim == null ) { target = null; } // no solution, release target } } if ( _target ) { // target can become null in balistic iteration if no solution Vector3 _cross = -Vector3.Cross( ( targetLoc - exitLoc ), Vector3.up ); Quaternion _eleAngleDir = Quaternion.AngleAxis( _factor * (float)_ballAim * Mathf.Rad2Deg, -_cross ); targetAimLocation = exitLoc + (( _eleAngleDir * Vector3.Cross( _cross, Vector3.up ) ).normalized * targetRange ); } } } else { // no gravity if ( useIntercept == true && playerControl == false && shotSpeed != null ) { // point at linear intercept position Vector3? _interceptAim = MFcompute.Intercept( exitLoc, velocity, (float)shotSpeed, targetLoc, _targetVelocity ); if ( _interceptAim == null ) { target = null; } else { targetAimLocation = (Vector3)_interceptAim; } } else { // point at target position targetAimLocation = _target.position; } } } else { targetAimLocation = Vector3.zero; } return targetAimLocation; }