[unreal] 寻路:随机漫游的实现

reference: https://forums.unrealengine.com/community/general-discussion/1377-ue4-pathfinding-basic-ai?1270-UE4-Pathfinding-basic-AI=

by : UE developer,IceWraith

        随机漫游的效果可以有很多种实现方法,这取决于你想要使用哪种系统。

        最好的(也是最复杂的)方法是准备行为树,不过你需要在编辑器首选项(菜单:编辑->编辑器偏好设置->试验性功能)中开启它们。你可以依照上面提到的教程,或者也可以按照以下步骤执行:

        (1) 创建新的黑板资源(右键人工智能->黑板),用来存储目标点:只包含的单一的键,键的类型设置为BlackbordKeyType_Vector。

        (2) 创建新的行为树任务,用以挑选随机的位置,这既可以在蓝图中完成,也可以在C++中完成。

        蓝图:新建一个蓝图(父类为BTTask_BlueprintBase), 重点在于:添加一个BlackboardKeySelector类型的变量,并且设置它的属性为public(点击变量旁边的眼睛,设置=public)


        C++:新建一个继承自UBTTask_BlackboardBase的类,实现你自己的ExecuteTask()函数。

        代码:

EBTNodeResult::Type UBTTask_FindLocation::ExecuteTask(class UBehaviorTreeComponent* OwnerComp, uint8* NodeMemory)
{
	UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(OwnerComp);
	AAIController* MyAI = Cast<AAIController>(OwnerComp->GetOwner());
	if (NavSys && MyAI && MyAI->GetPawn())
	{
		const float SearchRadius = 1000.0f;
		FNavLocation RandomPt;
		
		const bool bFound = NavSys->GetRandomPointInRadius(MyAI->GetPawn()->GetActorLocation(), SearchRadius, RandomPt);
		if (bFound)
		{
			OwnerComp->GetBlackboardComponent()->SetValueAsVector(GetSelectedBlackboardKey(), RandomPt.Location);
			return EBTNodeResult::Succeeded;
		}	
	}

	return EBTNodeResult::Failed;
}

        (3) 创建新的行为树,在root属性中设置你的黑板。你可以从包含两个节点的序列组合开始:FindSpot(在步骤2中做的)和MoveTo,它们共同访问黑板中的同一个键。


        (4) 新建一个AI,并在里面运行刚才的行为树。最简单的方法是在关卡蓝图中调用SpawnAI


        正如我所说的,这是最复杂的方法,但是为你之后的修改提供了一个最好的出发点。

        下面是蓝图中比较简单的设置:

        1. 调用AIController中的MoveToLocation和MoveToActor方法。

        2. 绑定AIController中的ReceiveMoveCompleted事件,来检测是否达到了目的地。

        3. 调用GetRandomPoint / GetRandomPointInRadius函数(NavData和FilterClass都设为空),在navmesh中选择随机目标点。


        对于蓝图还有更为简单的设置:

        1. 调用AI MoveTo函数,它会为你执行结束时的事件。

        2. 调用GetRandomPoint / GetRandomPointInRadius函数(NavData和FilterClass都设为空),在navmesh中选择随机目标点。


       最后,是C++的版本:

        1.调用AIController中的MoveToLocation / MoveToActor函数。

        2. 重写AIController的OnMoveCompleted来检测下一个目标点。

        3. 访问导航系统中随机一个位置的方法如上所示。


        这时候,让我们讨论一下怎样修改寻路的影响因子。你可以定义包含不同行程或者耗费的导航区域,使用C++或者是蓝图。新建继承自NavArea的蓝图/c++类。我强烈建议将遍历耗费(初始耗费属性)设置为大于等于1。区域通常由NavModifierVolume或者静态网格构造的动态障碍物来完成的(为了了解更多的细节,可以查看静态网格的NavCollision属性)

        此外,你可能还需要检查额外的两个actor: ANavLinkProxy(例如跳转链接)和ANavigationTestingActor (寻路调试工具,包括单步显示)

        希望能够给你带来帮助!

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页