Example #1
0
        private void debugBlock(SearchBlock block)
        {
            var color = Color.white;

            switch (block.Index % 5)
            {
            case 0: color = Color.red; break;

            case 1: color = Color.green; break;

            case 2: color = Color.blue; break;

            case 3: color = Color.yellow; break;

            case 4: color = Color.cyan; break;
            }

            for (int i = 0; i < block.Count; i++)
            {
                debugPoint(block.Get(i), false, color);
            }

            foreach (var index in block.InvestigatedIndices)
            {
                debugPoint(_points.Points[index], !_hasPoint || index != _pointIndex, color);
            }
        }
Example #2
0
        private bool findBestPoint(SearchBlock block, out int pointIndex, out float pointValue)
        {
            var pickedIndex   = -1;
            var previousValue = 0f;

            var previousLeft  = -1;
            var previousRight = -1;

            if (_hasPreviousPoint)
            {
                var previousPoint = _points.Points[_previousPointIndex];
                previousLeft  = previousPoint.Left;
                previousRight = previousPoint.Right;
            }

            for (int i = 0; i < block.Count; i++)
            {
                var index = block.Indices[i];
                var point = block.Get(i);

                var vector    = _searchPosition - point.Position;
                var distance  = vector.magnitude;
                var direction = vector / distance;

                var value = distance;

                if (_hasPreviousPoint && (index == previousLeft || index == previousRight))
                {
                    value *= -1;
                }
                else
                {
                    if (_hasSearchDirection)
                    {
                        value *= -Vector3.Dot(direction, _searchDirection) * 0.5f + 1.5f;
                    }
                    else
                    {
                        value *= -Vector3.Dot(direction, _actor.HeadDirection) * 0.5f + 1.5f;
                    }
                }

                if (pickedIndex < 0 || (value > 0 && value < previousValue) || (value < 0 && previousValue < 0 && value > previousValue) || (value < 0 && previousValue > 0))
                {
                    pickedIndex   = i;
                    previousValue = value;
                }
            }

            pointIndex = pickedIndex;
            pointValue = previousValue;

            return(pointIndex >= 0);
        }
Example #3
0
        private bool considerPoint(SearchBlock block, InvestigatedPoint point)
        {
            for (int i = 0; i < block.Count; i++)
            {
                if (areCloseEnough(point, block.Get(i)))
                {
                    block.Investigate(i);
                    markInvestigated(point);
                    return(true);
                }
            }

            return(false);
        }
Example #4
0
        public void WriteTo(ref SearchBlock other)
        {
            other.Index  = Index;
            other.Sum    = Sum;
            other.Center = Center;

            other.Indices.Clear();
            other.InvestigatedIndices.Clear();

            for (int i = 0; i < Indices.Count; i++)
            {
                other.Indices.Add(Indices[i]);
            }

            for (int i = 0; i < InvestigatedIndices.Count; i++)
            {
                other.InvestigatedIndices.Add(InvestigatedIndices[i]);
            }
        }
Example #5
0
        private void glimpse(SearchBlock block)
        {
            for (int i = block.Count - 1; i >= 0; i--)
            {
                var p = block.Get(i);

                if (canBeInvestigated(p))
                {
                    var point = new InvestigatedPoint(p.Position);
                    markInvestigated(point);

                    foreach (var friend in _friends)
                    {
                        friend.considerPoint(point);
                    }

                    block.Investigate(i);
                }
            }
        }
Example #6
0
 public void Give(SearchBlock block)
 {
     _cache.Add(block);
 }
