private bool updateIsMelee() { _meleeTarget = null; var weapon = _motor.EquippedWeapon; if (!weapon.HasMelee || weapon.Gun != null) { return(false); } var minDist = 0f; for (int i = 0; i < AIUtil.FindActors(_motor.transform.position, MeleeRadius, _actor); i++) { var actor = AIUtil.Actors[i]; if (actor.Side == _actor.Side) { continue; } var dist = Vector3.Distance(_motor.transform.position, actor.transform.position); if (_meleeTarget == null || dist < minDist) { _meleeTarget = actor; minDist = dist; } } return(_meleeTarget != null); }
private bool checkIncomingCollisions(Vector3 ownMovement, float speed) { var count = AIUtil.FindActors(transform.position, ObstructionRadius, _actor); var ownMovementMagnitude = ownMovement.magnitude; var hasOwnMovement = ownMovementMagnitude > 0.25f; var ownDirection = ownMovement / ownMovementMagnitude; var closestDot = 0f; var closestVector = Vector3.zero; var closestDirection = Vector3.zero; var closestPosition = Vector3.zero; var isClosestPrimary = false; var isClosestStatic = false; var hasClosest = false; for (int i = 0; i < count; i++) { var other = AIUtil.Actors[i]; if (other.Side != _actor.Side && other.IsAggressive && _actor.IsAggressive) { continue; } Vector3 velocity; float magnitude; var movement = _movements.ContainsKey(other) ? _movements[other] : null; var isStatic = false; if (movement != null && movement._isAvoidingMover) { velocity = movement._avoidDirection; magnitude = 1; } else { velocity = other.Motor.MovementDirection; magnitude = velocity.magnitude; if (magnitude < 0.1f) { var body = other.Body; if (body == null) { continue; } velocity = body.velocity; magnitude = velocity.magnitude; if (magnitude < 0.1f) { if (hasOwnMovement) { isStatic = true; velocity = -ownMovement; magnitude = 1; } else { continue; } } } } var direction = velocity / magnitude; if (hasOwnMovement && Vector3.Dot(ownDirection, direction) > -0.5f) { continue; } var vector = (transform.position - other.transform.position).normalized; var dot = Vector3.Dot(direction, vector); if (dot < 0.7f) { continue; } var isPrimary = (movement == null ? true : !movement._isAvoidingMover) && !isStatic; if (!hasClosest || (isClosestStatic && !isStatic) || (isPrimary && !isClosestPrimary) || (isPrimary && dot > closestDot) || (!isPrimary && !isClosestPrimary && dot > closestDot)) { hasClosest = true; isClosestPrimary = isPrimary; isClosestStatic = isStatic; closestPosition = other.transform.position; closestDirection = direction; closestVector = vector; closestDot = dot; } } if (hasClosest) { if (!isClosestPrimary && !isClosestStatic && !hasOwnMovement && canMoveInDirection(closestVector)) { return(avoid(closestVector, speed)); } var point = Util.FindClosestToPath(closestPosition, closestPosition + closestDirection * 100, transform.position); var vector = transform.position - point; var distance = vector.magnitude; if (distance < 0.1f) { var right = Vector3.Cross(closestVector, Vector3.up); var left = -right; if (hasOwnMovement && isClosestStatic) { right = (right + ownMovement).normalized; left = (left + ownMovement).normalized; } if (canMoveInDirection(right)) { return(avoid(right, speed)); } if (canMoveInDirection(left)) { return(avoid(left, speed)); } } else { var direction = vector / distance; if (hasOwnMovement && isClosestStatic) { direction = (direction + ownMovement).normalized; } if (canMoveInDirection(direction)) { return(avoid(direction, speed)); } } if (isClosestPrimary && !isClosestStatic && !hasOwnMovement && canMoveInDirection(closestVector)) { return(avoid(closestVector, speed)); } } return(false); }
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); }