Hot to make dynamic AI jumping

Hello. I created a level with random platforms generation with C++. Logic of platform generation: Shoot-n-Fall/SNF_PlatformBuilder.cpp at master · Norrowind/Shoot-n-Fall · GitHub

Now i need to make AI character navigate, using jumping on, or sliding off platforms to certain point on the level. Unfortunately i cant find solution for my situation. Every tutorial i found, use navlink proxy but i need to implement system with dynamic choosing what to do, depending on target point location(jump up or slide down) and i cant attach navlinks properly during “runtime”(platforms spawns in begin play)

Video with random platform generation - SNF_BasicShooting_RandomPlatformBuilder.webm - Google Drive

Anyone have an idea how to implement such “system”? Thanks

I think you could do this: Have an overlap capsule around your AI. The radius should be the maximum vertical distance a character can ever jump, it’s height should end at maximum jump height, and then extend downwards to the end of the level/“screen”. (Alternatively you can use a sphere and ignore platforms the character can simply fall on that are outside of this sphere.)

This should give you all the platforms your AI can theoretically land on, then you can get the object bounds, and have the AI select one platform to jump on. (Maybe make some sphere trace checks for blocking volumes.) Then you still have to make the AI jump onto the platform. Let me know if this helps.

Thank you for an answer. Idea is very interesting, but i cant figure out, what you mean by “get the object bounds”. Also i dont understand, how to determine jump/or not and just continue to move forward.

Sorry, the function is GetActorBounds. Overlap only gives you the actor itself, so you need to know the size of the actor, so you can land anywhere on it, not just on the pivot. You can get the Actor you are standing on and determine how close to that platforms edge the AI is. If it is closer than x units, and there is a platform it can jump to, it can jump there.

Sorry for silly question but i dont understand how to calculate landing with GetActorBounds, never use this func before

Well, the box extend gives you a range for the coordinates. Going with something following the logic of this here pseudo code:

MustJump() {
for each OverlappingPlatform { 
if (PlatformIsItCloserToTarget)
JumpOrSlideTo(PlatformOrigin +- PlatformBounds); //point on platform closest to character
break;
}}

Note: Whether the character has to jump depends on how far it has to travel in air. The following code might help.

FVector GravitationalForce; //z is presumed to be negative.
float CharacterSpeed;
float HorizontalDistance = FVector::Dist(TargetPosition, StartPosition); 

float TravelTime = HorizontalDistance/CharacterSpeed;
FVector FalloffVector = GravitationalForce / 2 * pow(TravelTime,2);

if ((StartPosition - FalloffVector).Z <= TargetPosition.Z) HasToJump = true;

EDIT: Noticed a mistake in my code. “float HorizontalDistance = FVector::Dist(TargetPosition, StartPosition);” is not the horizontal distance. You should use X and Y only. (you can multiply each vector with [1,1,0] for example)

Thanks! It works for jumping, but now i cant figure out how my AI should calculate slide possibility (linear algebra is not my strong side) and how to make AI find path to character when it has no valid platforms to move on.

Noticed a mistake in my code. “float HorizontalDistance = FVector::Dist(TargetPosition, StartPosition);” is not the horizontal distance. You should use X and Y only. (you can multiply each vector with [1,1,0] for example)

I think you will have to calculate which platforms the AI can jump to, from each platform, when the game starts, giving you a network of platforms, and allowing you to calculate the shortest path to the player.

The sliding should be something like this:

float Gravitation; //is positive
if (TargetPosition < StartPosition) {
float VerticalDistance = StartPosition.Z - TargetPosition.Z;
float ZTravelTime = sqrt(VerticalDistance/Gravitation/2);

if(ZTravelTime * CharacterSpeed < HorizontalDistance) CanSlide = false;