Example #7
0
        private void Update()
        {
            for (int i = _investigated.Count - 1; i >= 0; i--)
            {
                if (_investigated[i].Time < Time.timeSinceLevelLoad - MaxInvestigationAge)
                {
                    _investigated.RemoveAt(i);
                }
            }

            if (!_isSearching)
            {
                return;
            }

            if (_blocks.Count == 0 && !_hasPoint)
            {
                ToClearSearchHistory();

                _hasPreviousPoint = false;
                _points.Clear();

                foreach (var block in _investigatedBlocks)
                {
                    _blockCache.Give(block);
                }

                _investigatedBlocks.Clear();
                _usedCovers.Clear();
                _coverCache.Reset(transform.position, MaxDistance, false);

                foreach (var item in _coverCache.Items)
                {
                    if (_usedCovers.Contains(item.Cover))
                    {
                        continue;
                    }

                    var cover = item.Cover;

                    while (cover.LeftAdjacent != null && !_usedCovers.Contains(cover.LeftAdjacent))
                    {
                        cover = cover.LeftAdjacent;
                    }

                    var index = -1;

                    while (cover != null)
                    {
                        _usedCovers.Add(cover);

                        var left   = cover.LeftCorner(cover.Bottom) - cover.Forward * 0.25f;
                        var right  = cover.RightCorner(cover.Bottom) - cover.Forward * 0.25f;
                        var vector = right - left;
                        var length = vector.magnitude;

                        var leftApproach  = left;
                        var rightApproach = right;

                        {
                            NavMeshHit hit;
                            var        position = left + cover.Left * CoverOffset;

                            if (NavMesh.Raycast(left, position, out hit, 1))
                            {
                                leftApproach = left;
                            }
                            else
                            {
                                leftApproach = position;
                            }
                        }

                        {
                            NavMeshHit hit;
                            var        position = right + cover.Right * CoverOffset;

                            if (NavMesh.Raycast(right, position, out hit, 1))
                            {
                                rightApproach = right;
                            }
                            else
                            {
                                rightApproach = position;
                            }
                        }

                        if (cover.LeftAdjacent != null && cover.RightAdjacent != null)
                        {
                            leftApproach  = left;
                            rightApproach = right;
                        }
                        else if (cover.LeftAdjacent != null)
                        {
                            leftApproach = rightApproach;
                        }
                        else if (cover.RightAdjacent != null)
                        {
                            rightApproach = leftApproach;
                        }

                        possiblyAddRightPoint(ref index, new SearchPoint(left, leftApproach, -cover.Forward, false));

                        if (length > Advanced.BlockThreshold * 2)
                        {
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.2f, leftApproach, -cover.Forward, false));
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.4f, leftApproach, -cover.Forward, false));
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.6f, rightApproach, -cover.Forward, false));
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.8f, rightApproach, -cover.Forward, false));
                        }
                        else if (length > Advanced.BlockThreshold)
                        {
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.33f, leftApproach, -cover.Forward, false));
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.66f, rightApproach, -cover.Forward, false));
                        }

                        possiblyAddRightPoint(ref index, new SearchPoint(right, rightApproach, -cover.Forward, false));

                        if (cover.RightAdjacent != null && !_usedCovers.Contains(cover.RightAdjacent))
                        {
                            cover = cover.RightAdjacent;
                        }
                        else
                        {
                            cover = null;
                        }
                    }
                }

                _zoneCache.Reset(transform.position, MaxDistance);

                foreach (var block in _zoneCache.Items)
                {
                    foreach (var position in block.Points(Advanced.BlockThreshold))
                    {
                        addPoint(new SearchPoint(position, false));
                    }
                }

                mergeBlocks();
            }

            if (DebugPoints)
            {
                foreach (var block in _blocks)
                {
                    debugBlock(block);
                }

                foreach (var block in _investigatedBlocks)
                {
                    debugBlock(block);
                }
            }

            if (_blocks.Count == 0 && !_hasPoint)
            {
                return;
            }

            if (_block.Empty && !_hasPoint)
            {
                var pickedIndex   = -1;
                var previousValue = 0f;

                for (int i = 0; i < _blocks.Count; i++)
                {
                    var vector    = _searchPosition - _blocks[i].Center;
                    var distance  = vector.magnitude;
                    var direction = vector / distance;

                    var value = distance;

                    if (_hasBlockDirection)
                    {
                        value *= -Vector3.Dot(direction, _blockDirection) * 0.5f + 1.5f;
                    }
                    else
                    {
                        value *= -Vector3.Dot(direction, _actor.HeadDirection) * 0.5f + 1.5f;
                    }

                    if (pickedIndex < 0 || value < previousValue)
                    {
                        pickedIndex   = i;
                        previousValue = value;
                    }
                }


                if (pickedIndex != -1)
                {
                    _block = _blocks[pickedIndex];

                    _blocks.RemoveAt(pickedIndex);
                    _investigatedBlocks.Add(_block);

                    _hasBlockDirection = true;
                    _blockDirection    = (_block.Center - _searchPosition).normalized;
                }
            }

            if (!_hasPoint)
            {
                int   index;
                float value;
                findBestPoint(_block, out index, out value);

                setPoint(_block.Indices[index]);
                _block.Investigate(index);
            }

            if (!_hasApproached && !shouldApproach(_point))
            {
                _hasApproached = true;

                if (_wasRunning)
                {
                    run();
                }
                else
                {
                    walk();
                }
            }

            if (_wasRunning && !shouldRunTo(_point.Position))
            {
                walk();
            }

            _checkWait -= Time.deltaTime;

            if (_checkWait <= float.Epsilon)
            {
                glimpse(_block);

                for (int b = _blocks.Count - 1; b >= 0; b--)
                {
                    glimpse(_blocks[b]);

                    if (_blocks[b].Empty)
                    {
                        _investigatedBlocks.Add(_blocks[b]);
                        _blocks.RemoveAt(b);
                    }
                }

                _checkWait = 0.25f;
            }

            if (DebugTarget)
            {
                Debug.DrawLine(transform.position, _point.Position, Color.yellow);
            }

            if (canBeInvestigated(_point))
            {
                var point = new InvestigatedPoint(_point.Position);
                _hasPoint = false;

                markInvestigated(point);

                foreach (var friend in _friends)
                {
                    friend.considerPoint(point);
                }
            }
        }
