Skip to main content

AI Engine update - Week ending 6/13

This week, I worked on simple agent rendering: Rendering an agent as a simple circle.

I also had to implement a Matrix, in which I had to implement different functions such as
·         Translate
·         Rotate
·         Scale
·         Transform
This really helped with my 3-D math skills as I finally understood how to create, store and operate the above properties on a game object.



After that, I worked on behaviors:

Seek

Given a target point, the agent will try to move towards that point.
First, we calculate the direction we need to move in by subtracting our position from the target position, and normalizing it:
Vec2 direction = Vec2::Normalize(targetPosition - mpAgent->GetPosition());

We then calculate the velocity required by multiplying that by the max possible velocity of the agent:
Vec2 desiredVelocity = direction * mpAgent->GetMaxSpeed();

Then the force required to get to that velocity would be the difference between that and the current velocity:
Vec2 force = desiredVelocity - mpAgent->GetVelocity();

Flee

Flee is similar to Seek, except that the agent will move away from the target point.
First, we calculate the direction we need to move in by subtracting target position from our position, and normalizing it:
Vec2 direction = Vec2::Normalize(mpAgent->GetPosition() - targetPosition);
We then calculate the velocity required by multiplying that by the max possible velocity of the agent:
Vec2 desiredVelocity = direction * mpAgent->GetMaxSpeed();

Then the force required to get to that velocity would be the difference between that and the current velocity:
Vec2 force = desiredVelocity - mpAgent->GetVelocity();


I will continue to implement more steering patterns.

Comments

Popular posts from this blog

AI Controller Update - Week ending 7/4

This week, I worked on Obstacle Avoidance and a slight hint of navigation. Obstacle Avoidance Though the concept is simple enough, the execution is quite tricky. The first part is to detect obstacles in your area. We define a lookahead, which can vary based on the object’s current velocity. I’ve left it at a fixed value for now. Then we raycast forwards to find the first obstacle in our path. Next, we compute the normal from the point of impact. We steer our object away from the point in the direction of the normal. The code looks like this: bool bHit = GetWorld ()-> LineTraceSingleByChannel ( Hit , StartLocation , EndLocation , Channel , QueryParams , ResponseParam );        if ( bHit )        {               FVector PenetratedAlongHit = Hit . ImpactPoint - EndLocation ;               FVector PenetratedAlongNormal = PenetratedAlongHit . ProjectOnToNormal ( Hit . ImpactNormal );               float PenetrationDepth = PenetratedAlongNormal . Size ();

AI Controller Update - Week ending 7/18

This was another landmark week. I was finally able to get navigation meshes working with all the behaviors I’d implemented so far. To see how important this is, let’s consider an example: The follower (the smaller model) needs to get to the target position (the other character in this case). However, there is an obstacle in between. The steering algorithm doesn’t know anything about obstacles. So it will continually push the follower towards the actor, and into the obstacle. With a navmesh, we can tell the steering algorithms to follow a sequence of points in order to reach the target actor. Now, calculating this every frame is very expensive. So what do we do here? First, we raycast to the target position to see whether the follower can reach there uninterrupted. If it can, fantastic. We just ask the follower to seek to the target position. If there isn’t a direct path, we request the navmesh to provide us with a set of points that we store, and then seek to one by one. Wh

AI Controller Update - Week Ending 6/27

Now, this was a week in which some really important work was done. Last week, I wrote about the roadblocks I was facing with writing my own game engine – guaranteeing a smooth game loop, constant frame rate, and float precision. While it is quite easy to build a functional game loop, it is harder to build one that does not break under stress. Somehow my windows framework wasn’t sending regular updates to my main loop, and I spent quite a while scratching my head trying to figure it out. However, time is precious and it was running out. I had to make a decision, and make it quick. I chose to jump into Unreal and port over all my code into Unreal 4.16. Jumping to Unreal I wanted to build a follower behavior, but I also wanted to build it right. So, I made sure to have a component-based architecture from the get-go, and made sure to have the steering behaviors as Actor Components, so that they could be attached to any actor and be reused. The Actor Steering component