void Init()
        {
            var cathetus = Mathf.Sqrt((_searchRadius * _searchRadius) / 2);

            _searchBounds = new Vector3(cathetus, 0, cathetus);
            _unit         = GetComponent <RBTUnit>();
        }
        void FixedUpdate()
        {
            if (_unit.CommandGroupId != "" || !_unit.Alive)
            {
                return;
            }

            var     nearbyUnits = RBTUnitBehaviourManager.UnitGrid.FindNear(_unit.Position, _searchBounds);
            var     sqrRadius   = _searchRadius * _searchRadius;
            RBTUnit closestUnit = null;
            float   closestDist = 0;

            foreach (var unit in nearbyUnits)
            {
                var dist = (unit.Position - _unit.Position).sqrMagnitude;
                if (dist < sqrRadius && unit.Team != _unit.Team && unit.Alive)
                {
                    if (closestUnit == null || dist < closestDist)
                    {
                        closestDist = dist;
                        closestUnit = unit;
                    }
                    break;
                }
            }
            if (closestUnit)
            {
                RBTUnitBehaviourManager.Instance.CommandAttack(new List <RBTUnit>()
                {
                    _unit
                }, closestUnit);
            }
        }
Пример #3
0
        public void Add(RBTUnit unit)
        {
            if (_unitToCells.ContainsKey(unit))
            {
                return;
            }
            else
            {
                _unitToCells.Add(unit, new List <CellNode>());
            }

            var cellIndices = CalcOccupiedCells(unit);

            foreach (var cellIndex in cellIndices)
            {
                var newHead = new CellNode()
                {
                    unit = unit, cellIndex = cellIndex
                };
                if (_indexToCell.ContainsKey(cellIndex))
                {
                    var prevHead = _indexToCell[cellIndex];
                    prevHead.previous = newHead;
                    newHead.next      = prevHead;
                }

                _indexToCell[cellIndex] = newHead;
                _unitToCells[unit].Add(newHead);
            }
        }
Пример #4
0
        public void Remove(RBTUnit unit)
        {
            var cellNodes = _unitToCells[unit];

            foreach (var node in cellNodes)
            {
                var previous = node.previous;
                var next     = node.next;

                if (previous == null && next == null)
                {
                    _indexToCell.Remove(node.cellIndex);
                }
                else
                {
                    if (previous != null)
                    {
                        previous.next = next;
                    }
                    if (next != null)
                    {
                        next.previous = previous;
                    }
                }
            }

            _unitToCells.Remove(unit);
        }
        public HashSet <RBTUnit> FindNear(RBTUnit unit)
        {
            var grid  = RBTUnitBehaviourManager.UnitGrid;
            var scale = GetLargestDimension(unit.Bounds.Extents);
            var scaledSearchBounds = _baseSearchBounds * scale;

            return(grid.FindNear(unit.Position, scaledSearchBounds));
        }
        public bool WithinFov(RBTUnit source, RBTUnit target)
        {
            var dirSourceToTarget = (target.Position - source.Position).normalized;
            var sourceVelocityDir = source.Velocity.normalized;

            var dotProd = Vector3.Dot(dirSourceToTarget, sourceVelocityDir);

            return(dotProd > _minFovDotProd);
        }
        public List <RBTUnit> GetUnitsWithinFov(RBTUnit unit)
        {
            var nearby          = FindNear(unit);
            var nearbyWithinFov = new List <RBTUnit>();

            nearbyWithinFov.Capacity = nearbyWithinFov.Count;
            foreach (var nu in nearby)
            {
                if (WithinFov(unit, nu))
                {
                    nearbyWithinFov.Add(nu);
                }
            }
            return(nearbyWithinFov);
        }
        // Public
        public float GetMaxDistance(RBTUnit unit)
        {
            var scale = GetLargestDimension(unit.Bounds.Extents);

            return(Reach * scale);
        }
Пример #9
0
 public Vector3Int[] GetOccupiedCells(RBTUnit unit)
 {
     return(_unitToCells[unit].Select(node => node.cellIndex).ToArray());
 }
