private void consider(Cover cover, Vector3 position, int direction, Vector3 observer, float maxDistance) { if (float.IsNaN(position.x) || float.IsNaN(position.z)) { return; } CoverItem item = new CoverItem(); item.Cover = cover; item.Position = position; item.Position.y = cover.Bottom; item.Distance = Vector3.Distance(observer, item.Position); item.Direction = direction; var distanceToObserver = Vector3.Distance(observer, item.Position); if (distanceToObserver > maxDistance) { return; } var areThereOthers = false; const float threshold = 3; if (cover.IsTall) { if (!AIUtil.IsCoverPositionFree(cover, item.Position, threshold, null)) { areThereOthers = true; } } else { var hasChangedPosition = false; Vector3 side; if (Vector3.Dot((item.Position - observer).normalized, cover.Right) > 0) { side = cover.Right; } else { side = cover.Left; } do { hasChangedPosition = false; if (!AIUtil.IsCoverPositionFree(cover, item.Position, threshold, null)) { var next = item.Position + side * 0.5f; if (cover.IsInFront(next, false)) { item.Position = next; hasChangedPosition = true; } else { areThereOthers = true; } } }while (hasChangedPosition); } if (areThereOthers) { return; } Items.Add(item); }
private bool isValidCover(Cover cover, Vector3 position, int direction, bool checkPath, bool avoidPivot = true) { if (cover == _unreachableCover) { return(false); } if (_isKeepingCloseTo && Vector3.Distance(position, _keepCloseTo.Position) > _keepCloseTo.Distance) { return(false); } if (!_hasPivot) { if (!AIUtil.IsCoverPositionFree(cover, position, 1, _actor)) { return(false); } return(true); } if (!_hasCachedEnemies) { _cachedEnemyCount = 0; _hasCachedEnemies = true; var totalActorCount = AIUtil.FindActors(position, MinDefenselessDistance, _actor); if (totalActorCount > 0) { var enemyCount = 0; for (int i = 0; i < totalActorCount; i++) { if (AIUtil.Actors[i].Side != _actor.Side) { enemyCount++; } } if (enemyCount > 0) { if (_cachedEnemies == null || _cachedEnemies.Length < enemyCount) { _cachedEnemies = new Actor[enemyCount]; } var index = 0; for (int i = 0; i < totalActorCount; i++) { if (AIUtil.Actors[i].Side != _actor.Side) { _cachedEnemies[index++] = AIUtil.Actors[i]; } } _cachedEnemyCount = index; } } } for (int i = 0; i < _cachedEnemyCount; i++) { var enemy = _cachedEnemies[i]; if (enemy.Side != _actor.Side) { var enemyPosition = enemy.transform.position; var distance = Vector3.Distance(position, enemyPosition); if (distance < AvoidDistance) { return(false); } if (!AIUtil.IsGoodAngle(MaxTallCoverThreatAngle, MaxLowCoverThreatAngle, cover, position, enemyPosition, cover.IsTall)) { return(false); } } } if (_isPivotThreat) { var distance = Vector3.Distance(position, _pivotPosition); if (_hasMaxPivotDistance && distance > _maxPivotDistance) { return(false); } var aimPosition = position; if (AIUtil.IsObstructed(aimPosition + (_actor.StandingTopPosition - transform.position), _pivotPosition + Vector3.up * 2)) { return(false); } } else { var distance = Vector3.Distance(position, _pivotPosition); if (_hasMaxPivotDistance && distance > _maxPivotDistance) { return(false); } if (!AIUtil.IsGoodAngle(MaxDefenseAngle, MaxDefenseAngle, cover, _pivotPosition, position, cover.IsTall)) { return(false); } } if (!AIUtil.IsCoverPositionFree(cover, position, 1, _actor)) { return(false); } if (checkPath) { if (NavMesh.CalculatePath(transform.position, position, 1, _path)) { if (avoidPivot) { var count = _path.GetCornersNonAlloc(_corners); for (int i = 0; i < count; i++) { var a = i == 0 ? transform.position : _corners[i - 1]; var b = _corners[i]; var closest = Util.FindClosestToPath(a, b, _pivotPosition); if (Vector3.Distance(closest, _pivotPosition) < AvoidDistance) { return(false); } } } } else { return(false); } } return(true); }
private bool isValidCover(Cover cover, Vector3 position, int direction, bool checkPath) { if (!_hasThreat) { return(true); } if (Vector3.Distance(position, _threatPosition) < AvoidDistance) { return(false); } if (!AIUtil.IsGoodAngle(MaxTallCoverAngle, MaxLowCoverAngle, cover, position, _threatPosition, cover.IsTall)) { return(false); } if (!AIUtil.IsCoverPositionFree(cover, position, 1, _actor)) { return(false); } var aimPosition = position; if (cover.IsTall) { var angle = Util.AngleOfVector(_threatPosition - position); if (direction > 0) { if (!cover.IsFrontField(angle, _motor.CoverSettings.Angles.TallRightCornerFront)) { return(false); } if (!cover.IsRight(angle, _motor.CoverSettings.Angles.RightCorner, false)) { return(false); } aimPosition = cover.RightCorner(cover.Bottom, _motor.CoverSettings.CornerOffset.x); } else if (direction < 0) { if (!cover.IsFrontField(angle, _motor.CoverSettings.Angles.TallLeftCornerFront)) { return(false); } if (!cover.IsLeft(angle, _motor.CoverSettings.Angles.LeftCorner, false)) { return(false); } aimPosition = cover.LeftCorner(cover.Bottom, _motor.CoverSettings.CornerOffset.x); } } if (AIUtil.IsObstructed(aimPosition + (_actor.StandingTopPosition - transform.position), _threatPosition + Vector3.up * 2, 100)) { return(false); } if (checkPath) { if (Vector3.Distance(transform.position, _threatPosition) > AvoidDistance) { if (NavMesh.CalculatePath(transform.position, position, 1, _path)) { for (int i = 0; i < _path.GetCornersNonAlloc(_corners); i++) { var a = i == 0 ? transform.position : _corners[i - 1]; var b = _corners[i]; var closest = Util.FindClosestToPath(a, b, _threatPosition); if (Vector3.Distance(closest, _threatPosition) < AvoidDistance) { return(false); } } } else { return(false); } } } return(true); }