Lybra
10-31-2011, 03:15 PM
Hello everyone,
As a Computer Science/Software Engineering student - interested into Game Development - I decided to dedicate my bachelor thesis to the UDK. To be exact, I am trying to create a Point-and-Click Adventure type of game.
That means:
- indirect Pawn controls via Point-and-Click
- a rather static camera system
- rather small, narrow areas
So far, I have been successful in developing some of the core features...till now. For the actual pathfinding, I decided to use Navmeshes over Waypoints (for obvious reasons I guess). After following a couple of tutorials and the official documentation, I managed to create a basic, yet underwhelming, result:
http://www.youtube.com/watch?v=lxU-iiwLybI
As you can see, there are a couple of problems in it's actual state:
- pawn keeps bumping into obstacles
- pawn is taking detours from time to time
- infinite loops causing crashes
- ...
Navmesh Setup: http://85.25.34.39/navmesh.jpg
The actual code
PlayerController:
state LMBPressedState
{
function PlayerMove(float DeltaTime)
{
Pawn.FaceRotation(RInterpTo(Pawn.Rotation, Rotator(NextMoveLoc-Pawn.Location), DeltaTime, 20000, true),DeltaTime);
super.PlayerMove(DeltaTime);
}
function bool FindNavMeshPath(Vector Loc)
{
// Clear cache and constraints (ignore recycling for the moment)
NavigationHandle.PathConstraintList = none;
NavigationHandle.PathGoalList = none;
class'NavMeshPath_AlongLine'.static.AlongLine(Navi gationHandle, Loc);
class'NavMeshGoal_At'.static.AtLocation(Navigation Handle, Loc);
if (!NavigationHandle.FindPath())
{
return false;
}
return true;
}
Begin:
NavigationHandle.SetFinalDestination(HitLoc);
//Desired point directly reachable?
if(!NavigationHandle.PointReachable(HitLoc))
{
//if not, look for path
if(FindNavMeshPath(HitLoc))
{
FlushPersistentDebugLines();
NavigationHandle.DrawPathCache(,TRUE);
bFoundPath = true;
}
//no path found
else
{
//look for reachable point nearby
class'NavigationHandle'.static.GetValidPositionsFo rBox(HitLoc,Pawn.GetCollisionRadius()*6,Pawn.GetCo llisionExtent(),false,ValidPositions,10);
if(ValidPositions.Length > 0)
{
// no path found yet
bFoundPath = false;
// first location as distance reference
PathDistance = NavigationHandle.CalculatePathDistance(ValidPositi ons[0]);
NextMoveLoc = ValidPositions[0];
foreach ValidPositions(ValidLoc)
{
NavigationHandle.SetFinalDestination(ValidLoc);
if(FindNavMeshPath(ValidLoc))
{
FlushPersistentDebugLines();
NavigationHandle.DrawPathCache(,TRUE);
bFoundPath = true;
if(NavigationHandle.CalculatePathDistance(ValidLoc ) < PathDistance)
{
PathDistance = NavigationHandle.CalculatePathDistance(ValidLoc);
NextMoveLoc = ValidLoc;
}
}
}
NavigationHandle.SetFinalDestination(NextMoveLoc);
//clear the array
ValidPositions.Remove(0,ValidPositions.Length);
}
//found no nearby points
else
{
bFoundPath = false;
}
}
}
else
{
//point reachable, move there directly
MoveTo(HitLoc);
bFoundPath = false;
}
//pathfinding loop
while( Pawn != None && bFoundPath)
{
if( NavigationHandle.GetNextMoveLocation(NextMoveLoc, Pawn.GetCollisionRadius()) )
{
//prevent infinite loop
if(NextMoveLoc == PreviousLoc)
{
break;
}
if (!NavigationHandle.SuggestMovePreparation(NextMove Loc,self))
{
DrawDebugLine(Pawn.Location,NextMoveLoc,255,0,0,tr ue);
MoveTo(NextMoveLoc);
PreviousLoc = NextMoveLoc;
}
}
}
FlushPersistentDebugLines();
End:
GotoState('PlayerWaiting');
}
Scout
class SEGameScout extends UDKScout;
DefaultProperties
{
Begin Object NAME=CollisionCylinder
CollisionRadius=40
End Object
PathSizes.Empty
PathSizes(0)=(Desc=Human,Radius=20,Height=54)
PathSizes(1)=(Desc=Common,Radius=30,Height=96)
PathSizes(2)=(Desc=Max,Radius=50,Height=144)
TestJumpZ=0
MaxStepHeight=10
MaxJumpHeight=0
WalkableFloorZ=0.25
SizePersonFindName=Human
NavMeshGen_StartingHeightOffset=8.0
NavMeshGen_StepSize=20.0
NavMeshGen_EntityHalfHeight=24
NavMeshGen_MaxStepHeight=10.0
}
I already wasted a couple of days in a really tight schedule. To be honest, I didn't expect UDK to struggle with fundamental stuff like this, hopefully I am the one doing something wrong, something that can be fixed :)
Any help is greatly appreciated!
Thanks!
As a Computer Science/Software Engineering student - interested into Game Development - I decided to dedicate my bachelor thesis to the UDK. To be exact, I am trying to create a Point-and-Click Adventure type of game.
That means:
- indirect Pawn controls via Point-and-Click
- a rather static camera system
- rather small, narrow areas
So far, I have been successful in developing some of the core features...till now. For the actual pathfinding, I decided to use Navmeshes over Waypoints (for obvious reasons I guess). After following a couple of tutorials and the official documentation, I managed to create a basic, yet underwhelming, result:
http://www.youtube.com/watch?v=lxU-iiwLybI
As you can see, there are a couple of problems in it's actual state:
- pawn keeps bumping into obstacles
- pawn is taking detours from time to time
- infinite loops causing crashes
- ...
Navmesh Setup: http://85.25.34.39/navmesh.jpg
The actual code
PlayerController:
state LMBPressedState
{
function PlayerMove(float DeltaTime)
{
Pawn.FaceRotation(RInterpTo(Pawn.Rotation, Rotator(NextMoveLoc-Pawn.Location), DeltaTime, 20000, true),DeltaTime);
super.PlayerMove(DeltaTime);
}
function bool FindNavMeshPath(Vector Loc)
{
// Clear cache and constraints (ignore recycling for the moment)
NavigationHandle.PathConstraintList = none;
NavigationHandle.PathGoalList = none;
class'NavMeshPath_AlongLine'.static.AlongLine(Navi gationHandle, Loc);
class'NavMeshGoal_At'.static.AtLocation(Navigation Handle, Loc);
if (!NavigationHandle.FindPath())
{
return false;
}
return true;
}
Begin:
NavigationHandle.SetFinalDestination(HitLoc);
//Desired point directly reachable?
if(!NavigationHandle.PointReachable(HitLoc))
{
//if not, look for path
if(FindNavMeshPath(HitLoc))
{
FlushPersistentDebugLines();
NavigationHandle.DrawPathCache(,TRUE);
bFoundPath = true;
}
//no path found
else
{
//look for reachable point nearby
class'NavigationHandle'.static.GetValidPositionsFo rBox(HitLoc,Pawn.GetCollisionRadius()*6,Pawn.GetCo llisionExtent(),false,ValidPositions,10);
if(ValidPositions.Length > 0)
{
// no path found yet
bFoundPath = false;
// first location as distance reference
PathDistance = NavigationHandle.CalculatePathDistance(ValidPositi ons[0]);
NextMoveLoc = ValidPositions[0];
foreach ValidPositions(ValidLoc)
{
NavigationHandle.SetFinalDestination(ValidLoc);
if(FindNavMeshPath(ValidLoc))
{
FlushPersistentDebugLines();
NavigationHandle.DrawPathCache(,TRUE);
bFoundPath = true;
if(NavigationHandle.CalculatePathDistance(ValidLoc ) < PathDistance)
{
PathDistance = NavigationHandle.CalculatePathDistance(ValidLoc);
NextMoveLoc = ValidLoc;
}
}
}
NavigationHandle.SetFinalDestination(NextMoveLoc);
//clear the array
ValidPositions.Remove(0,ValidPositions.Length);
}
//found no nearby points
else
{
bFoundPath = false;
}
}
}
else
{
//point reachable, move there directly
MoveTo(HitLoc);
bFoundPath = false;
}
//pathfinding loop
while( Pawn != None && bFoundPath)
{
if( NavigationHandle.GetNextMoveLocation(NextMoveLoc, Pawn.GetCollisionRadius()) )
{
//prevent infinite loop
if(NextMoveLoc == PreviousLoc)
{
break;
}
if (!NavigationHandle.SuggestMovePreparation(NextMove Loc,self))
{
DrawDebugLine(Pawn.Location,NextMoveLoc,255,0,0,tr ue);
MoveTo(NextMoveLoc);
PreviousLoc = NextMoveLoc;
}
}
}
FlushPersistentDebugLines();
End:
GotoState('PlayerWaiting');
}
Scout
class SEGameScout extends UDKScout;
DefaultProperties
{
Begin Object NAME=CollisionCylinder
CollisionRadius=40
End Object
PathSizes.Empty
PathSizes(0)=(Desc=Human,Radius=20,Height=54)
PathSizes(1)=(Desc=Common,Radius=30,Height=96)
PathSizes(2)=(Desc=Max,Radius=50,Height=144)
TestJumpZ=0
MaxStepHeight=10
MaxJumpHeight=0
WalkableFloorZ=0.25
SizePersonFindName=Human
NavMeshGen_StartingHeightOffset=8.0
NavMeshGen_StepSize=20.0
NavMeshGen_EntityHalfHeight=24
NavMeshGen_MaxStepHeight=10.0
}
I already wasted a couple of days in a really tight schedule. To be honest, I didn't expect UDK to struggle with fundamental stuff like this, hopefully I am the one doing something wrong, something that can be fixed :)
Any help is greatly appreciated!
Thanks!