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); }
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); } } }
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); } } }
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(); } }