private bool considerPoint(InvestigatedPoint point) { if (point.Time < _timeOfReset) { return(false); } if (_hasPoint && areCloseEnough(point, _point)) { _hasPoint = false; markInvestigated(point); return(true); } if (considerPoint(_block, point)) { return(true); } for (int i = 0; i < _blocks.Count; i++) { if (considerPoint(_blocks[i], point)) { if (_blocks[i].Empty) { _investigatedBlocks.Add(_blocks[i]); _blocks.RemoveAt(i); } return(true); } } return(false); }
private bool areCloseEnough(InvestigatedPoint a, SearchPoint b) { if (Vector3.Distance(a.Position, b.Position) < 0.5f) { return(true); } return(false); }
private void finishInvestigatingThePoint() { var point = new InvestigatedPoint(_point.Position); _hasPoint = false; markInvestigated(point); for (int i = 0; i < _friends.Count; i++) { _friends[i].considerPoint(point); } }
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); }
/// <summary> /// Told by the brains to force mark a position as investigated. /// </summary> public void ToMarkPointInspected(Vector3 position) { if (!isActiveAndEnabled) { return; } var point = new InvestigatedPoint(position); if (!considerPoint(point)) { markInvestigated(point); } foreach (var friend in _friends) { friend.considerPoint(point); } }
/// <summary> /// Told by the brains to force mark a position as investigated. /// </summary> public void ToMarkPointInspected(Vector3 position) { if (!isActiveAndEnabled) { return; } var point = new InvestigatedPoint(position); if (!considerPoint(point)) { markInvestigated(point); } for (int i = 0; i < _friends.Count; i++) { _friends[i].considerPoint(point); } }
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 markInvestigated(InvestigatedPoint point) { _investigated.Add(point); Message("OnPointInvestigated", point.Position); }
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); } } }