前言:
笔者目前在校本科大三,目标方向是人工智能、计算机视觉。上一个OpenCV学习笔记专栏已完结,在学习完OpenCV后,我继续学习C++,并用纯C++做UE4项目的方式继续提升自己的水平。
梁迪老师的水平非常高,他的课程本来也无需笔记:课程本身即为最好的笔记。但由于我天赋有限,还是边看边记,以防遗忘——知识点太多,步骤太繁杂了。在学习过程中,我也偶有思考,思索为什么某个方法老师要这样做。所以,一是为了记录,二是为了分享,才有了这个专栏。
内容方面,由于我在开启这个专栏时,此项目已经做完很多了。所以,前期的一些大篇幅叙述的知识,可能在后期应用中一带而过。以及,前期的一些知识,后期会重新剖析,并加上我的个人理解。
另外,若有学术交流/学业交流意愿,可以邮件联系1246210283@qq.com,希望一齐进步。
本篇学习内容:
49.敌人模型与动作
50.敌人血条和视野
49.敌人模型与动作
创建EnemyAnim(AnimInstance)、EnemyCharacter、EnemyController(AI Controller),EnemyTool,EnemyShield(继承自EnemyTool)、EnemyWeapon(继承自EnemyTool)、Enemy_Animation(蓝图动画)
(1)在EnemyCharacter中设置AI控制器、设置碰撞体属性文件、添加模型、添加动画蓝图、实例化左右手插槽
(2)实现EnemyTool,实现方法和HandObject类似
(3)实现EnemyShield、EnemyWeapon
(4)在EnemyCharacter的BeginPlay下绑定左右手插槽
//绑定插槽
WeaponSocket->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, FName("RHSoaket"));//贴在目标上但是不使用它的大小变换
ShieldSocket->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, FName("LHSoaket"));
//给插槽添加物品
WeaponSocket->SetChildActorClass(ASlAiEnemyTool::SpawnEnemyWeapon());
ShieldSocket->SetChildActorClass(ASlAiEnemyTool::SpawnEnemyShield());
(5)写EnemyAnim
注:在C++里修改IdleType,就可以显示出敌人不同的静止动作
50.敌人血条和视野
(1)创建HPWidget文件,组件为SProgressBar,保存一个颜色指针用于动态修改血条颜色(血多为绿,血少为红)
(2)准备工作:EnemyController中准备构造函数、BeginPlay中绑定玩家、敌人角色指针
SPCharacter = Cast<ASlAiPlayerCharacter>(UGameplayStatics::GetPlayerCharacter(GWorld, 0));
if (!SECharacter) SECharacter = Cast<ASlAiEnemyCharacter>(GetPawn());
(3)EnemyCharacter中实例化敌人血条和感知
//实例化血条
HPBar = CreateDefaultSubobject<UWidgetComponent>(TEXT("HPBar")); //WidgetComponent.h, SSlAiEnemyHPWidget.h
HPBar->AttachTo(RootComponent);
//实例化敌人感知组件
EnemySense = CreateDefaultSubobject<UPawnSensingComponent>(TEXT("EnemySense"));
设置在BeginPlay下:
//设置血条Widget
SAssignNew(HPBarWidget, SSlAiEnemyHPWidget);
HPBar->SetSlateWidget(HPBarWidget);
HPBar->SetRelativeLocation(FVector(0.f, 0.f, 100.f));
HPBar->SetDrawSize(FVector2D(100.f, 10.f));
//初始化血量为100
HP = 100.f;
HPBarWidget->ChangeHP(HP / 200.f);
//敌人感知参数设置
EnemySense->HearingThreshold = 0.f;
EnemySense->LOSHearingThreshold = 0.f; //UE4中很强大的AI寻路组件
EnemySense->SightRadius = 1000.f; //视野半径
EnemySense->SetPeripheralVisionAngle(55.f); //视野角度
EnemySense->bHearNoises = false;
//绑定看到玩家的方法
FScriptDelegate OnSeePlayerDele;
OnSeePlayerDele.BindUFunction(this, "OnSeePlayer"); // 反射,通过函数名字来获取函数指针
EnemySense->OnSeePawn.Add(OnSeePlayerDele);
(4)设置血条朝向玩家。函数由EnemyController每帧调用。
void ASlAiEnemyCharacter::UpdateHPBarRotation(FVector SPLocation)
{
FVector StartPos(GetActorLocation().X, GetActorLocation().Y, 0);
FVector TargetPos(SPLocation.X, SPLocation.Y, 0.f);
HPBar->SetWorldRotation(FRotationMatrix::MakeFromX(TargetPos - StartPos).Rotator());
}
注:
Pitch:俯仰(上下看)— Y轴
Yaw:偏航(左右看) — Z轴
Roll:翻转(旋转)—X轴