Files
PHY/Source/PHY/Public/Animation/PHYCharacterMeshBridgeComponent.h

99 lines
4.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "UObject/SoftObjectPath.h"
#include "PHYCharacterMeshBridgeComponent.generated.h"
class ACharacter;
class UAnimInstance;
class UPHYClassComponent;
class UPHYRetargetPoseAnimInstance;
class USkeletalMesh;
class USkeletalMeshComponent;
/**
* @brief 角色运动源 Mesh 与显示层 Mesh 的桥接组件。
*
* ACharacter::GetMesh() 固定作为 SourceMeshComponent承载统一运动动画DisplayMeshComponent 承载职业和外观 Mesh。
*/
UCLASS(BlueprintType, Blueprintable, meta=(BlueprintSpawnableComponent))
class PHY_API UPHYCharacterMeshBridgeComponent : public UActorComponent
{
GENERATED_BODY()
public:
/** @brief 构造 Mesh Bridge 默认状态。 */
UPHYCharacterMeshBridgeComponent(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
/** @brief 使用角色和外部创建的显示 Mesh 组件初始化桥接关系。
* @param Character 拥有源运动 Mesh 的角色。
* @param InDisplayMeshComponent 由角色构造阶段创建的显示层 Mesh 组件。
*/
UFUNCTION(BlueprintCallable, Category="PHY|Animation")
void InitializeMeshBridge(ACharacter* Character, USkeletalMeshComponent* InDisplayMeshComponent);
/** @brief 将新的显示 Mesh 应用到显示层,并按骨架关系刷新 Follow Pose 模式。
* @param NewDisplayMesh 新显示层 Skeletal Mesh。
* @param NewDisplayAnimClass 可选显示层 AnimClass异骨架 Retarget 路径使用。
* @param NewRetargeter 可选 Retargeter 软路径,异骨架 Retarget Pose 路径会加载并传递给显示层 AnimInstance。
* @return 应用成功返回 true。
*/
UFUNCTION(BlueprintCallable, Category="PHY|Animation")
bool ApplyDisplayMesh(USkeletalMesh* NewDisplayMesh, TSubclassOf<UAnimInstance> NewDisplayAnimClass = nullptr, FSoftObjectPath NewRetargeter = FSoftObjectPath());
/** @brief 从职业组件读取职业外观并应用到显示层。
* @param ClassComponent 提供职业 Mesh 配置的职业组件。
* @return 应用成功返回 true。
*/
UFUNCTION(BlueprintCallable, Category="PHY|Animation")
bool ApplyPlayerClassVisualFromClassComponent(const UPHYClassComponent* ClassComponent);
/** @brief 根据源 Mesh 和显示 Mesh 的骨架关系刷新 Leader Pose 或显示层 AnimClass。 */
UFUNCTION(BlueprintCallable, Category="PHY|Animation")
void RefreshFollowPoseMode();
/** @brief 获取源运动 Mesh 组件。 */
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Animation")
USkeletalMeshComponent* GetSourceMeshComponent() const { return SourceMeshComponent; }
/** @brief 获取显示层 Mesh 组件。 */
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Animation")
USkeletalMeshComponent* GetDisplayMeshComponent() const { return DisplayMeshComponent; }
/** @brief 按 Socket 查询应使用的可视 Mesh 组件,优先返回拥有该 Socket 的显示层。 */
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Animation")
USkeletalMeshComponent* GetVisualMeshComponentForSocket(FName SocketName) const;
/** @brief 获取当前缓存的 Retargeter 软路径。 */
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Animation")
FSoftObjectPath GetCurrentRetargeter() const { return CurrentRetargeter; }
protected:
/** @brief 应用配置中的源运动 Mesh 和 AnimClass 默认值。 */
void ApplySourceDefaults();
/** @brief 判断显示层是否可使用 Leader Pose 跟随源运动 Mesh。 */
bool CanUseLeaderPose() const;
/** @brief 为异骨架显示层配置 Retarget Pose From Mesh 动画实例。 */
void ConfigureRetargetFollowPose();
/** @brief 获取异骨架显示层应使用的 AnimClass缺省时回退到原生 Retarget AnimInstance。 */
TSubclassOf<UAnimInstance> ResolveRetargetDisplayAnimClass() const;
/** @brief 源运动 Mesh 组件,固定来自 ACharacter::GetMesh()。 */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category="PHY|Animation")
TObjectPtr<USkeletalMeshComponent> SourceMeshComponent;
/** @brief 显示层 Mesh 组件,由 CharacterBase 创建并注入。 */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category="PHY|Animation")
TObjectPtr<USkeletalMeshComponent> DisplayMeshComponent;
/** @brief 当前显示层 Retargeter 软路径,异骨架 Retarget Pose From Mesh 路径使用。 */
UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category="PHY|Animation")
FSoftObjectPath CurrentRetargeter;
};