Add class-specific retargeter config
This commit is contained in:
@@ -4,13 +4,13 @@ DefaultAIClassTag=(TagName="Class.Saber")
|
|||||||
bApplyPlayerClassMeshToPlayers=True
|
bApplyPlayerClassMeshToPlayers=True
|
||||||
bApplyPlayerClassMeshToAI=False
|
bApplyPlayerClassMeshToAI=False
|
||||||
!PlayerClassMeshes=ClearArray
|
!PlayerClassMeshes=ClearArray
|
||||||
+PlayerClassMeshes=(ClassTag=(TagName="Class.Saber"),PlayerMesh=None)
|
+PlayerClassMeshes=(ClassTag=(TagName="Class.Saber"),PlayerMesh=None,PlayerRetargeter=)
|
||||||
+PlayerClassMeshes=(ClassTag=(TagName="Class.Lancer"),PlayerMesh=None)
|
+PlayerClassMeshes=(ClassTag=(TagName="Class.Lancer"),PlayerMesh=None,PlayerRetargeter=)
|
||||||
+PlayerClassMeshes=(ClassTag=(TagName="Class.Archer"),PlayerMesh=None)
|
+PlayerClassMeshes=(ClassTag=(TagName="Class.Archer"),PlayerMesh=None,PlayerRetargeter=)
|
||||||
+PlayerClassMeshes=(ClassTag=(TagName="Class.Rider"),PlayerMesh=None)
|
+PlayerClassMeshes=(ClassTag=(TagName="Class.Rider"),PlayerMesh=None,PlayerRetargeter=)
|
||||||
+PlayerClassMeshes=(ClassTag=(TagName="Class.Caster"),PlayerMesh=None)
|
+PlayerClassMeshes=(ClassTag=(TagName="Class.Caster"),PlayerMesh=None,PlayerRetargeter=)
|
||||||
+PlayerClassMeshes=(ClassTag=(TagName="Class.Assassin"),PlayerMesh=None)
|
+PlayerClassMeshes=(ClassTag=(TagName="Class.Assassin"),PlayerMesh=None,PlayerRetargeter=)
|
||||||
+PlayerClassMeshes=(ClassTag=(TagName="Class.Berserker"),PlayerMesh=None)
|
+PlayerClassMeshes=(ClassTag=(TagName="Class.Berserker"),PlayerMesh=None,PlayerRetargeter=)
|
||||||
!CoreAttributeAllocations=ClearArray
|
!CoreAttributeAllocations=ClearArray
|
||||||
+CoreAttributeAllocations=(ClassTag=(TagName="Class.Saber"),Strength=12,Dexterity=10,Vitality=12,Intelligence=8,Spirit=8,Perception=10)
|
+CoreAttributeAllocations=(ClassTag=(TagName="Class.Saber"),Strength=12,Dexterity=10,Vitality=12,Intelligence=8,Spirit=8,Perception=10)
|
||||||
+CoreAttributeAllocations=(ClassTag=(TagName="Class.Lancer"),Strength=10,Dexterity=13,Vitality=10,Intelligence=7,Spirit=8,Perception=12)
|
+CoreAttributeAllocations=(ClassTag=(TagName="Class.Lancer"),Strength=10,Dexterity=13,Vitality=10,Intelligence=7,Spirit=8,Perception=12)
|
||||||
|
|||||||
@@ -93,7 +93,8 @@ bool UPHYCharacterMeshBridgeComponent::ApplyPlayerClassVisualFromClassComponent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
USkeletalMesh* PlayerMesh = ClassComponent->GetConfiguredPlayerMesh();
|
USkeletalMesh* PlayerMesh = ClassComponent->GetConfiguredPlayerMesh();
|
||||||
return PlayerMesh ? ApplyDisplayMesh(PlayerMesh) : false;
|
const FSoftObjectPath PlayerRetargeter = ClassComponent->GetConfiguredPlayerRetargeter();
|
||||||
|
return PlayerMesh ? ApplyDisplayMesh(PlayerMesh, nullptr, PlayerRetargeter) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UPHYCharacterMeshBridgeComponent::RefreshFollowPoseMode()
|
void UPHYCharacterMeshBridgeComponent::RefreshFollowPoseMode()
|
||||||
|
|||||||
@@ -92,6 +92,25 @@ USkeletalMesh* UPHYClassComponent::GetConfiguredPlayerMesh() const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSoftObjectPath UPHYClassComponent::GetConfiguredPlayerRetargeter() const
|
||||||
|
{
|
||||||
|
const UPHYClassSettings* ClassSettings = GetDefault<UPHYClassSettings>();
|
||||||
|
if (!ClassSettings || !CurrentClassTag.IsValid())
|
||||||
|
{
|
||||||
|
return FSoftObjectPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const FPHYPlayerClassMeshConfig& MeshConfig : ClassSettings->PlayerClassMeshes)
|
||||||
|
{
|
||||||
|
if (MeshConfig.ClassTag == CurrentClassTag)
|
||||||
|
{
|
||||||
|
return MeshConfig.PlayerRetargeter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FSoftObjectPath();
|
||||||
|
}
|
||||||
|
|
||||||
bool UPHYClassComponent::ApplyConfiguredPlayerMeshIfAllowed(AActor* AvatarActor) const
|
bool UPHYClassComponent::ApplyConfiguredPlayerMeshIfAllowed(AActor* AvatarActor) const
|
||||||
{
|
{
|
||||||
if (!IsPlayerClassMeshAllowed())
|
if (!IsPlayerClassMeshAllowed())
|
||||||
@@ -112,8 +131,9 @@ bool UPHYClassComponent::ApplyConfiguredPlayerMeshIfAllowed(AActor* AvatarActor)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FSoftObjectPath PlayerRetargeter = GetConfiguredPlayerRetargeter();
|
||||||
UPHYCharacterMeshBridgeComponent* MeshBridge = Character->GetMeshBridgeComponent();
|
UPHYCharacterMeshBridgeComponent* MeshBridge = Character->GetMeshBridgeComponent();
|
||||||
return MeshBridge ? MeshBridge->ApplyDisplayMesh(PlayerMesh) : false;
|
return MeshBridge ? MeshBridge->ApplyDisplayMesh(PlayerMesh, nullptr, PlayerRetargeter) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UPHYClassComponent::ApplyClassAttributesToAbilitySystem(UAbilitySystemComponent* AbilitySystemComponent) const
|
bool UPHYClassComponent::ApplyClassAttributesToAbilitySystem(UAbilitySystemComponent* AbilitySystemComponent) const
|
||||||
|
|||||||
@@ -21,9 +21,11 @@ struct PHY_API FPHYRetargetPoseAnimInstanceProxy : public FAnimInstanceProxy
|
|||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
friend class UPHYRetargetPoseAnimInstance;
|
||||||
|
|
||||||
FPHYRetargetPoseAnimInstanceProxy() = default;
|
FPHYRetargetPoseAnimInstanceProxy() = default;
|
||||||
FPHYRetargetPoseAnimInstanceProxy(UAnimInstance* InAnimInstance, FAnimNode_RetargetPoseFromMesh* InRetargetNode);
|
FPHYRetargetPoseAnimInstanceProxy(UAnimInstance* InAnimInstance, FAnimNode_RetargetPoseFromMesh* InRetargetNode);
|
||||||
|
protected:
|
||||||
virtual void Initialize(UAnimInstance* InAnimInstance) override;
|
virtual void Initialize(UAnimInstance* InAnimInstance) override;
|
||||||
virtual void PreUpdate(UAnimInstance* InAnimInstance, float DeltaSeconds) override;
|
virtual void PreUpdate(UAnimInstance* InAnimInstance, float DeltaSeconds) override;
|
||||||
virtual void CacheBones() override;
|
virtual void CacheBones() override;
|
||||||
@@ -65,8 +67,9 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Animation")
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Animation")
|
||||||
FSoftObjectPath GetRetargeterPath() const { return RetargeterPath; }
|
FSoftObjectPath GetRetargeterPath() const { return RetargeterPath; }
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void NativeInitializeAnimation() override;
|
virtual void NativeInitializeAnimation() override;
|
||||||
|
protected:
|
||||||
virtual FAnimInstanceProxy* CreateAnimInstanceProxy() override;
|
virtual FAnimInstanceProxy* CreateAnimInstanceProxy() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "Components/ActorComponent.h"
|
#include "Components/ActorComponent.h"
|
||||||
#include "GameplayTagContainer.h"
|
#include "GameplayTagContainer.h"
|
||||||
|
#include "UObject/SoftObjectPath.h"
|
||||||
#include "PHYClassComponent.generated.h"
|
#include "PHYClassComponent.generated.h"
|
||||||
|
|
||||||
class USkeletalMesh;
|
class USkeletalMesh;
|
||||||
@@ -43,6 +44,10 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable, Category="PHY|Class")
|
UFUNCTION(BlueprintCallable, Category="PHY|Class")
|
||||||
USkeletalMesh* GetConfiguredPlayerMesh() const;
|
USkeletalMesh* GetConfiguredPlayerMesh() const;
|
||||||
|
|
||||||
|
/** @brief 按当前职业读取配置的玩家 IK Retargeter 软路径,未配置时返回空路径。 */
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Class")
|
||||||
|
FSoftObjectPath GetConfiguredPlayerRetargeter() const;
|
||||||
|
|
||||||
/** @brief 如果策略允许,则把当前职业配置的玩家 Mesh 应用到指定 Avatar 或组件所有者。 */
|
/** @brief 如果策略允许,则把当前职业配置的玩家 Mesh 应用到指定 Avatar 或组件所有者。 */
|
||||||
UFUNCTION(BlueprintCallable, Category="PHY|Class")
|
UFUNCTION(BlueprintCallable, Category="PHY|Class")
|
||||||
bool ApplyConfiguredPlayerMeshIfAllowed(AActor* AvatarActor = nullptr) const;
|
bool ApplyConfiguredPlayerMeshIfAllowed(AActor* AvatarActor = nullptr) const;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "GameplayTagContainer.h"
|
#include "GameplayTagContainer.h"
|
||||||
#include "UObject/Object.h"
|
#include "UObject/Object.h"
|
||||||
|
#include "UObject/SoftObjectPath.h"
|
||||||
#include "UObject/SoftObjectPtr.h"
|
#include "UObject/SoftObjectPtr.h"
|
||||||
#include "PHYClassSettings.generated.h"
|
#include "PHYClassSettings.generated.h"
|
||||||
|
|
||||||
@@ -72,6 +73,10 @@ public:
|
|||||||
/** @brief 玩家使用该职业时应用的专属 Skeletal Mesh 软引用。 */
|
/** @brief 玩家使用该职业时应用的专属 Skeletal Mesh 软引用。 */
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="PHY|Class")
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="PHY|Class")
|
||||||
TSoftObjectPtr<USkeletalMesh> PlayerMesh;
|
TSoftObjectPtr<USkeletalMesh> PlayerMesh;
|
||||||
|
|
||||||
|
/** @brief 玩家使用该职业时优先使用的 IK Retargeter 软路径,留空时回退动画默认配置。 */
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="PHY|Class")
|
||||||
|
FSoftObjectPath PlayerRetargeter;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user