UE4开发C++沙盒游戏教程笔记(九)(对应教程 28 ~ 30)
27. 手持物品与动作切换
让物品出现到角色手上
接下来实现切换手上物品为快捷栏内选中的物品。
给手上物品类添加一个通过 ID 返回物品 Actor 的工厂方法。
SlAiHandObject.h
public:
// 根据物品 ID 返回物品的工厂方法
// 这个 TSubclassOf<Type> 类型,其实就是 Type 这个类以及子类的所有类型。
// 所以这个方法可以返回任何 AActor 类或 AActor 的子类,一般在获取蓝图的时候使用。
static TSubclassOf<AActor> SpawnHandObject(int ObjectID);
SlAiHandObject.cpp
// 手持物品类的头文件
#include "SlAiHandNone.h"
#include "SlAiHandWood.h"
#include "SlAiHandStone.h"
#include "SlAiHandApple.h"
#include "SlAiHandMeat.h"
#include "SlAiHandAxe.h"
#include "SlAiHandHammer.h"
#include "SlAiHandSword.h"
TSubclassOf<AActor> ASlAiHandObject::SpawnHandObject(int ObjectID)
{
switch (ObjectID)
{
case 0:
return ASlAiHandNone::StaticClass();
case 1:
return ASlAiHandWood::StaticClass();
case 2:
return ASlAiHandStone::StaticClass();
case 3:
return ASlAiHandApple::StaticClass();
case 4:
return ASlAiHandMeat::StaticClass();
case 5:
return ASlAiHandAxe::StaticClass();
case 6:
return ASlAiHandHammer::StaticClass();
case 7:
return ASlAiHandSword::StaticClass();
}
return ASlAiHandNone::StaticClass();
}
随后让角色类应用这个工厂方法。
要考虑到的是,由于第一人称和第三人称的模型的手部位置不一样,所以要在切换视角的时候同步修改手持物品的位置,使其绑定到对应的模型的插槽上。
SlAiPlayerCharacter.h
public:
// 修改当前的手持物品
void ChangeHandObject(TSubclassOf<AActor> HandObjectClass);
SlAiPlayerCharacter.cpp
void ASlAiPlayerCharacter::BeginPlay()
{
Super::BeginPlay();
HandObject->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, FName("RHSocket"));
// 将之前注释掉的代码更改成如下
// 添加 Actor 到 HandObject
HandObject->SetChildActorClass(ASlAiHandObject::SpawnHandObject(0));
}
void ASlAiPlayerCharacter::ChangeView(EGameViewMode::Type NewGameView)
{
GameView = NewGameView;
switch (GameView)
{
case EGameViewMode::First:
FirstCamera->SetActive(true);
ThirdCamera->SetActive(false);
MeshFirst->SetOwnerNoSee(false);
GetMesh()->SetOwnerNoSee(true);
// 修改 HandObject 绑定的位置
HandObject->AttachToComponent(MeshFirst, FAttachmentTransformRules::SnapToTargetNotIncludingScale, FName("RHSocket"));
break;
case EGameViewMode::Third:
FirstCamera->SetActive(false);
ThirdCamera->SetActive(true);
MeshFirst->SetOwnerNoSee(true);
GetMesh()->SetOwnerNoSee(false);
// 修改 HandObject 绑定的位置
HandObject->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, FName("RHSocket"));
break;
}
}
void ASlAiPlayerCharacter::ChangeHandObject(TSubclassOf<AActor> HandObjectClass) // 此处有些多余代码,下一集会删,这里我就先删掉了
{
// 设置物品到 HandObject
HandObject->SetChildActorClass(HandObjectClass);
}
玩家控制器负责滚轮滑动来切换选中的快捷栏,所以它来负责调用角色类里面的切换手持物品的方法。
SlAiPlayerController.h
{
public:
// 对 Character 的手持物品进行更改,这个函数在 PlayerState 内会调用
void ChangeHandObject();
}
SlAiPlayerController.cpp
// 引入头文件
#include "SlAiHandObject.h"
void ASlAiPlayerController::ChangeHandObject()
{
// 生成手持物品
SPCharacter->ChangeHandObject(ASlAiHandObject::SpawnHandObject(SPState->GetCurrentHandObjectIndex()));
}
void ASlAiPlayerController::ScrollUpEvent()
{
if (!SPCharacter->IsAllowSwitch) return;
if (IsLeftButtonDown || IsRightButtonDown) return;
SPState->ChooseShortcut(true);
// 更改 Character 的手持物品
ChangeHandObject();
}
void ASlAiPlayerController::ScrollDownEvent()
{
if (!SPCharacter->IsAllowSwitch) return;
if (IsLeftButtonDown || IsRightButtonDown) return;
SPState->ChooseShortcut(false);
// 更改 Character 的手持物品
ChangeHandObject();
}
运行后可看到,此时物品已经可以正确地随着快捷栏格子的切换而出现在角色手中了。并且切换视角后也能看到物品能正确地被握持。
根据手上物品切换相应动作
在玩家状态类里添加一个方法,用于获取玩家手中物品的类型
SlAiPlayerState.h
public:
// 获取当前手持物品的物品类型
EObjectType::Type GetCurrentObjectType();
SlAiPlayerState.cpp
EObjectType::Type ASlAiPlayerState::GetCurrentObjectType()
{
TSharedPtr<ObjectAttribute> ObjectAttr;
ObjectAttr = *SlAiDataHandle::Get()->ObjectAttrMap.Find(GetCurrentHandObjectIndex());
return ObjectAttr->ObjectType;
}
玩家控制类根据手持物品的类型切换上半身预动作。
SlAiPlayerController.h
{
private:
// 修改预动作
void ChangePreUpperType(EUpperBody::Type RightType);
}
SlAiPlayerController.cpp
void ASlAiPlayerController::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
// 临时代码
ChangePreUpperType(EUpperBody::None);
}
void ASlAiPlayerController::ChangePreUpperType(EUpperBody::Type RightType = EUpperBody::None)
{
// 根据当前手持物品的类型来修改预动作
switch (SPState->GetCurrentObjectType())
{
case EObjectType

该博客围绕UE4游戏开发展开,介绍了手持物品与动作切换,包括让物品出现在角色手上、根据物品切换动作及碰撞检测;还涉及动作通知与读取资源Json,完善碰撞检测开启时机并加载资源数据;最后完善资源类、添加可拾取物品及显示物体介绍框界面。
9509

被折叠的 条评论
为什么被折叠?



