top of page

Anomalous Behaviour of an AI Animal

 

Project Name: Anomalous Behaviour of an AI animal

 

Technology: Unity Engine, C# Scripting

 

Type: Solo Project

AI Behaviours Implemented: Seeking and Fleeing

 

Project Overview:

In this scenario, there are 5 animals (cubs of lion’s), they are denoted by silver circles on the screen. Their objective is to seek the food. Each animal has 2 bars on his head. The yellow bar is “hunger bar”. The green bar is “health bar”. Food is denoted by Apples. You ask, why lion’s cubs eat apples? Even I am trying to find the answer to that question.

 

 

AI Behaviour Description:

If hunger bar denotes value from 0 to 50, that means the animal is not hungry and the animal will rest in current position. If hunger bar value goes above 50 then the animal will seek for the food. Eating/touching food takes hunger bar back to 0. Green bar above animal’s head denotes health. If the health of the animal is < 20% and he sees an animal is nearby, he will flee to the nearest safe spot(caves). There are 4 caves around the map. Going back to cave sets cub’s health to 70 and then he will continue searching for food. If the animal finds another animal near food then the animal will seek the enemy, instead of food. Touching other animals deals random damage to both the animals. At 100% hunger, animals will start to lose health slowly.

Figure: Legend for the video above

Sensory System:​

Each animal holds 3 lists in his memory. One list for the enemies, one list for food and one list for safe spots. I have considered animals know each other’s location from start including food positions and location of caves. These lists hold X, Y world position of each entity. The lists are sorted every frame depending on the distance from the other animals.

The distance between 2 entities is calculated using the simple vector line distance formula. The animal will always store the distance between the closest enemy and the closest food in a separate variable in case it is needed in future. These variables are also updated every frame.

Figure: Distance formula used to calculate distance every frame​

Each animal entity holds 2 invisible circles around them. One is for “a minimum distance” another is for “a maximum distance”. The animal will ignore everything which is under minimum distance and which is outside maximum distance. These circles do not serve any important purpose currently but will surely help if I decide to extend the scope of the project. The maximum distance can ignore all the entities which are relatively far from the object which will release some free memory because then the animal will technically only see the world which is under maximum distance. The minimum distance can help to implement “cohesion” and “separation” behaviors.

Each food item holds an invisible circle around it too which will trigger 2 main subsumption functions.

 

Touching/Collision is handled by Unity’s collider system. Touching an apple is considered as eating it and touching other animal is considered as doing battle with it.

 

Subsumption Architecture:

The basic function done by an animal is to rest or stay in one place. By default, each animal starts with 100 health and 0 hunger. That means, he will be passive and will stay in one place until the hunger goes over 50. Hunger grows slowly over time throughout the game. Hunger going above 50 will force the animal to seek the food. However, hunger reaching 100 means the animal will lose his health slowly.

Figure: Subsumption Architecture

The base state of an animal is to “Target Food (Seek food)” which can be subsumed by 3 different functions. The food seeking behavior is forced once animal’s hunger bar value goes above 50. If the animal finds food and eats the food, then his hunger value goes to 0 & then the “Stay” function subsumes the food seeking function. Once “Stay” comes into play, the animal will just stay in the same place until his hunger goes high again.

 

Food seeking can also be subsumed by “Target Enemy (Seek Enemy)” function if the animal finds an enemy near the food area. Once the enemy is taken care of, then the “Target Food” function continues to run.

 

If the animal gets below 20% health then the “Flee” function subsumes everything, forcing animal to run to a safe spot. This “Flee” function has the top priority and cannot be subsumed by anything. Once the animal flees, he will go to the nearest safe spot and then he will continue searching for food again. The reason flee doesn’t make the animal move in opposite direction of the enemy, is just to match it with the background story. These animals are cubs, if they feel danger or threatened then they should be going back to their cave. If they just flee backward they might fall in another danger next second. Fleeing back to cave gives them some health which is good for them too.

 

All these decisions are followed by a “Path Plan” module which does the number crunching of vectors and finding path, which is then followed by the actual “Motor/Actuator” which physically moves our animal.

 

While our animal is doing all this complex decision-making stuff, there is one thing in this architecture which might not happen in real life but is happening here, the “Damager” module. According to my project implementation, the animals don’t have any animation and they will do “attack” function if they come in contact with each other. So, even if the animal is staying in one place he can do random damage to other animals if the other animals pass by him by touching his collider.

 

Steering Behaviors:

 

  • Seek:

Seeking is the most basic form of movement followed by animals in this world. Seeking is done by moving the animal object towards target position. After each frame of the game, the target puts his “Forward” vector towards target. Next, the animal object is moved in the direction of “Forward” vector by the speed amount given by a default value. This movement happens each frame resulting the animal to move to the destination.

The pointing “Forward” vector towards target happens every frame, thus this sometimes gives feeling of “Pursuit” instead of just seek. We can consider this “Seek” as “Pursuit without prediction”. This can be seen clearly once there is only one Apple left on the map. If there is only 1 Apple left, then the user is provided with an option, whether or not to control the apple. The user can move the Apple using W, A, S, D keys and all the animals will try to Seek the apple together.

 

  • Flee:

If the animal wants to flee, then his forward movement is subsumed. I have actually implemented flee in 2 different ways. The default way was to move animal in opposite direction of the threatening animal. However, this sometimes made animals not find any food at all because if there are more animals than food then the fleeing animal had no chance to regain health to 70% by eating food, as the animal was always fleeing from nearby animals around the food. Additionally, to match the background story, I made the cubs flee back to cave so they will gain health and then can come back again.

 

Multiple instances of animals:

While in the planning phase of the project, I had decided that I wanted to make more than one animals to interact with each other. Thus, I did not face any problems instantiating more than one animal objects in actual development. There are some tweaks need to be made through Unity editor every time a new animal needs to be spawned on the map, but apart from that, all animals can show proper behavior as expected.

 

Positive points of this architecture:

 

The basic functionality of the animal is to “Stay” and “Seek” the food if hungry. Thus, after every time the animal eats a food, he will stay in place. This “Stay” will ignore any nearby animals and even food. I think this is like a real-life like animal behavior. In real life, animals are less interested in aggressive stance if they are not hungry and will probably ignore extra food. This leaving extra food behind and not attacking if not hungry makes this AI more realistic, I guess.

 

Weaknesses and Known Issues:

 

I can see there are 2 main weaknesses of this architecture. One weakness is that there is no “wandering” behavior. This might feel a little bit odd, but I think “wandering” is very subjective behavior, unlike other steering behaviors. A wandering animal will wander much more differently than a wandering human. I understand, we can have a generalized wandering behavior but then we will also need some environmental setup where we can make sense out of wandering. I think if I had collision avoidance and obstacles then the implementation of wandering could have been much more interesting. Another issue is about collisions and animation. Currently, the animal will do damage to any animal who comes in contact with it. So, even if the animal is fleeing, he can do damage to other animals. Also, if the animals are far too close to each other then also they will do damage even though they are not in the aggressive mood. This can be solved by implementing code which allows animals to do damage only if they are facing the enemy and adding some animations.

bottom of page