Example #8
0
 private void Awake()
 {
     _block      = new SearchBlock(_points);
     _blockCache = new SearchBlockCache(_points);
     _actor      = GetComponent <Actor>();
 }
Example #9
0
        private void Update()
        {
            GlobalSearchCache.Update();

            if (!_isSearching)
            {
                return;
            }

            if (_blocks.Count == 0 && !_hasPoint)
            {
                _isSearching = false;
                Message("OnFinishSearch");
            }

            if (DebugPoints)
            {
                foreach (var block in _blocks)
                {
                    debugBlock(block);
                }

                foreach (var block in _investigatedBlocks)
                {
                    debugBlock(block);
                }
            }

            if (_block.Empty && !_hasPoint && _blocks.Count > 0)
            {
                var pickedIndex   = -1;
                var previousValue = 0f;

                for (int i = 0; i < _blocks.Count; i++)
                {
                    var vector    = _searchPosition - _blocks[i].Center;
                    var distance  = vector.magnitude;
                    var direction = vector / distance;

                    var value = distance;

                    if (_hasBlockDirection)
                    {
                        value *= -Vector3.Dot(direction, _blockDirection) * 0.5f + 1.5f;
                    }
                    else
                    {
                        value *= -Vector3.Dot(direction, _actor.HeadDirection) * 0.5f + 1.5f;
                    }

                    if (pickedIndex < 0 || value < previousValue)
                    {
                        pickedIndex   = i;
                        previousValue = value;
                    }
                }

                _block = _blocks[pickedIndex];
                _blocks.RemoveAt(pickedIndex);
                _investigatedBlocks.Add(_block);

                _hasBlockDirection = true;
                _blockDirection    = (_block.Center - _searchPosition).normalized;
            }

            if (!_hasPoint)
            {
                int   index;
                float value;

                if (findBestPoint(_block, out index, out value))
                {
                    setPoint(_block.Indices[index]);
                    _block.Investigate(index);
                }
            }

            if (!_hasPoint)
            {
                return;
            }

            if (!_hasApproached && !shouldApproach(_point))
            {
                _hasApproached = true;

                if (_wasRunning)
                {
                    run();
                }
                else
                {
                    walk();
                }
            }

            if (_wasRunning && !shouldRunTo(_point.Position))
            {
                walk();
            }

            _checkWait -= Time.deltaTime;

            if (_checkWait <= float.Epsilon)
            {
                glimpse(_block);

                for (int b = _blocks.Count - 1; b >= 0; b--)
                {
                    glimpse(_blocks[b]);

                    if (_blocks[b].Empty)
                    {
                        _investigatedBlocks.Add(_blocks[b]);
                        _blocks.RemoveAt(b);
                    }
                }

                _checkWait = 0.25f;
            }

            if (DebugTarget)
            {
                Debug.DrawLine(transform.position, _point.Position, Color.yellow);
            }

            if (canBeInvestigated(_point))
            {
                finishInvestigatingThePoint();
            }
        }