第一次提交

This commit is contained in:
不明不惑
2026-03-03 01:23:02 +08:00
commit 3e434877e8
1053 changed files with 102411 additions and 0 deletions

View File

@@ -0,0 +1,277 @@
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
#include "Settings/GMS_SettingObjectLibrary.h"
#include "Locomotions/GMS_AnimLayer.h"
#include "Animation/BlendSpace.h"
#include "Locomotions/GMS_AnimLayer_Additive.h"
#include "Locomotions/GMS_AnimLayer_Overlay.h"
#include "Locomotions/GMS_AnimLayer_SkeletalControls.h"
#include "Locomotions/GMS_AnimLayer_States.h"
#include "Locomotions/GMS_AnimLayer_View_Default.h"
#include "Misc/DataValidation.h"
#include "Utility/GMS_Utility.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(GMS_SettingObjectLibrary)
#pragma region CommonSettings
#if WITH_EDITOR
#include "UObject/ObjectSaveContext.h"
void UGMS_MovementDefinition::PreSave(FObjectPreSaveContext SaveContext)
{
Super::PreSave(SaveContext);
}
EDataValidationResult UGMS_MovementDefinition::IsDataValid(class FDataValidationContext& Context) const
{
for (const TTuple<FGameplayTag, FGMS_MovementSetSetting>& Pair : MovementSets)
{
if (Pair.Value.ControlSetting == nullptr)
{
Context.AddError(FText::FromString(FString::Format(TEXT("ControlSetting is required on {0}!!!"), {Pair.Key.GetTagName().ToString()})));
}
if (Pair.Value.bUseInstancedStatesSetting && Pair.Value.AnimLayerSetting_States && Pair.Value.AnimLayerSetting_States->IsDataValid(Context) == EDataValidationResult::Invalid)
{
return EDataValidationResult::Invalid;
}
if (Pair.Value.bUseInstancedOverlaySetting && Pair.Value.AnimLayerSetting_Overlay && Pair.Value.AnimLayerSetting_Overlay->IsDataValid(Context) == EDataValidationResult::Invalid)
{
return EDataValidationResult::Invalid;
}
if (Pair.Value.AnimLayerSetting_Additive && Pair.Value.AnimLayerSetting_Additive->IsDataValid(Context) == EDataValidationResult::Invalid)
{
return EDataValidationResult::Invalid;
}
if (Pair.Value.AnimLayerSetting_View && Pair.Value.AnimLayerSetting_View->IsDataValid(Context) == EDataValidationResult::Invalid)
{
return EDataValidationResult::Invalid;
}
if (Pair.Value.AnimLayerSetting_SkeletalControls && Pair.Value.AnimLayerSetting_SkeletalControls->IsDataValid(Context) == EDataValidationResult::Invalid)
{
return EDataValidationResult::Invalid;
}
}
return Super::IsDataValid(Context);
}
#endif
FGameplayTag UGMS_MovementControlSetting_Default::MatchStateTagBySpeed(float Speed, float Threshold) const
{
for (const FGMS_MovementStateSetting& MovementState : MovementStates)
{
if (MovementState.Speed > 0.0f && MovementState.Speed < Speed + Threshold)
{
return MovementState.Tag;
}
}
return FGameplayTag::EmptyTag;
}
bool UGMS_MovementControlSetting_Default::GetStateByIndex(const int32& Index, FGMS_MovementStateSetting& OutSetting) const
{
if (MovementStates.IsValidIndex(Index))
{
OutSetting = MovementStates[Index];
return true;
}
return false;
}
bool UGMS_MovementControlSetting_Default::GetStateBySpeedLevel(const int32& Level, FGMS_MovementStateSetting& OutSetting) const
{
if (SpeedLevelToArrayIndex.Contains(Level))
{
OutSetting = MovementStates[SpeedLevelToArrayIndex[Level]];
return true;
}
return false;
}
bool UGMS_MovementControlSetting_Default::GetStateByTag(const FGameplayTag& Tag, FGMS_MovementStateSetting& OutSetting) const
{
if (auto Setting = GetMovementStateSetting(Tag))
{
OutSetting = *Setting;
return true;
}
return false;
}
const FGMS_MovementStateSetting* UGMS_MovementControlSetting_Default::GetMovementStateSetting(const FGameplayTag& Tag) const
{
if (!Tag.IsValid())
{
return nullptr;
}
return MovementStates.FindByPredicate([Tag](const FGMS_MovementStateSetting& Setting)
{
return Setting.Tag.IsValid() && Setting.Tag == Tag;
});
}
const FGMS_MovementStateSetting* UGMS_MovementControlSetting_Default::GetMovementStateSetting(const FGameplayTag& Tag, bool bHasFallback) const
{
if (auto Setting = GetMovementStateSetting(Tag))
{
return Setting;
}
if (bHasFallback)
{
checkf(!MovementStates.IsEmpty(), TEXT("%s: MovementStates can't be empty!"), *GetNameSafe(this))
return &MovementStates.Last();
}
return nullptr;
}
#pragma endregion
#pragma region ControlSettings
#if WITH_EDITOR
float UGMS_MovementControlSetting_Default::MigrateRotationInterpolationSpeed(float Old)
{
if (Old <= 0.0f)
{
return 0.0f;
}
// larger old value, smaller new value.
return FMath::GetMappedRangeValueClamped(FVector2f{0.0f, 20.0f}, FVector2f{0.3f, 0.1f}, Old);
}
void UGMS_MovementControlSetting_Default::PreSave(FObjectPreSaveContext SaveContext)
{
Super::PreSave(SaveContext);
SpeedLevelToArrayIndex.Empty();
MovementStates.Sort([](const FGMS_MovementStateSetting& A, const FGMS_MovementStateSetting& B)
{
return A.SpeedLevel < B.SpeedLevel;
});
for (int i = 0; i < MovementStates.Num(); ++i)
{
FGMS_MovementStateSetting& Setting = MovementStates[i];
Setting.EditorFriendlyName = FString::Format(TEXT("State({0}) SpeedLevel({1}) Speed({2})"), {UGMS_Utility::GetSimpleTagName(Setting.Tag).ToString(), Setting.SpeedLevel, Setting.Speed});
SpeedLevelToArrayIndex.Emplace(Setting.SpeedLevel, i);
}
// Migration code for GMS1.5, TODO remove in 1.6
PRAGMA_DISABLE_DEPRECATION_WARNINGS
if (MovementStates.Num() > 0)
{
const FGMS_MovementStateSetting& LastMovementState = MovementStates[MovementStates.Num() - 1];
// migrate velocity direction setting.
if (!VelocityDirectionSetting.IsValid())
{
if (LastMovementState.VelocityDirectionSetting.DirectionMode != EGMS_VelocityDirectionMode_DEPRECATED::TurningCircle)
{
FGMS_VelocityDirectionSetting_Default Temp;
Temp.bEnableRotationWhenNotMoving = LastMovementState.VelocityDirectionSetting.bEnableRotationWhenNotMoving;
Temp.TargetYawAngleRotationSpeed = LastMovementState.TargetYawAngleRotationSpeed;
Temp.RotationInterpolationSpeed = MigrateRotationInterpolationSpeed(LastMovementState.RotationInterpolationSpeed);
Temp.bOrientateToMoveInputIntent = LastMovementState.VelocityDirectionSetting.DirectionMode == EGMS_VelocityDirectionMode_DEPRECATED::OrientToInputDirection;
VelocityDirectionSetting.InitializeAs<FGMS_VelocityDirectionSetting_Default>(Temp);
}
else if (LastMovementState.VelocityDirectionSetting.DirectionMode == EGMS_VelocityDirectionMode_DEPRECATED::TurningCircle)
{
FGMS_VelocityDirectionSetting_RateBased Temp;
Temp.bEnableRotationWhenNotMoving = LastMovementState.VelocityDirectionSetting.bEnableRotationWhenNotMoving;
Temp.TurnRate = LastMovementState.VelocityDirectionSetting.TurningRate;
VelocityDirectionSetting.InitializeAs<FGMS_VelocityDirectionSetting_RateBased>(Temp);
}
}
// migrate view direction setting.
if (!ViewDirectionSetting.IsValid())
{
if (LastMovementState.ViewDirectionSetting.DirectionMode == EGMS_ViewDirectionMode_DEPRECATED::Aiming)
{
FGMS_ViewDirectionSetting_Aiming Temp;
Temp.bEnableRotationWhenNotMoving = LastMovementState.ViewDirectionSetting.bRotateToViewDirectionWhileNotMoving;
Temp.TargetYawAngleRotationSpeed = LastMovementState.TargetYawAngleRotationSpeed;
Temp.RotationInterpolationSpeed = MigrateRotationInterpolationSpeed(LastMovementState.RotationInterpolationSpeed);
Temp.MinAimingYawAngleLimit = LastMovementState.ViewDirectionSetting.MinAimingYawAngleLimit;
ViewDirectionSetting.InitializeAs<FGMS_ViewDirectionSetting_Aiming>(Temp);
}
else if (LastMovementState.ViewDirectionSetting.DirectionMode == EGMS_ViewDirectionMode_DEPRECATED::Default)
{
FGMS_ViewDirectionSetting_Default Temp;
Temp.bEnableRotationWhenNotMoving = LastMovementState.ViewDirectionSetting.bRotateToViewDirectionWhileNotMoving;
Temp.TargetYawAngleRotationSpeed = LastMovementState.TargetYawAngleRotationSpeed;
Temp.RotationInterpolationSpeed = MigrateRotationInterpolationSpeed(LastMovementState.RotationInterpolationSpeed);
ViewDirectionSetting.InitializeAs<FGMS_ViewDirectionSetting_Default>(Temp);
}
}
}
PRAGMA_ENABLE_DEPRECATION_WARNINGS
// Safety guard if still invalid.
if (!VelocityDirectionSetting.IsValid())
{
VelocityDirectionSetting.InitializeAs(FGMS_VelocityDirectionSetting_Default());
}
if (!ViewDirectionSetting.IsValid())
{
ViewDirectionSetting.InitializeAs(FGMS_ViewDirectionSetting_Default());
}
}
EDataValidationResult UGMS_MovementControlSetting_Default::IsDataValid(class FDataValidationContext& Context) const
{
for (int32 i = 0; i < MovementStates.Num(); i++)
{
const FGMS_MovementStateSetting& MRSetting = MovementStates[i];
if (!MRSetting.Tag.IsValid())
{
Context.AddError(FText::FromString(FString::Format(TEXT("Invalid tag at index({0}) of MovementStates"), {i})));
return EDataValidationResult::Invalid;
}
if (MRSetting.AllowedRotationModes.IsEmpty())
{
Context.AddError(FText::FromString(
FString::Format(TEXT("AllowedRotationModes at index({0}) of MovementStates can't be empty!"), {i})));
return EDataValidationResult::Invalid;
}
}
if (!ViewDirectionSetting.IsValid())
{
Context.AddError(FText::FromString(TEXT("Invalid view direction setting")));
return EDataValidationResult::Invalid;
}
if (ViewDirectionSetting.IsValid() && ViewDirectionSetting.GetScriptStruct() == FGMS_ViewDirectionSetting::StaticStruct())
{
Context.AddError(FText::FromString(FString::Format(TEXT("View direction setting({0}) was deprecated!"), {FGMS_ViewDirectionSetting::StaticStruct()->GetName()})));
return EDataValidationResult::Invalid;
}
if (!VelocityDirectionSetting.IsValid())
{
Context.AddError(FText::FromString(TEXT("Invalid velocity direction setting")));
return EDataValidationResult::Invalid;
}
if (VelocityDirectionSetting.IsValid() && VelocityDirectionSetting.GetScriptStruct() == FGMS_VelocityDirectionSetting::StaticStruct())
{
Context.AddError(FText::FromString(FString::Format(TEXT("Velocity direction setting({0}) was deprecated!"), {FGMS_VelocityDirectionSetting::StaticStruct()->GetName()})));
return EDataValidationResult::Invalid;
}
return Super::IsDataValid(Context);
}
#endif
#pragma endregion