• 19uec++多人游戏【基础AI导航】


    首先把这一期的资源导入一下

    创建一个球体类,继承于pawn类

     为其添加静态组件

    1. UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
    2. class UStaticMeshComponent * MeshComponent;
    3. ==================================================================
    4. #include "Components/StaticMeshComponent.h"
    5. MeshComponent = CreateDefaultSubobject(TEXT("MeshComponent"));
    6. RootComponent = MeshComponent;

    编译,为其创建蓝图类

    为其组件设为一个球体

     

    拖到场景中,发现太大了

     

    我们为其创建一个小球网格体模型

    首先创建一个文件夹

     

     我们把这个小球网格体复制到我们这个文件夹下面

    重命名一下这个网格体

     

    进入这个网格体,修改一下比例

     

     在类中换上这个网格体

    shift+end让其紧贴地面

     

    然后创建材质文件

     

    先将材质设为白色

     在网格体中赋予材质

    把导航体拖入场景中

     然后我们拉大体积,让其覆盖整个地面

    然后让其嵌入到地板底下

     

     按一下p,就可以显示导航的范围

    我们可以看到,球体本身也会影响导航

     

    小球mesh组件里面,去掉这个勾

     

     

    我们为这个小球,写蓝图

     然后为我们的小球随便添加一个移动组件

    编译,测试,小球开局真的动了 

     现在我们将移动逻辑写的更复杂一点

    将移动速度变小,发现小球一直在我们屁股后面追

     

    ====================================

    我们继续提高逻辑,让其自动添加路径

    首先自定义事件

     

     测试,已经画出了路径点

     在c++文件中加上这个

    在小球头文件中,添加三个变量

    1. //移动速度
    2. UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
    3. float MovementForce;
    4. //是否让移动速度改变
    5. UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
    6. bool bUseVelocityChange;
    7. //移动到目标的阈值
    8. UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
    9. float RequiredDistanceToTarget;

     在构造函数中初始化这三个变量,并将mesh组件的模拟物理激活

    1. AASTrackerBot::AASTrackerBot()
    2. {
    3. // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
    4. PrimaryActorTick.bCanEverTick = true;
    5. MeshComponent = CreateDefaultSubobject(TEXT("MeshComponent"));
    6. MeshComponent->SetSimulatePhysics(true);
    7. RootComponent = MeshComponent;
    8. MovementForce = 1000;
    9. bUseVelocityChange = false;
    10. RequiredDistanceToTarget = 100;
    11. }

     在小球的头文件中,添加寻找路径点的函数,和路径点变量

    FVector GetNextPathPoint();
    1. //路径点
    2. FVector NextPathPoint;
    1. #include "Components/StaticMeshComponent.h"
    2. #include "GameFramework/Character.h"
    3. #include"Kismet/GamePlayStatics.h"
    4. #include "NavigationSystem.h"
    5. #include "NavigationPath.h"
    6. #include "DrawDebugHelpers.h"

     定义这个函数

    1. FVector AASTrackerBot::GetNextPathPoint()
    2. {
    3. //得到0号玩家
    4. ACharacter *playerPawn = UGameplayStatics::GetPlayerCharacter(this, 0);
    5. //找到通往玩家的路径
    6. UNavigationPath *NavPath = UNavigationSystemV1::FindPathToActorSynchronously(this, GetActorLocation(), playerPawn);
    7. if (NavPath->PathPoints.Num() > 1)
    8. {
    9. //返回第二个点
    10. return NavPath->PathPoints[1];
    11. }
    12. else
    13. {
    14. return GetActorLocation();
    15. }
    16. }

     在游戏开始函数中,调用这个函数

    1. void AASTrackerBot::BeginPlay()
    2. {
    3. Super::BeginPlay();
    4. NextPathPoint = GetNextPathPoint();
    5. }

     在每帧函数里,不断得去移动

    1. void AASTrackerBot::Tick(float DeltaTime)
    2. {
    3. Super::Tick(DeltaTime);
    4. //得到小球自身与下一个点的距离
    5. float DistanceToTarget = (NextPathPoint - GetActorLocation()).Size();
    6. //如果大于阈值,就继续滚
    7. if (DistanceToTarget > RequiredDistanceToTarget)
    8. {
    9. //小球的移动方向
    10. FVector ForceDirection = NextPathPoint - GetActorLocation();
    11. ForceDirection.Normalize();
    12. //小球的推力
    13. ForceDirection *= MovementForce;
    14. MeshComponent->ComponentVelocity.Size();
    15. MeshComponent->AddImpulse(ForceDirection, NAME_None, bUseVelocityChange);
    16. DrawDebugDirectionalArrow(GetWorld(), GetActorLocation(), GetActorLocation() + ForceDirection, 32, FColor::Red, false, 0.0f, 0, 1.0f);
    17. }
    18. //如果到达了路径点,就生成下一个点,继续移动
    19. else
    20. {
    21. NextPathPoint = GetNextPathPoint();
    22. DrawDebugString(GetWorld(), GetActorLocation(), "Target Reached!");
    23. }
    24. //在下一个目标点画一个球
    25. DrawDebugSphere(GetWorld(), NextPathPoint, 20, 12, FColor::Yellow, false, 0.0f, 0, 1.0f);
    26. }

    编译,然后在小球的mesh组件里面,勾上模拟物理

    测试成功

     

     

  • 相关阅读:
    基于51单片机汽车智能灯光控制系统设计
    前端飞机大战小游戏
    【LeetCode滑动窗口专题#2】无重复字符的最长子串
    [计算机网络] 选择判断查缺补漏
    阅读 | 001《人工智能导论》(二)知识获取篇
    Kubernetes:Ingress总结(一)
    Redis:报错Creating Server TCP listening socket *:6379: bind: No error
    免费开源 | 基于SSM的校园订餐系统
    【jQuery】jQuery中如何发送ajax请求以及解决跨域问题_10
    Flash、eeprom、rom、ram
  • 原文地址:https://blog.csdn.net/zhang2362167998/article/details/128076283