| Home Page | Recent Changes | Preferences

Bot Vision

Bots can snipe through pea-soup fog...

EntropicLqd: I have a problem - my bots can snipe me from a mile away in dense fog. This is somewhat unfair since I can't actually see them (nor they me). I've tried reducing the bot's sight radius but that has had no effect. Anyone have any other thoughts on making the bots only able to see very close targets? I've included the code (from my mutator subclass) I'm using to adjust the sight radius below.

function ModifyPlayer( Pawn Other ) {
    if ( Other.Controller != None ) {
        if ( Other.Controller.bIsPlayer && !Other.IsHumanControlled() ) {
            Log("Sight radius adjusted");
// repEndDist is the end distance of the fog
            Other.SightRadius = repEndDist / 8;

I'm still stuck on this one.

ZxAnPhOrIaN: I need that code for my level, wich uses dense fog.

EntropicLqd: The SightRadius is reset within the function Bot.ResetSkill(). This in turn is called from Bot.Possess(), Bot.InitialiseSkill(), and Bot.Restart(). My guess is that the SightRadius value is being reset to it's original value after the ModifyPlayer() function is called. I'll have a go at proving that tonight if I get time.

What are the implicatons of changing the Bot.Default.SightRadius value within the mutator? Will it screw up subsequent normal games or will the value be reset with each new game?

Mychaeel: In Unreal Tournament changes to a class's default properties persisted over level switches. I'm not so sure about that in UT2003 – it would be worth finding out for sure.

EntropicLqd: In UT2003 changes to a class's default properties persist not only over level changes, but also for the life of that instance of UT2003 - the value is not reset until you quit and re-load UT2003. Not only that but the SightRadius has bugger all effect on how far the bots can see to attack things - irrespective of what the code claims. I suspect the real problem lies within the AI attack code being able to pick out targets that the bot's can't see as it were.

Foxpaw: You could make a mutator that would subclass the bots - not the most compatible solution but maybe someone could find a better way. What you really want to do is to modify the Controller's PickTarget function... but you can't do that because it's native and final. So modify whatever calls it. Picktarget can take an argument that gives a maximum range for selecting a target. I'm not sure where it's called from. You could maybe call PickTarget every X amount of time (much more frequently than the bot's normally would) though that would not be very elegant. If you could find when the function is called you could maybe modify that function to pass an arbitrary maximum range to target people through the fog.

Bot Vision - Better than X-Ray

If you've ever spent any time attempting to make a mod that restricts the distance players can see, or their peripheral vision then you'll know that getting the Bots to behave in a believable manner is hard. This page will describe my on-going thoughts and musings on how to get things working in the manner you wish.

Finding Objects and General Navigation

Now, in general a Bot's view of the world is a network of nodes. Some of the paths between the nodes are "more expensive" than others, and a Bot will generally try and take the easiest path to wherever it is trying to get to. Generally, this may be armour, health, a weapon, or another pick up. Left to it's own devices a Bot will quite happily run around a level collecting stuff. The Bot knows where everything on the level is - because it can navigate through the network of nodes to find any object in the level. Remember, the nodes are placed on the level as PathNode objects, Inventory items, and other such stuff.

When a Bot has decided to go somewhere it stores information about it's route through the level in its Controller. This makes sense - the controller is responsible to directing the Bot, and the pawn (representing the Bot in game) is responsible for the animation. This distinction is more or less true. I'm not convinced that it is as cut and dried as that. It's best to think of the Controller as the Bot's brain, and the Pawn as the Bot's representation in the world.

The Controller class has some useful attributes to support this navigation, reproduced below for your pleasure and enjoyment.

var Actor     RouteCache[16]; // A cache of pathnodes the Bot needs to travel along to reach its goal?
var [[ReachSpec]] CurrentPath;
var vector    CurrentPathDir; // Direction the bot needs to travel to remain on it's "path"
var Actor     RouteGoal;      // final destination for current route
var float     RouteDist;      // total distance for current route
var float     LastRouteFind;  // time at which last route finding occured

// Some useful functions for Bot navigation are:
//Navigation functions - return the next path toward the goal
native(518) final function Actor FindPathTo(vector aPoint);
native(517) final function Actor FindPathToward(actor anActor, optional bool bWeightDetours);
native final function Actor FindPathToIntercept(Pawn P, Actor RouteGoal, optional bool bWeightDetours);
native final function Actor FindPathTowardNearest(class<NavigationPoint> GoalClass, optional bool bWeightDetours);
native(525) final function NavigationPoint FindRandomDest();

Seeing Enemies and Shooting at Them

So, how do Bots see other players? Well, there are a few functions and attributes that would appear to affect this part of the Bot's behaviour. In my experience none of them seem to work well in low visibility conditions. I've listed all the ones I can find below.

// From the Controller class
float FovAngle; // The Field of View from the player's (human or bot) point of view

// Enemy information
var Pawn   Enemy;         // A reference to the current Enemy of the bot
var Actor  Target;
var vector LastSeenPos;   // enemy position when I last saw enemy (auto updated if EnemyNotVisible() enabled)
var vector LastSeeingPos; // position where I last saw enemy (auto updated if EnemyNotVisible enabled)
var float  LastSeenTime;

// LineOfSightTo() returns true if any of several points of Other is visible (origin, top, bottom)
native(514) final function bool LineOfSightTo(actor Other);

// CanSee() similar to line of sight, but also takes into account Pawn's peripheral (how big is that?) vision
native(533) final function bool CanSee(Pawn Other); 

function bool WouldReactToSeeing(Pawn Seen)
event HearNoise( float Loudness, Actor NoiseMaker);
event SeePlayer( Pawn Seen );   // called when a player (bIsPlayer==true) pawn is seen
event SeeMonster( Pawn Seen );  // called when a non-player (bIsPlayer==false) pawn is seen
event EnemyNotVisible();

// From the ScriptedController class
function bool CheckIfNearPlayer(float Distance);

// From the Bot class
// Calls the CanAttack() function of the current weapon to see if Other is in range
function bool CanAttack(Actor Other);

event SeePlayer(Pawn SeenPlayer); // Called when a player has been seen
function SetPeripheralVision(); // Set's the peripheral vision of a Bot based on skill

// SetAlertness()
// Change creature's alertness, and appropriately modify attributes used by engine for
// determining seeing and hearing.  SeePlayer() is affected by PeripheralVision, and
// also by SightRadius and the target's visibility HearNoise() is affected by HearingThreshold
function SetAlertness(float NewAlertness);

// Attempts to determine if Bot has line of sight to Target deltatime from now.
function bool CheckFutureSight(float deltatime);

Irritatingly the control for the Bot's "sight" does not solely rest with the Controller. There are some attributes of the Pawn class that have an impact. The most obvious one of these is SightRadius, which is allegdly the Bot's maximum seeing distance. However, as I have proved conclusively the Bot's maximum seeing distance != the Bot's attacking distance.

ZxAnPhOrIaN: Is sight radius how far the bot can see weapons, powerups, triggers, etc?

Wormbo: It would be possible to reset the bot's target to None from an external actor if the distance to the enemy gets too big. The Tick function might be handy (and hacky ;)) here.

Refactor Me

The Unreal Engine Documentation Site

Wiki Community

Topic Categories

Image Uploads

Random Page

Recent Changes

Offline Wiki

Unreal Engine

Console Commands


Mapping Topics

Mapping Lessons

UnrealEd Interface


Scripting Topics

Scripting Lessons

Making Mods

Class Tree


Modeling Topics


Log In