详细解析如何在LyraStarterGame项目中创建一个完整的GameFeature插件,包括角色移动的实现机制。
一、创建GameFeature插件基础结构
1. 创建GameFeature插件模板
# 在引擎或项目中使用插件模板
# 或手动创建以下结构:
YourPlugin/
├── Source/
│ ├── YourPlugin/
│ │ ├── YourPlugin.Build.cs
│ │ ├── YourPlugin.h
│ │ └── YourPlugin.cpp
│ └── YourPluginEditor/
├── Config/
├── Content/
└── YourPlugin.uplugin
2. GameFeatureData配置
// Config/GameFeatureData.json
{
"GameFeatureName": "YourFeature",
"GameFeatureActions": [
{
"ActionType": "WorldAction",
"WorldData": {
"MapsToLoad": [],
"GameModes": [],
"Experiences": []
}
}
]
}
二、创建角色和Experience定义
1. 创建自定义Experience
// YourExperience.h
UCLASS()
class UYourGameExperience : public ULyraExperienceDefinition
{
GENERATED_BODY()
public:
UYourGameExperience(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
protected:
virtual void OnExperienceLoaded(const ULyraExperienceDefinition* Experience) override;
// 添加你的角色pawn类
UPROPERTY(EditDefaultsOnly, Category = "Gameplay")
TSoftClassPtr<APawn> DefaultPawnClass;
// 添加输入配置
UPROPERTY(EditDefaultsOnly, Category = "Input")
TObjectPtr<ULyraInputConfig> InputConfig;
};
2. 配置PawnData
// 在Content中创建Blueprints/Pawns/BP_YourCharacter
// 继承自ALyraCharacter
// 创建PawnData资产:
// 1. 右键创建 -> Lyra -> Pawn Data
// 2. 配置:
// - Input Config: 你的输入配置
// - Ability Sets: 能力集
// - Camera Mode: LyraCameraMode
// - Character Class: BP_YourCharacter
三、Lyra角色移动实现机制
1. 移动组件架构
Lyra使用分层移动组件:
// 核心移动组件:ULyraCharacterMovementComponent
UCLASS()
class ULyraCharacterMovementComponent : public UCharacterMovementComponent
{
GENERATED_BODY()
// 基础移动实现
virtual void UpdateBasedMovement(float DeltaSeconds) override;
virtual void PhysWalking(float deltaTime, int32 Iterations) override;
// Lyra特定功能
void HandleMoverGroundMovement();
void ApplyAccumulatedForces();
// 网络同步
virtual void PerformMovement(float DeltaTime) override;
};
2. 输入处理流程
// 1. 输入绑定(LyraInputComponent)
ULyraInputComponent::BindNativeActions(
const ULyraInputConfig* InputConfig,
const ULyraInputConfig::FInputActionCallback& PressedFunc,
const ULyraInputConfig::FInputActionCallback& ReleasedFunc);
// 2. 输入转换为移动(LyraHeroComponent)
void ULyraHeroComponent::Input_Move(const FInputActionValue& InputActionValue)
{
APawn* Pawn = GetPawn<APawn>();
if (Pawn)
{
const FVector2D Value = InputActionValue.Get<FVector2D>();
const FRotator MovementRotation(0.0f, Pawn->GetControlRotation().Yaw, 0.0f);
if (Value.X != 0.0f)
{
const FVector MovementDirection = MovementRotation.RotateVector(FVector::RightVector);
Pawn->AddMovementInput(MovementDirection, Value.X);
}
if (Value.Y != 0.0f)
{
const FVector MovementDirection = MovementRotation.RotateVector(FVector::ForwardVector);
Pawn->AddMovementInput(MovementDirection, Value.Y);
}
}
}
3. Gameplay Ability System集成
// 移动能力(LyraGameplayAbility_Jump)
ULYRA_API ULyraGameplayAbility_Jump : public ULyraGameplayAbility
{
void ActivateAbility(
const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
const FGameplayEventData* TriggerEventData) override
{
// 触发跳跃
ACharacter* Character = CastChecked<ACharacter>(ActorInfo->AvatarActor.Get());
Character->Jump();
}
};
4. 网络复制和预测
// LyraCharacterMovementComponent网络同步
void ULyraCharacterMovementComponent::ServerMove_Implementation(
float TimeStamp,
FVector_NetQuantize10 InAccel,
FVector_NetQuantize100 ClientLoc,
uint8 CompressedMoveFlags,
uint8 ClientRoll,
uint32 View,
UPrimitiveComponent* ClientMovementBase,
FName ClientBaseBoneName,
uint8 ClientMovementMode)
{
// 服务器端移动处理
// ...
}
四、完整GameFeature配置示例
1. GameFeature Action配置
// 自定义GameFeatureAction
UCLASS()
class UYourGameFeatureAction_AddInputConfig : public UGameFeatureAction
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, Category="Input")
TSoftObjectPtr<ULyraInputConfig> InputConfig;
virtual void OnGameFeatureActivating(FGameFeatureActivatingContext& Context) override;
virtual void OnGameFeatureDeactivating(FGameFeatureDeactivatingContext& Context) override;
};
2. 在Experience中引用
// YourExperience.cpp
void UYourGameExperience::OnExperienceLoaded(const ULyraExperienceDefinition* Experience)
{
Super::OnExperienceLoaded(Experience);
// 加载Pawn数据
if (DefaultPawnClass.IsValid())
{
APawn* DefaultPawn = DefaultPawnClass->GetDefaultObject<APawn>();
// 配置pawn组件
}
// 应用输入配置
if (InputConfig)
{
ULyraInputComponent* InputComponent = FindInputComponent();
if (InputComponent)
{
InputComponent->BindAbilityActions(
InputConfig,
this,
&ThisClass::Input_AbilityInputTagPressed,
&ThisClass::Input_AbilityInputTagReleased);
}
}
}
五、部署和使用
1. 打包GameFeature
# GameFeatures/YourFeature/Config/GameFeature.ini
[/Script/GameFeatures.GameFeaturePluginProtocol_InstallBundle]
+InstallBundles=MyFeatureContent
[/Script/GameFeatures.GameFeatureData]
+Actions=/Game/YourFeature/Actions/GFAction_YourAction.GFAction_YourAction
2. 运行时激活
// 在GameMode或Experience中激活
UGameFeaturesSubsystem& Subsystem = UGameFeaturesSubsystem::Get();
Subsystem.LoadAndActivateGameFeaturePlugin("YourFeature", FGameFeaturePluginLoadComplete());
六、关键实现要点
- 移动预测:Lyra使用CharacterMovementComponent的预测机制
- 输入处理:通过LyraInputComponent和InputConfig绑定
- 能力系统:移动与Gameplay Ability System深度集成
- 网络同步:使用UE5的移动组件网络复制
- 模块化设计:通过GameFeature实现功能模块化
这个架构允许你创建完全自定义的角色移动系统,同时保持与Lyra框架的兼容性。
3572

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



