Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }