Add SLS movement bridge
This commit is contained in:
@@ -24,6 +24,7 @@ public class PHY : ModuleRules
|
|||||||
"GenericInputSystem",
|
"GenericInputSystem",
|
||||||
"GenericGameSystem",
|
"GenericGameSystem",
|
||||||
"GenericEffectsSystem",
|
"GenericEffectsSystem",
|
||||||
|
"SmoothLocomotionSystem",
|
||||||
"AuroraDevs_UGC",
|
"AuroraDevs_UGC",
|
||||||
"IKRig",
|
"IKRig",
|
||||||
"AIModule"
|
"AIModule"
|
||||||
|
|||||||
@@ -17,14 +17,16 @@
|
|||||||
#include "GGA_AbilitySystemComponent.h"
|
#include "GGA_AbilitySystemComponent.h"
|
||||||
#include "GameFramework/CharacterMovementComponent.h"
|
#include "GameFramework/CharacterMovementComponent.h"
|
||||||
#include "Interaction/GGS_InteractionSystemComponent.h"
|
#include "Interaction/GGS_InteractionSystemComponent.h"
|
||||||
|
#include "Locomotion/PHYSLSMovementBridgeComponent.h"
|
||||||
#include "Net/UnrealNetwork.h"
|
#include "Net/UnrealNetwork.h"
|
||||||
#include "PHYGameplayTags.h"
|
#include "PHYGameplayTags.h"
|
||||||
#include "Ragdoll/GGS_RagdollComponent.h"
|
#include "Ragdoll/GGS_RagdollComponent.h"
|
||||||
|
#include "Components/SLSCharacterMovementComponent.h"
|
||||||
#include "Targeting/GCS_TargetingSystemComponent.h"
|
#include "Targeting/GCS_TargetingSystemComponent.h"
|
||||||
#include "Team/GCS_CombatTeamAgentComponent.h"
|
#include "Team/GCS_CombatTeamAgentComponent.h"
|
||||||
|
|
||||||
APHYCharacterBase::APHYCharacterBase(const FObjectInitializer& ObjectInitializer)
|
APHYCharacterBase::APHYCharacterBase(const FObjectInitializer& ObjectInitializer)
|
||||||
: Super(ObjectInitializer)
|
: Super(ObjectInitializer.SetDefaultSubobjectClass<USLSCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
|
||||||
{
|
{
|
||||||
bReplicates = true;
|
bReplicates = true;
|
||||||
|
|
||||||
@@ -36,6 +38,18 @@ APHYCharacterBase::APHYCharacterBase(const FObjectInitializer& ObjectInitializer
|
|||||||
RagdollComponent = CreateDefaultSubobject<UGGS_RagdollComponent>(TEXT("RagdollComponent"));
|
RagdollComponent = CreateDefaultSubobject<UGGS_RagdollComponent>(TEXT("RagdollComponent"));
|
||||||
ContextEffectComponent = CreateDefaultSubobject<UGES_ContextEffectComponent>(TEXT("ContextEffectComponent"));
|
ContextEffectComponent = CreateDefaultSubobject<UGES_ContextEffectComponent>(TEXT("ContextEffectComponent"));
|
||||||
MeshBridgeComponent = CreateDefaultSubobject<UPHYCharacterMeshBridgeComponent>(TEXT("MeshBridgeComponent"));
|
MeshBridgeComponent = CreateDefaultSubobject<UPHYCharacterMeshBridgeComponent>(TEXT("MeshBridgeComponent"));
|
||||||
|
SLSMovementBridgeComponent = CreateDefaultSubobject<UPHYSLSMovementBridgeComponent>(TEXT("SLSMovementBridgeComponent"));
|
||||||
|
|
||||||
|
if (UClass* GenericIntegrationClass = FindObject<UClass>(nullptr, TEXT("/Script/GenericGameSystem.GenericIntegrationComponent")))
|
||||||
|
{
|
||||||
|
GenericIntegrationComponent = Cast<UActorComponent>(CreateDefaultSubobject(
|
||||||
|
TEXT("GenericIntegrationComponent"),
|
||||||
|
UActorComponent::StaticClass(),
|
||||||
|
GenericIntegrationClass,
|
||||||
|
false,
|
||||||
|
false));
|
||||||
|
}
|
||||||
|
|
||||||
DisplayMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("DisplayMeshComponent"));
|
DisplayMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("DisplayMeshComponent"));
|
||||||
DisplayMeshComponent->SetupAttachment(GetMesh());
|
DisplayMeshComponent->SetupAttachment(GetMesh());
|
||||||
DisplayMeshComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
DisplayMeshComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
||||||
@@ -70,6 +84,11 @@ void APHYCharacterBase::BeginPlay()
|
|||||||
ContextEffectComponent->SetGameplayTagsProvider(this);
|
ContextEffectComponent->SetGameplayTagsProvider(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SLSMovementBridgeComponent)
|
||||||
|
{
|
||||||
|
SLSMovementBridgeComponent->InitializeSLSMovementBridge(this, GenericIntegrationComponent);
|
||||||
|
}
|
||||||
|
|
||||||
UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(this, UGameFrameworkComponentManager::NAME_GameActorReady);
|
UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(this, UGameFrameworkComponentManager::NAME_GameActorReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,6 +200,11 @@ bool APHYCharacterBase::HandleInputTag(const FGameplayTag InputTag, const ETrigg
|
|||||||
|
|
||||||
if (InputTag == PHYGameplayTags::Input_Sprint)
|
if (InputTag == PHYGameplayTags::Input_Sprint)
|
||||||
{
|
{
|
||||||
|
if (USLSCharacterMovementComponent* SLSMovementComponent = GetSLSCharacterMovementComponent())
|
||||||
|
{
|
||||||
|
SLSMovementComponent->UpdateMovementType(bPressed ? ESLSMovementType::Sprint : ESLSMovementType::Jog);
|
||||||
|
}
|
||||||
|
|
||||||
if (CharacterStateComponent)
|
if (CharacterStateComponent)
|
||||||
{
|
{
|
||||||
CharacterStateComponent->SetMovementState(bPressed ? PHYGameplayTags::State_Movement_Sprint : PHYGameplayTags::State_Movement_Run);
|
CharacterStateComponent->SetMovementState(bPressed ? PHYGameplayTags::State_Movement_Sprint : PHYGameplayTags::State_Movement_Run);
|
||||||
@@ -197,6 +221,11 @@ bool APHYCharacterBase::HandleInputTag(const FGameplayTag InputTag, const ETrigg
|
|||||||
|
|
||||||
if (InputTag == PHYGameplayTags::Input_Aim)
|
if (InputTag == PHYGameplayTags::Input_Aim)
|
||||||
{
|
{
|
||||||
|
if (USLSCharacterMovementComponent* SLSMovementComponent = GetSLSCharacterMovementComponent())
|
||||||
|
{
|
||||||
|
SLSMovementComponent->UpdateRotationMode(bPressed ? ESLSRotationMode::AimingDirection : ESLSRotationMode::VelocityDirection);
|
||||||
|
}
|
||||||
|
|
||||||
if (CharacterStateComponent)
|
if (CharacterStateComponent)
|
||||||
{
|
{
|
||||||
CharacterStateComponent->SetMovementSet(bPressed ? PHYGameplayTags::State_MovementSet_Aiming : PHYGameplayTags::State_MovementSet_Default);
|
CharacterStateComponent->SetMovementSet(bPressed ? PHYGameplayTags::State_MovementSet_Aiming : PHYGameplayTags::State_MovementSet_Default);
|
||||||
@@ -241,6 +270,11 @@ bool APHYCharacterBase::HandleInputTag(const FGameplayTag InputTag, const ETrigg
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
USLSCharacterMovementComponent* APHYCharacterBase::GetSLSCharacterMovementComponent() const
|
||||||
|
{
|
||||||
|
return Cast<USLSCharacterMovementComponent>(GetCharacterMovement());
|
||||||
|
}
|
||||||
|
|
||||||
void APHYCharacterBase::SetMovementIntent(const FVector NewMovementIntent)
|
void APHYCharacterBase::SetMovementIntent(const FVector NewMovementIntent)
|
||||||
{
|
{
|
||||||
const FVector ClampedIntent = NewMovementIntent.GetClampedToMaxSize(1.0f);
|
const FVector ClampedIntent = NewMovementIntent.GetClampedToMaxSize(1.0f);
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "Locomotion/PHYSLSMovementBridgeComponent.h"
|
||||||
|
|
||||||
|
#include UE_INLINE_GENERATED_CPP_BY_NAME(PHYSLSMovementBridgeComponent)
|
||||||
|
|
||||||
|
#include "Characters/PHYCharacterSettings.h"
|
||||||
|
#include "Components/SLSCharacterMovementComponent.h"
|
||||||
|
#include "GameFramework/Character.h"
|
||||||
|
#include "PHYConfigSettings.h"
|
||||||
|
|
||||||
|
UPHYSLSMovementBridgeComponent::UPHYSLSMovementBridgeComponent()
|
||||||
|
{
|
||||||
|
PrimaryComponentTick.bCanEverTick = false;
|
||||||
|
SetIsReplicatedByDefault(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UPHYSLSMovementBridgeComponent::InitializeSLSMovementBridge(ACharacter* InCharacter, UActorComponent* InGenericIntegrationComponent)
|
||||||
|
{
|
||||||
|
bInitialized = false;
|
||||||
|
OwnerCharacter = InCharacter;
|
||||||
|
GenericIntegrationComponent = InGenericIntegrationComponent;
|
||||||
|
SLSCharacterMovementComponent = nullptr;
|
||||||
|
|
||||||
|
const UPHYLocomotionSettings* LocomotionSettings = GetDefault<UPHYLocomotionSettings>();
|
||||||
|
if (!LocomotionSettings || !LocomotionSettings->bUseSmoothLocomotionSystem || !OwnerCharacter)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SLSCharacterMovementComponent = Cast<USLSCharacterMovementComponent>(OwnerCharacter->GetCharacterMovement());
|
||||||
|
if (!SLSCharacterMovementComponent)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const UPHYCharacterSettings* CharacterSettings = GetDefault<UPHYCharacterSettings>();
|
||||||
|
|
||||||
|
// 首期由项目侧显式初始化,避免依赖 SLSIntegrationComponent 的总装逻辑。
|
||||||
|
SLSCharacterMovementComponent->Config.InitComponentType = ESLSComponentInitType::ManualInit;
|
||||||
|
SLSCharacterMovementComponent->Config.MovementType = ESLSMovementType::Jog;
|
||||||
|
SLSCharacterMovementComponent->Config.RotationMode = ESLSRotationMode::VelocityDirection;
|
||||||
|
SLSCharacterMovementComponent->Config.bEnableSprintInLookingDirectionRotationMode = true;
|
||||||
|
|
||||||
|
SLSCharacterMovementComponent->ApplyBaseSLSCharacterMovementSettings();
|
||||||
|
|
||||||
|
if (CharacterSettings)
|
||||||
|
{
|
||||||
|
SLSCharacterMovementComponent->MaxWalkSpeed = CharacterSettings->DefaultMaxWalkSpeed;
|
||||||
|
SLSCharacterMovementComponent->MaxAcceleration = CharacterSettings->DefaultMaxAcceleration;
|
||||||
|
}
|
||||||
|
|
||||||
|
SLSCharacterMovementComponent->InitializeMovementComponent(SLSCharacterMovementComponent->Config);
|
||||||
|
bInitialized = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -19,7 +19,9 @@ class UGGS_InteractionSystemComponent;
|
|||||||
class UGGS_RagdollComponent;
|
class UGGS_RagdollComponent;
|
||||||
class UPHYCharacterMeshBridgeComponent;
|
class UPHYCharacterMeshBridgeComponent;
|
||||||
class UPHYCharacterStateComponent;
|
class UPHYCharacterStateComponent;
|
||||||
|
class UPHYSLSMovementBridgeComponent;
|
||||||
class USkeletalMeshComponent;
|
class USkeletalMeshComponent;
|
||||||
|
class USLSCharacterMovementComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief PHY 玩家和 AI 共用角色基类。
|
* @brief PHY 玩家和 AI 共用角色基类。
|
||||||
@@ -124,6 +126,18 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Character|Animation")
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Character|Animation")
|
||||||
UPHYCharacterMeshBridgeComponent* GetMeshBridgeComponent() const { return MeshBridgeComponent; }
|
UPHYCharacterMeshBridgeComponent* GetMeshBridgeComponent() const { return MeshBridgeComponent; }
|
||||||
|
|
||||||
|
/** @brief 获取 PHY SLS 运动桥接组件。 */
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Character|Locomotion")
|
||||||
|
UPHYSLSMovementBridgeComponent* GetSLSMovementBridgeComponent() const { return SLSMovementBridgeComponent; }
|
||||||
|
|
||||||
|
/** @brief 获取 SLS 角色运动组件。 */
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Character|Locomotion")
|
||||||
|
USLSCharacterMovementComponent* GetSLSCharacterMovementComponent() const;
|
||||||
|
|
||||||
|
/** @brief 获取 GenericGameSystem 可选集成入口组件。 */
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Character|Locomotion")
|
||||||
|
UActorComponent* GetGenericIntegrationComponent() const { return GenericIntegrationComponent; }
|
||||||
|
|
||||||
/** @brief 获取显示层 Mesh 组件,职业和外观 Mesh 应应用到该组件。 */
|
/** @brief 获取显示层 Mesh 组件,职业和外观 Mesh 应应用到该组件。 */
|
||||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Character|Animation")
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Character|Animation")
|
||||||
USkeletalMeshComponent* GetDisplayMeshComponent() const { return DisplayMeshComponent; }
|
USkeletalMeshComponent* GetDisplayMeshComponent() const { return DisplayMeshComponent; }
|
||||||
@@ -248,6 +262,14 @@ protected:
|
|||||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Character|Animation")
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Character|Animation")
|
||||||
TObjectPtr<UPHYCharacterMeshBridgeComponent> MeshBridgeComponent;
|
TObjectPtr<UPHYCharacterMeshBridgeComponent> MeshBridgeComponent;
|
||||||
|
|
||||||
|
/** @brief PHY 对 SLS 运动系统的桥接组件。 */
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Character|Locomotion")
|
||||||
|
TObjectPtr<UPHYSLSMovementBridgeComponent> SLSMovementBridgeComponent;
|
||||||
|
|
||||||
|
/** @brief GenericGameSystem 可选集成入口组件。 */
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Character|Locomotion")
|
||||||
|
TObjectPtr<UActorComponent> GenericIntegrationComponent;
|
||||||
|
|
||||||
/** @brief 显示层 Mesh 组件,承载职业和外观 Mesh。 */
|
/** @brief 显示层 Mesh 组件,承载职业和外观 Mesh。 */
|
||||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Character|Animation")
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="PHY|Character|Animation")
|
||||||
TObjectPtr<USkeletalMeshComponent> DisplayMeshComponent;
|
TObjectPtr<USkeletalMeshComponent> DisplayMeshComponent;
|
||||||
|
|||||||
68
Source/PHY/Public/Locomotion/PHYSLSMovementBridgeComponent.h
Normal file
68
Source/PHY/Public/Locomotion/PHYSLSMovementBridgeComponent.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Components/ActorComponent.h"
|
||||||
|
#include "PHYSLSMovementBridgeComponent.generated.h"
|
||||||
|
|
||||||
|
class ACharacter;
|
||||||
|
class USLSCharacterMovementComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PHY 对 Smooth Locomotion System 的首期运动桥接组件。
|
||||||
|
*
|
||||||
|
* 该组件只缓存并初始化明确接入的 SLS 运动组件,不使用 SLSIntegrationComponent,
|
||||||
|
* 也不承担相机系统职责。
|
||||||
|
*/
|
||||||
|
UCLASS(BlueprintType, Blueprintable)
|
||||||
|
class PHY_API UPHYSLSMovementBridgeComponent : public UActorComponent
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** @brief 创建运动桥接组件。 */
|
||||||
|
UPHYSLSMovementBridgeComponent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化 SLS 运动桥接。
|
||||||
|
* @param InCharacter 拥有该桥接组件的角色。
|
||||||
|
* @param InGenericIntegrationComponent 可选的 Generic 集成入口组件。
|
||||||
|
* @return 初始化是否成功。
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, Category="PHY|Locomotion|SLS")
|
||||||
|
bool InitializeSLSMovementBridge(ACharacter* InCharacter, UActorComponent* InGenericIntegrationComponent);
|
||||||
|
|
||||||
|
/** @brief 获取桥接到的角色。 */
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Locomotion|SLS")
|
||||||
|
ACharacter* GetOwnerCharacter() const { return OwnerCharacter; }
|
||||||
|
|
||||||
|
/** @brief 获取 SLS 角色运动组件。 */
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Locomotion|SLS")
|
||||||
|
USLSCharacterMovementComponent* GetSLSCharacterMovementComponent() const { return SLSCharacterMovementComponent; }
|
||||||
|
|
||||||
|
/** @brief 获取可选的 Generic 集成入口组件。 */
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Locomotion|SLS")
|
||||||
|
UActorComponent* GetGenericIntegrationComponent() const { return GenericIntegrationComponent; }
|
||||||
|
|
||||||
|
/** @brief 查询桥接是否已完成初始化。 */
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Locomotion|SLS")
|
||||||
|
bool IsSLSMovementBridgeInitialized() const { return bInitialized; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** @brief 拥有 SLS 运动能力的角色。 */
|
||||||
|
UPROPERTY(Transient, BlueprintReadOnly, Category="PHY|Locomotion|SLS")
|
||||||
|
TObjectPtr<ACharacter> OwnerCharacter;
|
||||||
|
|
||||||
|
/** @brief SLS 核心角色运动组件。 */
|
||||||
|
UPROPERTY(Transient, BlueprintReadOnly, Category="PHY|Locomotion|SLS")
|
||||||
|
TObjectPtr<USLSCharacterMovementComponent> SLSCharacterMovementComponent;
|
||||||
|
|
||||||
|
/** @brief GenericGameSystem 提供的可选集成入口。 */
|
||||||
|
UPROPERTY(Transient, BlueprintReadOnly, Category="PHY|Locomotion|SLS")
|
||||||
|
TObjectPtr<UActorComponent> GenericIntegrationComponent;
|
||||||
|
|
||||||
|
/** @brief 桥接初始化状态。 */
|
||||||
|
UPROPERTY(Transient, BlueprintReadOnly, Category="PHY|Locomotion|SLS")
|
||||||
|
bool bInitialized = false;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user