More Aggressive Enemy

I wanted my enemies to chase my players more aggressively, so I implemented the following code to MoveAction. Basically if no movements will take an enemy within shooting range of a player unit, then it will cycle through all of the valid movement positions until it finds a tile with the shortest movement distance to the nearest player. I was wondering if people have any thoughts on this type of implementation or additional advice (code below)?

My current thoughts are that

  1. it’s very aggressive, some enemies will definitely need an aggro range function or something that cuts their movement distance when moving towards enemies that aren’t very nearby
  2. I haven’t integrated the pathfinding algorithm into it yet, so enemies can end up in suboptimal locations that are blocked by walls and such. Should be an easy fix, I just haven’t done it yet.

So, other thoughts/implementation methods? Thanks!

public override EnemyAIAction GetEnemyAIAction(GridPosition gridPosition)
    {
        int finalActionValue;

        int targetCountAtGridPosition = _unit.GetAction<ShootAction>().GetTargetCountAtGridPosition(gridPosition);
        int targetPointValue = 10;

        finalActionValue = targetCountAtGridPosition * targetPointValue;

        int distanceToNearestTargetAtGridPosition = 0;
        // if no targets are in range, then try to find a move point towards the closest target unit
        if (targetCountAtGridPosition == 0)
        {
            distanceToNearestTargetAtGridPosition = GetDistanceToNearestTargetAtGridPosition(gridPosition);
            finalActionValue = 
                _maxMoveDistance * Pathfinding._Instance._PathfindingDistanceMultplier - 
                distanceToNearestTargetAtGridPosition;
        }

        return new EnemyAIAction
        {
            gridPosition = gridPosition,
            actionValue = finalActionValue
        };
    }
private int GetDistanceToNearestTargetAtGridPosition(GridPosition gridPosition)
    {
        List<Unit> targetUnits = UnitManager._Instance._FriendlyUnitList;

        if (targetUnits == null) 
        {
            Debug.LogError("No target units found, this battle should be over.");
            return 0;
        }
        
        // initialize nearest unit and distance
        Unit nearestTarget = targetUnits[0];
        int distance = int.MaxValue;

        foreach (Unit target in targetUnits)
        {
            int testDistance = Pathfinding._Instance.GetPathLength(gridPosition, target._CurrentGridPosition);
            if (testDistance < distance)
            {
                nearestTarget = target;
                distance = testDistance;
            }
        }

        return distance;
    }
3 Likes

I thought about this a little bit more, and I think when I do the initial GetTargetCountAtGridPosition check, if that position is at the max movement distance, I can add it to a list. Then if I need to do the GetDistanceToNearestTargetAtGridPosition check, I only need to run it against the positions at the periphery of the enemy’s movement range. This should help optimize that function, especially when I hook it back up to the pathfinding system.

2 Likes

Yup that’s a good way to do it and yup adding a simple aggro range will indeed make it work great.
Keep them just walking around randomly when not aggroed, then when a player gets close enough start running that logic.

2 Likes

Privacy & Terms