Пример #10
0
        List <Vector3Int> CalcOccupiedCells(RBTUnit unit)
        {
            var boundsCorners = unit.Bounds.Corners;
            // var cellIndices = new HashSet<Vector3Int>();
            var occupiedCells = new OccupiedCells();

            for (int i = 0; i < 4; i++)
            {
                var startCorner = boundsCorners[i % 4];
                var endCorner   = boundsCorners[(i + 1) % 4];

                var startCell = GetCellIndex(startCorner);
                var endCell   = GetCellIndex(endCorner);

                occupiedCells.Add(startCell);
                if (startCell == endCell)
                {
                    continue;
                }
                occupiedCells.Add(endCell);

                var rayDir = (endCorner - startCorner).normalized;

                var step_dzdx = Mathf.Abs(rayDir.z / (rayDir.x + 0.0001f));
                var step_dxdz = Mathf.Abs(rayDir.x / (rayDir.z + 0.0001f));

                var rayStepX = Mathf.Sqrt(1 + Mathf.Pow(step_dzdx, 2));
                var rayStepZ = Mathf.Sqrt(1 + Mathf.Pow(step_dxdz, 2));

                int   stepX, stepZ;
                float initialAdjustmentX, initialAdjustmentZ;

                if (rayDir.x < 0)
                {
                    stepX = -1;
                    initialAdjustmentX = startCorner.x - startCell.x;
                }
                else
                {
                    stepX = 1;
                    initialAdjustmentX = (startCell.x + 1) - startCorner.x;
                }

                if (rayDir.z < 0)
                {
                    stepZ = -1;
                    initialAdjustmentZ = startCorner.z - startCell.z;
                }
                else
                {
                    stepZ = 1;
                    initialAdjustmentZ = (startCell.z + 1) - startCorner.z;
                }

                step_dxdz *= stepX;
                step_dzdx *= stepZ;

                var rayLengthX = initialAdjustmentX * rayStepX;
                var rayLengthZ = initialAdjustmentZ * rayStepZ;

                float zAlongX = startCorner.z + step_dzdx * initialAdjustmentX;
                float xAlongZ = startCorner.x + step_dxdz * initialAdjustmentZ;

                var maxRayLength = (endCorner - startCorner).magnitude;

                var currentCellX = GetCellIndex(new Vector3(startCorner.x + stepX * initialAdjustmentX, startCorner.y, zAlongX));
                if (rayLengthX < maxRayLength)
                {
                    occupiedCells.Add(currentCellX);
                }

                var currentCellZ = GetCellIndex(new Vector3(xAlongZ, startCorner.y, startCorner.z + stepZ * initialAdjustmentZ));
                if (rayLengthZ < maxRayLength)
                {
                    occupiedCells.Add(currentCellZ);
                }

                bool endCellReached = false;
                while (!endCellReached)
                {
                    bool commonAdjacentCell = currentCellZ.z - currentCellX.z == 1 && currentCellX.x - currentCellZ.x == 1;
                    if (commonAdjacentCell)
                    {
                        occupiedCells.Add(new Vector3Int(currentCellZ.x, startCell.y, currentCellX.z));
                    }

                    if (rayLengthX < rayLengthZ)
                    {
                        rayLengthX += rayStepX;
                        if (rayLengthX < maxRayLength)
                        {
                            zAlongX        += step_dzdx;
                            currentCellX.x += stepX;
                            currentCellX.z  = Mathf.FloorToInt(zAlongX);
                            occupiedCells.Add(currentCellX);
                        }
                    }
                    else
                    {
                        rayLengthZ += rayStepZ;
                        if (rayLengthZ < maxRayLength)
                        {
                            xAlongZ        += step_dxdz;
                            currentCellZ.z += stepZ;
                            currentCellZ.x  = Mathf.FloorToInt(xAlongZ);
                            occupiedCells.Add(currentCellZ);
                        }
                    }

                    endCellReached = rayLengthX >= maxRayLength && rayLengthZ >= maxRayLength;
                }
            }

            foreach (var entry in occupiedCells.rowEdgeValues)
            {
                var valuePair = entry.Value;
                var smallestX = valuePair.Item1;
                var biggestX  = valuePair.Item2;
                var z         = entry.Key;
                var y         = Mathf.FloorToInt(boundsCorners[0].y);
                for (int x = smallestX + 1; x < biggestX; x++)
                {
                    occupiedCells.Add(new Vector3Int(x, y, z));
                }
            }

            int topCount = occupiedCells.Count;
            var allCells = new List <Vector3Int>();

            allCells.Capacity = topCount;
            foreach (var row in occupiedCells.rowToCells.Values)
            {
                foreach (var cell in row)
                {
                    allCells.Add(cell);
                }
            }
            var diffY = GetCellIndex(boundsCorners[0]).y - GetCellIndex(boundsCorners[4]).y;

            for (int y = 1; y <= diffY; y++)
            {
                for (int i = 0; i < topCount; i++)
                {
                    allCells.Add(new Vector3Int(allCells[i].x, allCells[i].y - y, allCells[i].z));
                }
            }

            return(allCells);
        }
Пример #11
0
 public void Update(RBTUnit unit)
 {
     Remove(unit);
     Add(unit);
 }
 public UnitEvent(RBTUnit sender)
 {
     Sender = sender;
 }
 public OnStateChangedEvent(RBTUnit sender, UnitState prevState, UnitState newState)
     : base(sender)
 {
     PrevState = prevState;
     NewState  = newState;
 }
 public OnDeActivatedEvent(RBTUnit sender)
     : base(sender)
 {
 }
 public OnDeselectedEvent(RBTUnit sender)
     : base(sender)
 {
 }