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); } }
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); }
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); }
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]); } }
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); } } }
public void Give(SearchBlock block) { _cache.Add(block); }
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 Awake() { _block = new SearchBlock(_points); _blockCache = new SearchBlockCache(_points); _actor = GetComponent <Actor>(); }
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(); } }