├── .github └── ISSUE_TEMPLATE │ ├── 不具合報告---bug-report.md │ └── 機能要望---feature-request.md ├── .gitignore ├── Config ├── DefaultEditor.ini ├── DefaultEngine.ini ├── DefaultGame.ini └── DefaultGameplayTags.ini ├── Content └── KawaiiPhysicsSample │ ├── Chain │ ├── ABP_ChainAnimDynamics.uasset │ ├── ABP_ChainKawaiiPhysics.uasset │ ├── ABP_ChainKawaiiPhysicsCollision0.uasset │ ├── ABP_ChainKawaiiPhysicsCollision1.uasset │ ├── ABP_ChainKawaiiPhysicsCollision2.uasset │ ├── ABP_ChainKawaiiPhysicsCollision_World.uasset │ ├── ABP_Chain_AnimDynamics.uasset │ ├── ABP_Chain_KawaiiPhysics.uasset │ ├── ABP_Chain_KawaiiPhysics_Collision0.uasset │ ├── ABP_Chain_KawaiiPhysics_Collision1.uasset │ ├── ABP_Chain_KawaiiPhysics_Collision2.uasset │ ├── ABP_Chain_KawaiiPhysics_Collision3.uasset │ ├── ABP_Chain_KawaiiPhysics_Collision_World.uasset │ ├── AnimBP_ChainAnimDynamics.uasset │ ├── AnimBP_ChainKawaiiPhysics.uasset │ ├── AnimBP_ChainKawaiiPhysicsCollision0.uasset │ ├── AnimBP_ChainKawaiiPhysicsCollision1.uasset │ ├── AnimBP_ChainKawaiiPhysicsCollision2.uasset │ ├── AnimBP_ChainKawaiiPhysicsCollision_World.uasset │ ├── BP_Chain.uasset │ ├── M_Metal_Lighter.uasset │ ├── S_Chain.uasset │ ├── S_Chain_PhysicsDefault.uasset │ ├── S_Chain_PhysicsSimulated.uasset │ └── S_Chain_Skeleton.uasset │ ├── Cloth │ ├── CLOTH_SimpleCloth.uasset │ ├── CLOTH_SimpleCloth_PhysicsAsset.uasset │ ├── CLOTH_SimpleCloth_Skeleton.uasset │ └── M_ClothingMaterial.uasset │ ├── GrayChan │ ├── ABP_GC_AnimDynamics.uasset │ ├── ABP_GC_AnimNodeFunction.uasset │ ├── ABP_GC_ExternalForce.uasset │ ├── ABP_GC_KawaiiPhysics.uasset │ ├── ABP_GC_Skirt.uasset │ ├── ABP_GC_UseTemplate.uasset │ ├── ABP_GC_UseTemplate_Override.uasset │ ├── Animations │ │ ├── ThirdPersonIdle.uasset │ │ ├── ThirdPersonRun.uasset │ │ ├── ThirdPersonRun_UseAnimNotify.uasset │ │ ├── ThirdPersonRun_UseAnimNotifyState.uasset │ │ ├── ThirdPersonRun_UseAnimNotifyState_Filterd.uasset │ │ ├── ThirdPersonRun_UseAnimNotifyState_Filtered.uasset │ │ └── ThirdPersonRun_UseAnimNotify_Filtered.uasset │ ├── Blueprints │ │ ├── BP_GrayChan.uasset │ │ └── BP_GrayChan_ExternalForce.uasset │ ├── ExternalForces │ │ └── BP_KawaiiPhysics_ExternalForce_Sample.uasset │ ├── LimitSourceType │ │ ├── ABP_GC_SourceType_AnimNode.uasset │ │ ├── ABP_GC_SourceType_DataAsset.uasset │ │ ├── ABP_GC_SourceType_PhysicsAsset.uasset │ │ ├── Data_ABP_GC_SourceType_Collision.uasset │ │ └── PA_GC_SourceType.uasset │ ├── Materials │ │ ├── MI_GrayChan_Eyballs_Ex.uasset │ │ ├── MI_GrayChan_Logo_Tim.uasset │ │ ├── M_GrayChan_Cloth.uasset │ │ ├── M_GrayChan_Eyballs_Ex.uasset │ │ ├── M_GrayChan_Hair.uasset │ │ ├── M_GrayChan_Logo_Tim.uasset │ │ └── M_GrayChan_Skin.uasset │ ├── Mesh │ │ ├── GrayChan.uasset │ │ ├── GrayChan_PhysicsAsset.uasset │ │ ├── GrayChan_PhysicsAssetTailSimulated.uasset │ │ ├── GrayChan_Skeleton.uasset │ │ └── GrayChan_UsePostProcessABP.uasset │ ├── PABP_GC_AnimNotifies.uasset │ └── Textures │ │ ├── T_GrayChan_Cloth.uasset │ │ ├── T_GrayChan_Cloth_Details.uasset │ │ ├── T_GrayChan_Cloth_MSR.uasset │ │ ├── T_GrayChan_Eyeball.uasset │ │ ├── T_GrayChan_Eyeball_Beta.uasset │ │ ├── T_GrayChan_Eyeball_GuruguruAlp.uasset │ │ ├── T_GrayChan_Eyeball_HeartAlp.uasset │ │ ├── T_GrayChan_Eyeball_Highlight.uasset │ │ ├── T_GrayChan_Eyeball_ShiitakeAlp.uasset │ │ ├── T_GrayChan_Hair.uasset │ │ ├── T_GrayChan_Hair_LUT.uasset │ │ └── T_GrayChan_Skin.uasset │ ├── KawaiiPhysicsSample.umap │ ├── Others │ ├── LS_DemoWarmUp.uasset │ ├── LS_ExternalForce.uasset │ ├── LS_SequencerSample.uasset │ ├── LS_TeleportDistance.uasset │ ├── LS_TeleportRotation.uasset │ └── LS_WorldDampingRotation.uasset │ ├── Skirt │ ├── ABP_Skirt.uasset │ ├── ABP_Skirt_ExternalForce.uasset │ ├── Animations │ │ └── A_CheckSkirt.uasset │ ├── BP_Skirt.uasset │ ├── Blueprints │ │ └── BP_Skirt.uasset │ ├── Data_SkirtBoneConstraints.uasset │ ├── Meshs │ │ ├── SKM_Skirt.uasset │ │ ├── SK_Skirt.uasset │ │ ├── SM_Skirt.uasset │ │ └── S_Skirt.uasset │ └── PABP_Skirt.uasset │ ├── Template │ └── TABP_Base.uasset │ └── Volumes │ └── BP_Volume_AddExternalForce.uasset ├── KawaiiPhysicsSample.uproject ├── LICENSE ├── Plugins └── KawaiiPhysics │ ├── KawaiiPhysics.uplugin │ ├── Resources │ └── Icon128.png │ └── Source │ ├── KawaiiPhysics │ ├── AnimNotifies │ │ ├── AnimNotifyState_KawaiiPhysics.cpp │ │ ├── AnimNotifyState_KawaiiPhysics.h │ │ ├── AnimNotify_KawaiiPhysics.cpp │ │ └── AnimNotify_KawaiiPhysics.h │ ├── KawaiiPhysics.Build.cs │ ├── Private │ │ ├── AnimNode_KawaiiPhysics.cpp │ │ ├── KawaiiPhysics.cpp │ │ ├── KawaiiPhysicsBoneConstraintsDataAsset.cpp │ │ ├── KawaiiPhysicsCustomExternalForce.cpp │ │ ├── KawaiiPhysicsExternalForce.cpp │ │ ├── KawaiiPhysicsLibrary.cpp │ │ └── KawaiiPhysicsLimitsDataAsset.cpp │ └── Public │ │ ├── AnimNode_KawaiiPhysics.h │ │ ├── KawaiiPhysics.h │ │ ├── KawaiiPhysicsBoneConstraintsDataAsset.h │ │ ├── KawaiiPhysicsCustomExternalForce.h │ │ ├── KawaiiPhysicsExternalForce.h │ │ ├── KawaiiPhysicsLibrary.h │ │ └── KawaiiPhysicsLimitsDataAsset.h │ └── KawaiiPhysicsEd │ ├── KawaiiPhysicsEd.Build.cs │ ├── Private │ ├── AnimGraphNode_KawaiiPhysics.cpp │ ├── KawaiiPhysicsEd.cpp │ └── KawaiiPhysicsEditMode.cpp │ └── Public │ ├── AnimGraphNode_KawaiiPhysics.h │ ├── KawaiiPhysicsEd.h │ └── KawaiiPhysicsEditMode.h ├── README.md └── README_en.md /.github/ISSUE_TEMPLATE/不具合報告---bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 不具合報告 - Bug report 3 | about: 改善のためのレポート - Create a report to help us improve 4 | title: "[BUG]" 5 | labels: バグ bug 6 | assignees: pafuhana1213 7 | 8 | --- 9 | 10 | **不具合の説明 - Describe the bug** 11 | 不具合に関して、明確で簡潔な説明を記載してください。 12 | A clear and concise description of what the bug is. 13 | 14 | ** 再現手順 - To Reproduce** 15 | 開発者の手元で再現できないと不具合への対応が困難・不可能になるため 16 | 詳細な再現手順を記載してください。 17 | もし情報が不足していることで再現できなかった場合は対応しない(できない)可能性があります。 18 | If I can't reproduce the issue, it will be difficult or impossible to address it, 19 | so please provide a detailed description of the steps to reproduce it. 20 | If it is not possible to reproduce due to lack of information, it may not be possible to respond (or I may not be able to respond). 21 | 22 | 1. 23 | 2. 24 | 3. 25 | 4. See error 26 | 27 | ** 期待される動作 - Expected behavior** 28 | 期待される動作を明確かつ簡潔に記載してください。 29 | A clear and concise description of what you expected to happen. 30 | 31 | ** 再現環境 - Environment 32 | Engine version : 33 | Plugin version : 34 | BP Only? Use C++?: 35 | 36 | **スクリーンショット または動画 - Screenshots or Movies** 37 | 必要に応じてスクリーンショットまたは動画を添付してください。 38 | If applicable, add screenshots or movies to help explain your problem. 39 | 40 | **その他 - Additional context** 41 | 問題に関するその他の内容はここに記載してください。 42 | Add any other context about the problem here. 43 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/機能要望---feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 機能要望 - Feature request 3 | about: アイデア・提案 - Suggest an idea for this project 4 | title: "[Feature Requset]" 5 | labels: 要望 Request 6 | assignees: pafuhana1213 7 | 8 | --- 9 | 10 | ** あなたの機能リクエストはどんな問題に関連していますか? - Is your feature request related to a problem? Please describe.** 11 | 12 | **あなたのアイデア・提案を説明してください - Describe the solution you'd like** 13 | 14 | **その他 - Additional context** 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio 2015 user specific files 2 | .vs/ 3 | 4 | # Visual Studio 2015 database file 5 | *.VC.db 6 | 7 | # Compiled Object files 8 | *.slo 9 | *.lo 10 | *.o 11 | *.obj 12 | 13 | # Precompiled Headers 14 | *.gch 15 | *.pch 16 | 17 | # Compiled Dynamic libraries 18 | *.so 19 | *.dylib 20 | *.dll 21 | 22 | # Fortran module files 23 | *.mod 24 | 25 | # Compiled Static libraries 26 | *.lai 27 | *.la 28 | *.a 29 | *.lib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.ipa 36 | 37 | # These project files can be generated by the engine 38 | *.xcodeproj 39 | *.xcworkspace 40 | *.sln 41 | *.suo 42 | *.opensdf 43 | *.sdf 44 | *.VC.db 45 | *.VC.opendb 46 | 47 | # Precompiled Assets 48 | SourceArt/**/*.png 49 | SourceArt/**/*.tga 50 | 51 | # Binary Files 52 | Binaries/* 53 | Plugins/*/Binaries/* 54 | 55 | # Builds 56 | Build/* 57 | 58 | # Whitelist PakBlacklist-.txt files 59 | !Build/*/ 60 | Build/*/** 61 | !Build/*/PakBlacklist*.txt 62 | 63 | # Don't ignore icon files in Build 64 | !Build/**/*.ico 65 | 66 | # Built data for maps 67 | *_BuiltData.uasset 68 | 69 | # Configuration files generated by the Editor 70 | Saved/* 71 | 72 | # Compiled source files for the engine to use 73 | Intermediate/* 74 | Plugins/*/Intermediate/* 75 | 76 | # Cache files for the editor to use 77 | DerivedDataCache/* 78 | -------------------------------------------------------------------------------- /Config/DefaultEditor.ini: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /Config/DefaultEngine.ini: -------------------------------------------------------------------------------- 1 | [URL] 2 | [/Script/Engine.RendererSettings] 3 | r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange=True 4 | 5 | [/Script/HardwareTargeting.HardwareTargetingSettings] 6 | TargetedHardwareClass=Desktop 7 | AppliedTargetedHardwareClass=Desktop 8 | DefaultGraphicsPerformance=Maximum 9 | AppliedDefaultGraphicsPerformance=Maximum 10 | 11 | [/Script/EngineSettings.GameMapsSettings] 12 | EditorStartupMap=/Game/KawaiiPhysicsSample/KawaiiPhysicsSample.KawaiiPhysicsSample 13 | GameDefaultMap=/Game/KawaiiPhysicsSample/KawaiiPhysicsSample.KawaiiPhysicsSample 14 | 15 | [/Script/Engine.PhysicsSettings] 16 | DefaultGravityZ=-980.000000 17 | DefaultTerminalVelocity=4000.000000 18 | DefaultFluidFriction=0.300000 19 | SimulateScratchMemorySize=262144 20 | RagdollAggregateThreshold=4 21 | TriangleMeshTriangleMinAreaThreshold=5.000000 22 | bEnableShapeSharing=False 23 | bEnablePCM=True 24 | bEnableStabilization=False 25 | bWarnMissingLocks=True 26 | bEnable2DPhysics=False 27 | PhysicErrorCorrection=(PingExtrapolation=0.100000,PingLimit=100.000000,ErrorPerLinearDifference=1.000000,ErrorPerAngularDifference=1.000000,MaxRestoredStateError=1.000000,MaxLinearHardSnapDistance=400.000000,PositionLerp=0.000000,AngleLerp=0.400000,LinearVelocityCoefficient=100.000000,AngularVelocityCoefficient=10.000000,ErrorAccumulationSeconds=0.500000,ErrorAccumulationDistanceSq=15.000000,ErrorAccumulationSimilarity=100.000000) 28 | LockedAxis=Invalid 29 | DefaultDegreesOfFreedom=Full3D 30 | BounceThresholdVelocity=200.000000 31 | FrictionCombineMode=Average 32 | RestitutionCombineMode=Average 33 | MaxAngularVelocity=3600.000000 34 | MaxDepenetrationVelocity=0.000000 35 | ContactOffsetMultiplier=0.020000 36 | MinContactOffset=2.000000 37 | MaxContactOffset=8.000000 38 | bSimulateSkeletalMeshOnDedicatedServer=True 39 | DefaultShapeComplexity=CTF_UseSimpleAndComplex 40 | bDefaultHasComplexCollision=True 41 | bSuppressFaceRemapTable=False 42 | bSupportUVFromHitResults=False 43 | bDisableActiveActors=False 44 | bDisableKinematicStaticPairs=False 45 | bDisableKinematicKinematicPairs=False 46 | bDisableCCD=False 47 | bEnableEnhancedDeterminism=False 48 | MaxPhysicsDeltaTime=0.033333 49 | bSubstepping=False 50 | bSubsteppingAsync=False 51 | MaxSubstepDeltaTime=0.016667 52 | MaxSubsteps=6 53 | SyncSceneSmoothingFactor=0.000000 54 | InitialAverageFrameRate=0.016667 55 | PhysXTreeRebuildRate=10 56 | DefaultBroadphaseSettings=(bUseMBPOnClient=False,bUseMBPOnServer=False,MBPBounds=(Min=(X=0.000000,Y=0.000000,Z=0.000000),Max=(X=0.000000,Y=0.000000,Z=0.000000),IsValid=0),MBPNumSubdivs=2) 57 | 58 | 59 | -------------------------------------------------------------------------------- /Config/DefaultGame.ini: -------------------------------------------------------------------------------- 1 | [/Script/EngineSettings.GeneralProjectSettings] 2 | ProjectID=16B4F7024E386C8CB97EF2BAEC2AD01A 3 | 4 | [/Script/UnrealEd.ProjectPackagingSettings] 5 | IncludeDebugFiles=True 6 | 7 | -------------------------------------------------------------------------------- /Config/DefaultGameplayTags.ini: -------------------------------------------------------------------------------- 1 | [/Script/GameplayTags.GameplayTagsSettings] 2 | ImportTagsFromConfig=True 3 | WarnOnInvalidTags=True 4 | ClearInvalidTags=False 5 | AllowEditorTagUnloading=True 6 | AllowGameTagUnloading=False 7 | FastReplication=False 8 | InvalidTagCharacters="\"\'," 9 | NumBitsForContainerSize=6 10 | NetIndexFirstBitSegment=16 11 | +GameplayTagList=(Tag="Kawaii.Hair.L",DevComment="") 12 | +GameplayTagList=(Tag="Kawaii.Hair.R",DevComment="") 13 | 14 | -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_ChainAnimDynamics.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_ChainAnimDynamics.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_ChainKawaiiPhysics.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_ChainKawaiiPhysics.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_ChainKawaiiPhysicsCollision0.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_ChainKawaiiPhysicsCollision0.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_ChainKawaiiPhysicsCollision1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_ChainKawaiiPhysicsCollision1.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_ChainKawaiiPhysicsCollision2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_ChainKawaiiPhysicsCollision2.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_ChainKawaiiPhysicsCollision_World.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_ChainKawaiiPhysicsCollision_World.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_Chain_AnimDynamics.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_Chain_AnimDynamics.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics_Collision0.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics_Collision0.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics_Collision1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics_Collision1.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics_Collision2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics_Collision2.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics_Collision3.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics_Collision3.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics_Collision_World.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/ABP_Chain_KawaiiPhysics_Collision_World.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/AnimBP_ChainAnimDynamics.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/AnimBP_ChainAnimDynamics.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/AnimBP_ChainKawaiiPhysics.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/AnimBP_ChainKawaiiPhysics.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/AnimBP_ChainKawaiiPhysicsCollision0.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/AnimBP_ChainKawaiiPhysicsCollision0.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/AnimBP_ChainKawaiiPhysicsCollision1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/AnimBP_ChainKawaiiPhysicsCollision1.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/AnimBP_ChainKawaiiPhysicsCollision2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/AnimBP_ChainKawaiiPhysicsCollision2.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/AnimBP_ChainKawaiiPhysicsCollision_World.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/AnimBP_ChainKawaiiPhysicsCollision_World.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/BP_Chain.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/BP_Chain.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/M_Metal_Lighter.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/M_Metal_Lighter.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/S_Chain.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/S_Chain.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/S_Chain_PhysicsDefault.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/S_Chain_PhysicsDefault.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/S_Chain_PhysicsSimulated.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/S_Chain_PhysicsSimulated.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Chain/S_Chain_Skeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Chain/S_Chain_Skeleton.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Cloth/CLOTH_SimpleCloth.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Cloth/CLOTH_SimpleCloth.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Cloth/CLOTH_SimpleCloth_PhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Cloth/CLOTH_SimpleCloth_PhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Cloth/CLOTH_SimpleCloth_Skeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Cloth/CLOTH_SimpleCloth_Skeleton.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Cloth/M_ClothingMaterial.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Cloth/M_ClothingMaterial.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/ABP_GC_AnimDynamics.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/ABP_GC_AnimDynamics.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/ABP_GC_AnimNodeFunction.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/ABP_GC_AnimNodeFunction.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/ABP_GC_ExternalForce.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/ABP_GC_ExternalForce.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/ABP_GC_KawaiiPhysics.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/ABP_GC_KawaiiPhysics.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/ABP_GC_Skirt.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/ABP_GC_Skirt.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/ABP_GC_UseTemplate.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/ABP_GC_UseTemplate.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/ABP_GC_UseTemplate_Override.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/ABP_GC_UseTemplate_Override.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonIdle.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonIdle.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun_UseAnimNotify.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun_UseAnimNotify.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun_UseAnimNotifyState.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun_UseAnimNotifyState.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun_UseAnimNotifyState_Filterd.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun_UseAnimNotifyState_Filterd.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun_UseAnimNotifyState_Filtered.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun_UseAnimNotifyState_Filtered.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun_UseAnimNotify_Filtered.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Animations/ThirdPersonRun_UseAnimNotify_Filtered.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Blueprints/BP_GrayChan.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Blueprints/BP_GrayChan.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Blueprints/BP_GrayChan_ExternalForce.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Blueprints/BP_GrayChan_ExternalForce.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/ExternalForces/BP_KawaiiPhysics_ExternalForce_Sample.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/ExternalForces/BP_KawaiiPhysics_ExternalForce_Sample.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/LimitSourceType/ABP_GC_SourceType_AnimNode.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/LimitSourceType/ABP_GC_SourceType_AnimNode.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/LimitSourceType/ABP_GC_SourceType_DataAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/LimitSourceType/ABP_GC_SourceType_DataAsset.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/LimitSourceType/ABP_GC_SourceType_PhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/LimitSourceType/ABP_GC_SourceType_PhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/LimitSourceType/Data_ABP_GC_SourceType_Collision.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/LimitSourceType/Data_ABP_GC_SourceType_Collision.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/LimitSourceType/PA_GC_SourceType.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/LimitSourceType/PA_GC_SourceType.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Materials/MI_GrayChan_Eyballs_Ex.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Materials/MI_GrayChan_Eyballs_Ex.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Materials/MI_GrayChan_Logo_Tim.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Materials/MI_GrayChan_Logo_Tim.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Materials/M_GrayChan_Cloth.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Materials/M_GrayChan_Cloth.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Materials/M_GrayChan_Eyballs_Ex.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Materials/M_GrayChan_Eyballs_Ex.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Materials/M_GrayChan_Hair.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Materials/M_GrayChan_Hair.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Materials/M_GrayChan_Logo_Tim.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Materials/M_GrayChan_Logo_Tim.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Materials/M_GrayChan_Skin.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Materials/M_GrayChan_Skin.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Mesh/GrayChan.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Mesh/GrayChan.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Mesh/GrayChan_PhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Mesh/GrayChan_PhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Mesh/GrayChan_PhysicsAssetTailSimulated.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Mesh/GrayChan_PhysicsAssetTailSimulated.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Mesh/GrayChan_Skeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Mesh/GrayChan_Skeleton.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Mesh/GrayChan_UsePostProcessABP.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Mesh/GrayChan_UsePostProcessABP.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/PABP_GC_AnimNotifies.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/PABP_GC_AnimNotifies.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Cloth.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Cloth.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Cloth_Details.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Cloth_Details.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Cloth_MSR.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Cloth_MSR.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball_Beta.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball_Beta.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball_GuruguruAlp.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball_GuruguruAlp.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball_HeartAlp.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball_HeartAlp.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball_Highlight.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball_Highlight.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball_ShiitakeAlp.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Eyeball_ShiitakeAlp.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Hair.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Hair.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Hair_LUT.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Hair_LUT.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Skin.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/GrayChan/Textures/T_GrayChan_Skin.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/KawaiiPhysicsSample.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/KawaiiPhysicsSample.umap -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Others/LS_DemoWarmUp.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Others/LS_DemoWarmUp.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Others/LS_ExternalForce.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Others/LS_ExternalForce.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Others/LS_SequencerSample.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Others/LS_SequencerSample.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Others/LS_TeleportDistance.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Others/LS_TeleportDistance.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Others/LS_TeleportRotation.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Others/LS_TeleportRotation.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Others/LS_WorldDampingRotation.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Others/LS_WorldDampingRotation.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Skirt/ABP_Skirt.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Skirt/ABP_Skirt.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Skirt/ABP_Skirt_ExternalForce.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Skirt/ABP_Skirt_ExternalForce.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Skirt/Animations/A_CheckSkirt.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Skirt/Animations/A_CheckSkirt.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Skirt/BP_Skirt.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Skirt/BP_Skirt.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Skirt/Blueprints/BP_Skirt.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Skirt/Blueprints/BP_Skirt.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Skirt/Data_SkirtBoneConstraints.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Skirt/Data_SkirtBoneConstraints.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Skirt/Meshs/SKM_Skirt.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Skirt/Meshs/SKM_Skirt.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Skirt/Meshs/SK_Skirt.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Skirt/Meshs/SK_Skirt.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Skirt/Meshs/SM_Skirt.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Skirt/Meshs/SM_Skirt.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Skirt/Meshs/S_Skirt.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Skirt/Meshs/S_Skirt.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Skirt/PABP_Skirt.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Skirt/PABP_Skirt.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Template/TABP_Base.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Template/TABP_Base.uasset -------------------------------------------------------------------------------- /Content/KawaiiPhysicsSample/Volumes/BP_Volume_AddExternalForce.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Content/KawaiiPhysicsSample/Volumes/BP_Volume_AddExternalForce.uasset -------------------------------------------------------------------------------- /KawaiiPhysicsSample.uproject: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "EngineAssociation": "5.2", 4 | "Category": "", 5 | "Description": "" 6 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2024 pafuhana1213 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/KawaiiPhysics.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1.18, 4 | "VersionName": "1.18.0", 5 | "FriendlyName": "KawaiiPhysics", 6 | "Description": "", 7 | "Category": "Animation", 8 | "CreatedBy": "pafuhana1213", 9 | "CreatedByURL": "https://twitter.com/pafuhana1213", 10 | "DocsURL": "https://github.com/pafuhana1213/KawaiiPhysics", 11 | "MarketplaceURL": "KawaiiPhysics : Simple fake Physics for UnrealEngine4&5", 12 | "SupportURL": "https://github.com/pafuhana1213/KawaiiPhysics/issues", 13 | "CanContainContent": false, 14 | "IsBetaVersion": false, 15 | "IsExperimentalVersion": false, 16 | "Installed": false, 17 | "Modules": [ 18 | { 19 | "Name": "KawaiiPhysics", 20 | "Type": "Runtime", 21 | "LoadingPhase": "PostConfigInit" 22 | }, 23 | { 24 | "Name": "KawaiiPhysicsEd", 25 | "Type": "UncookedOnly", 26 | "LoadingPhase": "PreDefault" 27 | } 28 | ], 29 | "Plugins": [ 30 | { 31 | "Name": "StructUtils", 32 | "Enabled": true 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pafuhana1213/KawaiiPhysics/257f31918dd325f91404d13d958412ad5868ce59/Plugins/KawaiiPhysics/Resources/Icon128.png -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/AnimNotifies/AnimNotifyState_KawaiiPhysics.cpp: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | 4 | #include "AnimNotifyState_KawaiiPhysics.h" 5 | #include "KawaiiPhysicsLibrary.h" 6 | #include "Misc/UObjectToken.h" 7 | 8 | #define LOCTEXT_NAMESPACE "KawaiiPhysics_AnimNotifyState" 9 | 10 | UAnimNotifyState_KawaiiPhysicsAddExternalForce::UAnimNotifyState_KawaiiPhysicsAddExternalForce( 11 | const FObjectInitializer& ObjectInitializer) 12 | : Super(ObjectInitializer) 13 | { 14 | #if WITH_EDITORONLY_DATA 15 | NotifyColor = FColor(255, 170, 0, 255); 16 | #endif // WITH_EDITORONLY_DATA 17 | } 18 | 19 | FString UAnimNotifyState_KawaiiPhysicsAddExternalForce::GetNotifyName_Implementation() const 20 | { 21 | return FString(TEXT("KP: Add ExternalForce")); 22 | } 23 | 24 | void UAnimNotifyState_KawaiiPhysicsAddExternalForce::NotifyBegin(USkeletalMeshComponent* MeshComp, 25 | UAnimSequenceBase* Animation, 26 | float TotalDuration, 27 | const FAnimNotifyEventReference& EventReference) 28 | { 29 | UKawaiiPhysicsLibrary::AddExternalForcesToComponent(MeshComp, AdditionalExternalForces, this, 30 | FilterTags, bFilterExactMatch); 31 | Super::NotifyBegin(MeshComp, Animation, TotalDuration, EventReference); 32 | } 33 | 34 | void UAnimNotifyState_KawaiiPhysicsAddExternalForce::NotifyEnd(USkeletalMeshComponent* MeshComp, 35 | UAnimSequenceBase* Animation, 36 | const FAnimNotifyEventReference& EventReference) 37 | { 38 | UKawaiiPhysicsLibrary::RemoveExternalForcesFromComponent(MeshComp, this, FilterTags, bFilterExactMatch); 39 | 40 | Super::NotifyEnd(MeshComp, Animation, EventReference); 41 | } 42 | 43 | #if WITH_EDITOR 44 | void UAnimNotifyState_KawaiiPhysicsAddExternalForce::ValidateAssociatedAssets() 45 | { 46 | static const FName NAME_AssetCheck("AssetCheck"); 47 | 48 | if (const UAnimSequenceBase* ContainingAsset = Cast(GetContainingAsset())) 49 | { 50 | for (auto& ForceInstancedStruct : AdditionalExternalForces) 51 | { 52 | if (!ForceInstancedStruct.IsValid()) 53 | { 54 | FMessageLog AssetCheckLog(NAME_AssetCheck); 55 | 56 | const FText MessageLooping = FText::Format( 57 | NSLOCTEXT("AnimNotify", "ExternalForce_ShouldSet", 58 | " AnimNotifyState(KawaiiPhysics_AddExternalForce) doesn't have a valid ExternalForce in {0}"), 59 | FText::AsCultureInvariant(ContainingAsset->GetPathName())); 60 | 61 | AssetCheckLog.Warning() 62 | ->AddToken(FUObjectToken::Create(ContainingAsset)) 63 | ->AddToken(FTextToken::Create(MessageLooping)); 64 | 65 | if (GIsEditor) 66 | { 67 | constexpr bool bForce = true; 68 | AssetCheckLog.Notify(MessageLooping, EMessageSeverity::Warning, bForce); 69 | } 70 | } 71 | 72 | //const auto& ExternalForce = ForceInstancedStruct.Get(); 73 | } 74 | } 75 | } 76 | 77 | #endif 78 | 79 | #undef LOCTEXT_NAMESPACE 80 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/AnimNotifies/AnimNotifyState_KawaiiPhysics.h: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameplayTagContainer.h" 7 | #include "Animation/AnimNotifies/AnimNotifyState.h" 8 | 9 | #if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 10 | #include "StructUtils/InstancedStruct.h" 11 | #else 12 | #include "InstancedStruct.h" 13 | #endif 14 | 15 | #include "AnimNotifyState_KawaiiPhysics.generated.h" 16 | 17 | /** 18 | * UAnimNotifyState_KawaiiPhysicsAddExternalForce 19 | * 20 | * This class represents an animation notify state that adds external forces to a skeletal mesh component 21 | * during an animation sequence. It inherits from UAnimNotifyState and provides functionality to add and remove 22 | * external forces at the beginning and end of the animation notify state. 23 | */ 24 | UCLASS(Blueprintable, meta = (DisplayName = "KawaiiPhyiscs: Add ExternalForce")) 25 | class KAWAIIPHYSICS_API UAnimNotifyState_KawaiiPhysicsAddExternalForce : public UAnimNotifyState 26 | { 27 | GENERATED_BODY() 28 | 29 | public: 30 | /** 31 | * Constructor for UAnimNotifyState_KawaiiPhysicsAddExternalForce. 32 | * 33 | * @param ObjectInitializer - The object initializer for this class. 34 | */ 35 | UAnimNotifyState_KawaiiPhysicsAddExternalForce(const FObjectInitializer& ObjectInitializer); 36 | 37 | /** 38 | * Gets the name of the notify state. 39 | * 40 | * @return The name of the notify state as a string. 41 | */ 42 | virtual FString GetNotifyName_Implementation() const override; 43 | 44 | /** 45 | * Called when the animation notify state begins. 46 | * 47 | * @param MeshComp - The skeletal mesh component. 48 | * @param Animation - The animation sequence. 49 | * @param TotalDuration - The total duration of the notify state. 50 | * @param EventReference - The event reference. 51 | */ 52 | virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, 53 | const FAnimNotifyEventReference& EventReference) override; 54 | 55 | /** 56 | * Called when the animation notify state ends. 57 | * 58 | * @param MeshComp - The skeletal mesh component. 59 | * @param Animation - The animation sequence. 60 | * @param EventReference - The event reference. 61 | */ 62 | virtual void NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, 63 | const FAnimNotifyEventReference& EventReference) override; 64 | 65 | /** 66 | * Additional external forces to be applied to the skeletal mesh component. 67 | */ 68 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ExternalForce", 69 | meta = (BaseStruct = "/Script/KawaiiPhysics.KawaiiPhysics_ExternalForce", ExcludeBaseStruct)) 70 | TArray AdditionalExternalForces; 71 | 72 | /** 73 | * Tags used to filter which external forces are applied. 74 | */ 75 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ExternalForce") 76 | FGameplayTagContainer FilterTags; 77 | 78 | /** 79 | * Whether to filter tags to exact matches (if False, parent tags will also be included). 80 | * Tagのフィルタリングにて完全一致にするか否か(Falseの場合は親Tagも含めます) 81 | */ 82 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ExternalForce") 83 | bool bFilterExactMatch; 84 | 85 | #if WITH_EDITOR 86 | /** 87 | * Validates the associated assets in the editor. 88 | */ 89 | virtual void ValidateAssociatedAssets() override; 90 | #endif 91 | }; 92 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/AnimNotifies/AnimNotify_KawaiiPhysics.cpp: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #include "AnimNotify_KawaiiPhysics.h" 4 | #include "KawaiiPhysicsLibrary.h" 5 | #include "Misc/UObjectToken.h" 6 | #include "Logging/MessageLog.h" 7 | 8 | #define LOCTEXT_NAMESPACE "KawaiiPhysics_AnimNotify" 9 | 10 | UAnimNotify_KawaiiPhysicsAddExternalForce::UAnimNotify_KawaiiPhysicsAddExternalForce( 11 | const FObjectInitializer& ObjectInitializer) 12 | { 13 | #if WITH_EDITORONLY_DATA 14 | NotifyColor = FColor(255, 170, 0, 255); 15 | #endif // WITH_EDITORONLY_DATA 16 | } 17 | 18 | FString UAnimNotify_KawaiiPhysicsAddExternalForce::GetNotifyName_Implementation() const 19 | { 20 | return FString(TEXT("KP: Add ExternalForce")); 21 | } 22 | 23 | void UAnimNotify_KawaiiPhysicsAddExternalForce::Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, 24 | const FAnimNotifyEventReference& EventReference) 25 | { 26 | UKawaiiPhysicsLibrary::AddExternalForcesToComponent(MeshComp, AdditionalExternalForces, this, 27 | FilterTags, bFilterExactMatch, true); 28 | 29 | Super::Notify(MeshComp, Animation, EventReference); 30 | } 31 | 32 | #if WITH_EDITOR 33 | void UAnimNotify_KawaiiPhysicsAddExternalForce::ValidateAssociatedAssets() 34 | { 35 | static const FName NAME_AssetCheck("AssetCheck"); 36 | 37 | if (const UAnimSequenceBase* ContainingAsset = Cast(GetContainingAsset())) 38 | { 39 | for (auto& ForceInstancedStruct : AdditionalExternalForces) 40 | { 41 | if (!ForceInstancedStruct.IsValid()) 42 | { 43 | FMessageLog AssetCheckLog(NAME_AssetCheck); 44 | 45 | const FText MessageLooping = FText::Format( 46 | NSLOCTEXT("AnimNotify", "ExternalForce_ShouldSet", 47 | " AnimNotify(KawaiiPhysics_AddExternalForce) doesn't have a valid ExternalForce in {0}"), 48 | FText::AsCultureInvariant(ContainingAsset->GetPathName())); 49 | 50 | AssetCheckLog.Warning() 51 | ->AddToken(FUObjectToken::Create(ContainingAsset)) 52 | ->AddToken(FTextToken::Create(MessageLooping)); 53 | 54 | if (GIsEditor) 55 | { 56 | constexpr bool bForce = true; 57 | AssetCheckLog.Notify(MessageLooping, EMessageSeverity::Warning, bForce); 58 | } 59 | } 60 | 61 | //const auto& ExternalForce = ForceInstancedStruct.Get(); 62 | } 63 | } 64 | } 65 | #endif 66 | 67 | #undef LOCTEXT_NAMESPACE 68 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/AnimNotifies/AnimNotify_KawaiiPhysics.h: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameplayTagContainer.h" 7 | #include "Animation/AnimNotifies/AnimNotify.h" 8 | 9 | #if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 5 10 | #include "StructUtils/InstancedStruct.h" 11 | #else 12 | #include "InstancedStruct.h" 13 | #endif 14 | 15 | #include "AnimNotify_KawaiiPhysics.generated.h" 16 | 17 | /** 18 | * UAnimNotify_KawaiiPhysicsAddExternalForce 19 | * 20 | * This class represents an animation notify that adds external forces to a skeletal mesh component 21 | * during an animation sequence. It inherits from UAnimNotify and provides functionality to add and remove 22 | * external forces when the notify is triggered. 23 | */ 24 | UCLASS(Blueprintable, meta = (DisplayName = "KawaiiPhyiscs: Add ExternalForce")) 25 | class KAWAIIPHYSICS_API UAnimNotify_KawaiiPhysicsAddExternalForce : public UAnimNotify 26 | { 27 | GENERATED_BODY() 28 | 29 | public: 30 | /** 31 | * Constructor for UAnimNotify_KawaiiPhysicsAddExternalForce. 32 | * 33 | * @param ObjectInitializer - The object initializer for this class. 34 | */ 35 | UAnimNotify_KawaiiPhysicsAddExternalForce(const FObjectInitializer& ObjectInitializer); 36 | 37 | /** 38 | * Gets the name of the notify. 39 | * 40 | * @return The name of the notify as a string. 41 | */ 42 | virtual FString GetNotifyName_Implementation() const override; 43 | 44 | /** 45 | * Called when the animation notify is triggered. 46 | * 47 | * @param MeshComp - The skeletal mesh component. 48 | * @param Animation - The animation sequence. 49 | * @param EventReference - The event reference. 50 | */ 51 | virtual void Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, 52 | const FAnimNotifyEventReference& EventReference) override; 53 | 54 | public: 55 | /** 56 | * Additional external forces to be applied to the skeletal mesh component. 57 | */ 58 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ExternalForce", 59 | meta = (BaseStruct = "/Script/KawaiiPhysics.KawaiiPhysics_ExternalForce", ExcludeBaseStruct)) 60 | TArray AdditionalExternalForces; 61 | 62 | /** 63 | * Tags used to filter which external forces are applied. 64 | */ 65 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ExternalForce") 66 | FGameplayTagContainer FilterTags; 67 | 68 | /** 69 | * Whether to filter tags to exact matches (if False, parent tags will also be included). 70 | * Tagのフィルタリングにて完全一致にするか否か(Falseの場合は親Tagも含めます) 71 | */ 72 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ExternalForce") 73 | bool bFilterExactMatch; 74 | 75 | #if WITH_EDITOR 76 | /** 77 | * Validates the associated assets in the editor. 78 | */ 79 | virtual void ValidateAssociatedAssets() override; 80 | #endif 81 | }; 82 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/KawaiiPhysics.Build.cs: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | using UnrealBuildTool; 4 | 5 | public class KawaiiPhysics : ModuleRules 6 | { 7 | public KawaiiPhysics(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] 13 | { 14 | // ... add public include paths required here ... 15 | } 16 | ); 17 | 18 | 19 | PrivateIncludePaths.AddRange( 20 | new string[] 21 | { 22 | // ... add other private include paths required here ... 23 | } 24 | ); 25 | 26 | 27 | PublicDependencyModuleNames.AddRange( 28 | new[] 29 | { 30 | "Core", 31 | // ... add other public dependencies that you statically link with here ... 32 | "AnimGraphRuntime", 33 | "GameplayTags" 34 | } 35 | ); 36 | 37 | // StructUtils plugin has been integrated into the engine starting from 5.5 38 | if (Target.Version.MajorVersion == 5 && Target.Version.MinorVersion <= 4) 39 | { 40 | PublicDependencyModuleNames.Add("StructUtils"); 41 | } 42 | 43 | PrivateDependencyModuleNames.AddRange( 44 | new[] 45 | { 46 | "CoreUObject", 47 | "Engine", 48 | "Slate", 49 | "SlateCore" 50 | // ... add private dependencies that you statically link with here ... 51 | } 52 | ); 53 | 54 | 55 | DynamicallyLoadedModuleNames.AddRange( 56 | new string[] 57 | { 58 | // ... add any modules that your module loads dynamically here ... 59 | } 60 | ); 61 | 62 | if (Target.bBuildEditor) PublicDependencyModuleNames.Add("UnrealEd"); 63 | } 64 | } -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Private/KawaiiPhysics.cpp: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #include "KawaiiPhysics.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | #define LOCTEXT_NAMESPACE "FKawaiiPhysicsModule" 7 | 8 | void FKawaiiPhysicsModule::StartupModule() 9 | { 10 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 11 | } 12 | 13 | void FKawaiiPhysicsModule::ShutdownModule() 14 | { 15 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 16 | // we call this function before unloading the module. 17 | } 18 | 19 | #undef LOCTEXT_NAMESPACE 20 | 21 | IMPLEMENT_MODULE(FKawaiiPhysicsModule, KawaiiPhysics) 22 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Private/KawaiiPhysicsBoneConstraintsDataAsset.cpp: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | 4 | #include "KawaiiPhysicsBoneConstraintsDataAsset.h" 5 | 6 | #include "KawaiiPhysics.h" 7 | #include "Internationalization/Regex.h" 8 | 9 | #if WITH_EDITOR 10 | #include "Editor.h" 11 | #endif 12 | 13 | struct FBoneConstraintDataCustomVersion 14 | { 15 | enum Type 16 | { 17 | // FNameからFBoneReferenceに移行 18 | ChangeToBoneReference = 0, 19 | 20 | // ------------------------------------------------------ 21 | VersionPlusOne, 22 | LatestVersion = VersionPlusOne - 1 23 | }; 24 | 25 | // The GUID for this custom version number 26 | const static FGuid GUID; 27 | 28 | private: 29 | FBoneConstraintDataCustomVersion() 30 | { 31 | } 32 | }; 33 | 34 | const FGuid FBoneConstraintDataCustomVersion::GUID(0xA1C4D3F6, 0x5B2E7A8D, 0x9F6E4B3C, 0xD7E1A8B2); 35 | FCustomVersionRegistration GRegisterBoneConstraintDataCustomVersion(FBoneConstraintDataCustomVersion::GUID, 36 | FBoneConstraintDataCustomVersion::LatestVersion, 37 | TEXT("BoneConstraintData")); 38 | 39 | void FModifyBoneConstraintData::Update(const FModifyBoneConstraint& BoneConstraint) 40 | { 41 | BoneReference1 = BoneConstraint.Bone1; 42 | BoneReference2 = BoneConstraint.Bone2; 43 | bOverrideCompliance = BoneConstraint.bOverrideCompliance; 44 | ComplianceType = BoneConstraint.ComplianceType; 45 | } 46 | 47 | TArray UKawaiiPhysicsBoneConstraintsDataAsset::GenerateBoneConstraints() 48 | { 49 | TArray BoneConstraints; 50 | 51 | for (const FModifyBoneConstraintData& BoneConstraintData : BoneConstraintsData) 52 | { 53 | FModifyBoneConstraint BoneConstraint; 54 | BoneConstraint.Bone1 = BoneConstraintData.BoneReference1; 55 | BoneConstraint.Bone2 = BoneConstraintData.BoneReference2; 56 | BoneConstraint.bOverrideCompliance = BoneConstraintData.bOverrideCompliance; 57 | BoneConstraint.ComplianceType = BoneConstraintData.ComplianceType; 58 | 59 | BoneConstraints.Add(BoneConstraint); 60 | } 61 | 62 | return BoneConstraints; 63 | } 64 | 65 | void UKawaiiPhysicsBoneConstraintsDataAsset::Serialize(FStructuredArchiveRecord Record) 66 | { 67 | Super::Serialize(Record); 68 | 69 | Record.GetUnderlyingArchive().UsingCustomVersion(FBoneConstraintDataCustomVersion::GUID); 70 | } 71 | 72 | void UKawaiiPhysicsBoneConstraintsDataAsset::PostLoad() 73 | { 74 | Super::PostLoad(); 75 | 76 | if (GetLinkerCustomVersion(FBoneConstraintDataCustomVersion::GUID) < 77 | FBoneConstraintDataCustomVersion::ChangeToBoneReference) 78 | { 79 | for (auto& Data : BoneConstraintsData) 80 | { 81 | Data.BoneReference1 = FBoneReference(Data.BoneName1); 82 | Data.BoneReference2 = FBoneReference(Data.BoneName2); 83 | } 84 | 85 | #if WITH_EDITOR 86 | UpdatePreviewBoneList(); 87 | #endif 88 | UE_LOG(LogKawaiiPhysics, Log, TEXT("Update : BoneName -> BoneReference (%s)"), *this->GetName()); 89 | } 90 | } 91 | 92 | USkeleton* UKawaiiPhysicsBoneConstraintsDataAsset::GetSkeleton(bool& bInvalidSkeletonIsError, 93 | const IPropertyHandle* PropertyHandle) 94 | { 95 | #if WITH_EDITOR 96 | return PreviewSkeleton.LoadSynchronous(); 97 | #else 98 | return nullptr; 99 | #endif 100 | } 101 | 102 | #if WITH_EDITOR 103 | #define LOCTEXT_NAMESPACE "KawaiiPhysicsBoneConstraintsDataAsset" 104 | 105 | void UKawaiiPhysicsBoneConstraintsDataAsset::ApplyRegex() 106 | { 107 | GEditor->BeginTransaction(FText::FromString("ApplyRegex")); 108 | Modify(); 109 | 110 | UpdatePreviewBoneList(); 111 | 112 | for (FRegexPatternBoneSet& Pattern : RegexPatternList) 113 | { 114 | const FRegexPattern Pattern1 = FRegexPattern(Pattern.RegexPatternBone1); 115 | const FRegexPattern Pattern2 = FRegexPattern(Pattern.RegexPatternBone2); 116 | 117 | FRegexMatcher Matcher1(Pattern1, PreviewBoneListString); 118 | FRegexMatcher Matcher2(Pattern2, PreviewBoneListString); 119 | 120 | while (Matcher1.FindNext() && Matcher2.FindNext()) 121 | { 122 | FModifyBoneConstraintData BoneConstraintData; 123 | BoneConstraintData.BoneReference1 = FBoneReference(FName(*Matcher1.GetCaptureGroup(0))); 124 | BoneConstraintData.BoneReference2 = FBoneReference(FName(*Matcher2.GetCaptureGroup(0))); 125 | BoneConstraintsData.Add(BoneConstraintData); 126 | } 127 | } 128 | 129 | GEditor->EndTransaction(); 130 | } 131 | 132 | 133 | void UKawaiiPhysicsBoneConstraintsDataAsset::UpdatePreviewBoneList() 134 | { 135 | PreviewBoneList.Empty(); 136 | PreviewBoneListString.Empty(); 137 | 138 | if (!PreviewSkeleton.IsValid()) 139 | { 140 | PreviewSkeleton.LoadSynchronous(); 141 | } 142 | 143 | if (PreviewSkeleton.IsValid()) 144 | { 145 | const FReferenceSkeleton& RefSkeleton = PreviewSkeleton->GetReferenceSkeleton(); 146 | const TArray& RefBoneInfo = RefSkeleton.GetRefBoneInfo(); 147 | 148 | for (const FMeshBoneInfo& BoneInfo : RefBoneInfo) 149 | { 150 | PreviewBoneList.Add(BoneInfo.Name); 151 | PreviewBoneListString.Append(BoneInfo.Name.ToString()); 152 | PreviewBoneListString.Append(TEXT(", ")); 153 | } 154 | } 155 | } 156 | 157 | void UKawaiiPhysicsBoneConstraintsDataAsset::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) 158 | { 159 | const FName PropertyName = PropertyChangedEvent.MemberProperty 160 | ? PropertyChangedEvent.MemberProperty->GetFName() 161 | : NAME_None; 162 | 163 | if (PropertyName == FName(TEXT("PreviewSkeleton"))) 164 | { 165 | UpdatePreviewBoneList(); 166 | } 167 | } 168 | 169 | #undef LOCTEXT_NAMESPACE 170 | 171 | #endif 172 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Private/KawaiiPhysicsCustomExternalForce.cpp: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #include "KawaiiPhysicsCustomExternalForce.h" 4 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Private/KawaiiPhysicsExternalForce.cpp: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #include "KawaiiPhysicsExternalForce.h" 4 | 5 | #include "SceneInterface.h" 6 | #include "GameFramework/Character.h" 7 | #include "GameFramework/CharacterMovementComponent.h" 8 | 9 | DECLARE_CYCLE_STAT(TEXT("KawaiiPhysics_ExternalForce_Basic_Apply"), STAT_KawaiiPhysics_ExternalForce_Basic_Apply, 10 | STATGROUP_Anim); 11 | DECLARE_CYCLE_STAT(TEXT("KawaiiPhysics_ExternalForce_Gravity_Apply"), STAT_KawaiiPhysics_ExternalForce_Gravity_Apply, 12 | STATGROUP_Anim); 13 | DECLARE_CYCLE_STAT(TEXT("KawaiiPhysics_ExternalForce_Curve_Apply"), STAT_KawaiiPhysics_ExternalForce_Curve_Apply, 14 | STATGROUP_Anim); 15 | DECLARE_CYCLE_STAT(TEXT("KawaiiPhysics_ExternalForce_Wind_Apply"), STAT_KawaiiPhysics_ExternalForce_Wind_Apply, 16 | STATGROUP_Anim); 17 | 18 | /// 19 | /// Basic 20 | /// 21 | void FKawaiiPhysics_ExternalForce_Basic::PreApply(FAnimNode_KawaiiPhysics& Node, 22 | const USkeletalMeshComponent* SkelComp) 23 | { 24 | Super::PreApply(Node, SkelComp); 25 | 26 | PrevTime = Time; 27 | Time += Node.DeltaTime; 28 | if (Interval > 0.0f) 29 | { 30 | if (Time > Interval) 31 | { 32 | Force = ForceDir * RandomizedForceScale; 33 | Time = FMath::Fmod(Time, Interval); 34 | } 35 | else 36 | { 37 | Force = FVector::ZeroVector; 38 | } 39 | } 40 | else 41 | { 42 | Force = ForceDir * RandomizedForceScale; 43 | } 44 | 45 | if (ExternalForceSpace == EExternalForceSpace::WorldSpace) 46 | { 47 | Force = ComponentTransform.InverseTransformVector(Force); 48 | } 49 | } 50 | 51 | void FKawaiiPhysics_ExternalForce_Basic::Apply(FKawaiiPhysicsModifyBone& Bone, FAnimNode_KawaiiPhysics& Node, 52 | const FComponentSpacePoseContext& PoseContext, const FTransform& BoneTM) 53 | { 54 | if (!CanApply(Bone)) 55 | { 56 | return; 57 | } 58 | 59 | SCOPE_CYCLE_COUNTER(STAT_KawaiiPhysics_ExternalForce_Basic_Apply); 60 | 61 | float ForceRate = 1.0f; 62 | if (const auto Curve = ForceRateByBoneLengthRate.GetRichCurve(); !Curve->IsEmpty()) 63 | { 64 | ForceRate = Curve->Eval(Bone.LengthRateFromRoot); 65 | } 66 | 67 | if (ExternalForceSpace == EExternalForceSpace::BoneSpace) 68 | { 69 | const FVector BoneForce = BoneTM.TransformVector(Force); 70 | Bone.Location += BoneForce * ForceRate * Node.DeltaTime; 71 | 72 | #if ENABLE_ANIM_DEBUG 73 | BoneForceMap.Add(Bone.BoneRef.BoneName, BoneForce); 74 | #endif 75 | } 76 | else 77 | { 78 | Bone.Location += Force * ForceRate * Node.DeltaTime; 79 | 80 | #if ENABLE_ANIM_DEBUG 81 | BoneForceMap.Add(Bone.BoneRef.BoneName, Force * ForceRate); 82 | #endif 83 | } 84 | } 85 | 86 | /// 87 | /// Gravity 88 | /// 89 | void FKawaiiPhysics_ExternalForce_Gravity::PreApply(FAnimNode_KawaiiPhysics& Node, 90 | const USkeletalMeshComponent* SkelComp) 91 | { 92 | Super::PreApply(Node, SkelComp); 93 | 94 | Force = bUseOverrideGravityDirection ? OverrideGravityDirection : FVector(0, 0, -1.0f); 95 | 96 | // For Character's Custom Gravity Direction 97 | if (const ACharacter* Character = Cast(SkelComp->GetOwner())) 98 | { 99 | #if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 3 100 | if (bUseCharacterGravityDirection) 101 | { 102 | Force = Character->GetGravityDirection(); 103 | } 104 | #endif 105 | 106 | if (bUseCharacterGravityScale) 107 | { 108 | if (const UCharacterMovementComponent* CharacterMovementComponent = Character-> 109 | GetCharacterMovement()) 110 | { 111 | Force *= CharacterMovementComponent->GetGravityZ(); 112 | } 113 | } 114 | } 115 | 116 | Force *= RandomizedForceScale; 117 | Force = ComponentTransform.InverseTransformVector(Force); 118 | } 119 | 120 | void FKawaiiPhysics_ExternalForce_Gravity::Apply(FKawaiiPhysicsModifyBone& Bone, FAnimNode_KawaiiPhysics& Node, 121 | const FComponentSpacePoseContext& PoseContext, 122 | const FTransform& BoneTM) 123 | { 124 | if (!CanApply(Bone)) 125 | { 126 | return; 127 | } 128 | 129 | SCOPE_CYCLE_COUNTER(STAT_KawaiiPhysics_ExternalForce_Gravity_Apply); 130 | 131 | float ForceRate = 1.0f; 132 | if (const auto Curve = ForceRateByBoneLengthRate.GetRichCurve(); !Curve->IsEmpty()) 133 | { 134 | ForceRate = Curve->Eval(Bone.LengthRateFromRoot); 135 | } 136 | 137 | Bone.Location += 0.5f * Force * ForceRate * Node.DeltaTime * Node.DeltaTime; 138 | 139 | #if ENABLE_ANIM_DEBUG 140 | BoneForceMap.Add(Bone.BoneRef.BoneName, Force * ForceRate); 141 | AnimDrawDebug(Bone, Node, PoseContext); 142 | #endif 143 | } 144 | 145 | /// 146 | /// Curve 147 | /// 148 | void FKawaiiPhysics_ExternalForce_Curve::InitMaxCurveTime() 149 | { 150 | if (const FRichCurve* CurveX = ForceCurve.GetRichCurve(0); CurveX && !CurveX->IsEmpty()) 151 | { 152 | MaxCurveTime = FMath::Max(MaxCurveTime, CurveX->GetLastKey().Time); 153 | } 154 | if (const FRichCurve* CurveY = ForceCurve.GetRichCurve(1); CurveY && !CurveY->IsEmpty()) 155 | { 156 | MaxCurveTime = FMath::Max(MaxCurveTime, CurveY->GetLastKey().Time); 157 | } 158 | if (const FRichCurve* CurveZ = ForceCurve.GetRichCurve(2); CurveZ && !CurveZ->IsEmpty()) 159 | { 160 | MaxCurveTime = FMath::Max(MaxCurveTime, CurveZ->GetLastKey().Time); 161 | } 162 | } 163 | 164 | void FKawaiiPhysics_ExternalForce_Curve::Initialize(const FAnimationInitializeContext& Context) 165 | { 166 | FKawaiiPhysics_ExternalForce::Initialize(Context); 167 | 168 | InitMaxCurveTime(); 169 | } 170 | 171 | void FKawaiiPhysics_ExternalForce_Curve::PreApply(FAnimNode_KawaiiPhysics& Node, const USkeletalMeshComponent* SkelComp) 172 | { 173 | Super::PreApply(Node, SkelComp); 174 | 175 | #if WITH_EDITOR 176 | InitMaxCurveTime(); 177 | #endif 178 | 179 | PrevTime = Time; 180 | 181 | if (CurveEvaluateType == EExternalForceCurveEvaluateType::Single) 182 | { 183 | Time += Node.DeltaTime * TimeScale; 184 | if (MaxCurveTime > 0 && Time > MaxCurveTime) 185 | { 186 | Time = FMath::Fmod(Time, MaxCurveTime); 187 | } 188 | Force = ForceCurve.GetValue(Time) * RandomizedForceScale; 189 | } 190 | else 191 | { 192 | TArray CurveValues; 193 | const float SubStep = Node.DeltaTime * TimeScale / SubstepCount; 194 | 195 | for (int i = 0; i < SubstepCount; ++i) 196 | { 197 | Time += SubStep; 198 | if (MaxCurveTime > 0 && Time > MaxCurveTime) 199 | { 200 | Time = FMath::Fmod(Time, MaxCurveTime); 201 | } 202 | CurveValues.Add(ForceCurve.GetValue(Time)); 203 | } 204 | 205 | Force = FVector::ZeroVector; 206 | switch (CurveEvaluateType) 207 | { 208 | case EExternalForceCurveEvaluateType::Average: 209 | for (const auto& CurveValue : CurveValues) 210 | { 211 | Force += CurveValue; 212 | } 213 | Force /= static_cast(SubstepCount); 214 | 215 | break; 216 | 217 | case EExternalForceCurveEvaluateType::Max: 218 | Force = FVector(FLT_MIN); 219 | for (const auto& CurveValue : CurveValues) 220 | { 221 | Force = FVector::Max(Force, CurveValue); 222 | } 223 | break; 224 | case EExternalForceCurveEvaluateType::Min: 225 | Force = FVector(FLT_MAX); 226 | for (const auto& CurveValue : CurveValues) 227 | { 228 | Force = FVector::Min(Force, CurveValue); 229 | } 230 | break; 231 | default: 232 | break; 233 | } 234 | 235 | Force *= RandomizedForceScale; 236 | } 237 | 238 | if (ExternalForceSpace == EExternalForceSpace::WorldSpace) 239 | { 240 | Force = ComponentTransform.InverseTransformVector(Force); 241 | } 242 | } 243 | 244 | void FKawaiiPhysics_ExternalForce_Curve::Apply(FKawaiiPhysicsModifyBone& Bone, FAnimNode_KawaiiPhysics& Node, 245 | const FComponentSpacePoseContext& PoseContext, const FTransform& BoneTM) 246 | { 247 | if (!CanApply(Bone)) 248 | { 249 | return; 250 | } 251 | 252 | SCOPE_CYCLE_COUNTER(STAT_KawaiiPhysics_ExternalForce_Curve_Apply); 253 | 254 | float ForceRate = 1.0f; 255 | if (const auto Curve = ForceRateByBoneLengthRate.GetRichCurve(); !Curve->IsEmpty()) 256 | { 257 | ForceRate = Curve->Eval(Bone.LengthRateFromRoot); 258 | } 259 | 260 | if (ExternalForceSpace == EExternalForceSpace::BoneSpace) 261 | { 262 | const FVector BoneForce = BoneTM.TransformVector(Force); 263 | Bone.Location += BoneForce * ForceRate * Node.DeltaTime; 264 | 265 | #if ENABLE_ANIM_DEBUG 266 | BoneForceMap.Add(Bone.BoneRef.BoneName, BoneForce * ForceRate); 267 | #endif 268 | } 269 | else 270 | { 271 | Bone.Location += Force * ForceRate * Node.DeltaTime; 272 | 273 | #if ENABLE_ANIM_DEBUG 274 | BoneForceMap.Add(Bone.BoneRef.BoneName, Force * ForceRate); 275 | #endif 276 | } 277 | 278 | #if ENABLE_ANIM_DEBUG 279 | AnimDrawDebug(Bone, Node, PoseContext); 280 | #endif 281 | } 282 | 283 | void FKawaiiPhysics_ExternalForce_Wind::PreApply(FAnimNode_KawaiiPhysics& Node, const USkeletalMeshComponent* SkelComp) 284 | { 285 | Super::PreApply(Node, SkelComp); 286 | 287 | World = SkelComp ? SkelComp->GetWorld() : nullptr; 288 | } 289 | 290 | void FKawaiiPhysics_ExternalForce_Wind::Apply(FKawaiiPhysicsModifyBone& Bone, FAnimNode_KawaiiPhysics& Node, 291 | const FComponentSpacePoseContext& PoseContext, const FTransform& BoneTM) 292 | { 293 | const FSceneInterface* Scene = World && World->Scene ? World->Scene : nullptr; 294 | if (!CanApply(Bone) || !Scene) 295 | { 296 | return; 297 | } 298 | 299 | SCOPE_CYCLE_COUNTER(STAT_KawaiiPhysics_ExternalForce_Wind_Apply); 300 | 301 | float ForceRate = 1.0f; 302 | if (const auto Curve = ForceRateByBoneLengthRate.GetRichCurve(); !Curve->IsEmpty()) 303 | { 304 | ForceRate = Curve->Eval(Bone.LengthRateFromRoot); 305 | } 306 | 307 | FVector WindDirection = FVector::ZeroVector; 308 | float WindSpeed, WindMinGust, WindMaxGust = 0.0f; 309 | Scene->GetWindParameters(ComponentTransform.TransformPosition(Bone.PoseLocation), WindDirection, 310 | WindSpeed, WindMinGust, WindMaxGust); 311 | WindDirection = ComponentTransform.InverseTransformVector(WindDirection); 312 | WindDirection *= WindSpeed; 313 | 314 | Bone.Location += WindDirection * ForceRate * RandomizedForceScale * Node.DeltaTime; 315 | 316 | #if ENABLE_ANIM_DEBUG 317 | BoneForceMap.Add(Bone.BoneRef.BoneName, WindDirection * ForceRate * RandomizedForceScale); 318 | AnimDrawDebug(Bone, Node, PoseContext); 319 | #endif 320 | } 321 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Private/KawaiiPhysicsLibrary.cpp: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #include "KawaiiPhysicsLibrary.h" 4 | 5 | #include "AnimNode_KawaiiPhysics.h" 6 | #include "BlueprintGameplayTagLibrary.h" 7 | #include "KawaiiPhysicsExternalForce.h" 8 | 9 | DEFINE_LOG_CATEGORY_STATIC(LogKawaiiPhysicsLibrary, Verbose, All); 10 | 11 | FKawaiiPhysicsReference UKawaiiPhysicsLibrary::ConvertToKawaiiPhysics(const FAnimNodeReference& Node, 12 | EAnimNodeReferenceConversionResult& Result) 13 | { 14 | return FAnimNodeReference::ConvertToType(Node, Result); 15 | } 16 | 17 | bool UKawaiiPhysicsLibrary::CollectKawaiiPhysicsNodes(TArray& Nodes, 18 | UAnimInstance* AnimInstance, 19 | const FGameplayTagContainer& FilterTags, bool bFilterExactMatch) 20 | { 21 | if (!ensure(AnimInstance && AnimInstance->GetClass())) 22 | { 23 | return false; 24 | } 25 | 26 | bool bResult = false; 27 | if (const IAnimClassInterface* AnimClassInterface = 28 | IAnimClassInterface::GetFromClass((AnimInstance->GetClass()))) 29 | { 30 | const TArray& AnimNodeProperties = AnimClassInterface->GetAnimNodeProperties(); 31 | for (int i = 0; i < AnimNodeProperties.Num(); ++i) 32 | { 33 | if (AnimNodeProperties[i]->Struct-> 34 | IsChildOf(FKawaiiPhysicsReference::FInternalNodeType::StaticStruct())) 35 | { 36 | EAnimNodeReferenceConversionResult Result; 37 | FKawaiiPhysicsReference KawaiiPhysicsReference = ConvertToKawaiiPhysics( 38 | FAnimNodeReference(AnimInstance, i), Result); 39 | 40 | if (Result == EAnimNodeReferenceConversionResult::Succeeded) 41 | { 42 | auto& Tag = KawaiiPhysicsReference.GetAnimNode().KawaiiPhysicsTag; 43 | if (FilterTags.IsEmpty() || UBlueprintGameplayTagLibrary::MatchesAnyTags( 44 | Tag, FilterTags, bFilterExactMatch)) 45 | { 46 | Nodes.Add(KawaiiPhysicsReference); 47 | bResult = true; 48 | } 49 | } 50 | } 51 | } 52 | } 53 | 54 | return bResult; 55 | } 56 | 57 | bool UKawaiiPhysicsLibrary::CollectKawaiiPhysicsNodes(TArray& Nodes, 58 | USkeletalMeshComponent* MeshComp, 59 | const FGameplayTagContainer& FilterTags, bool bFilterExactMatch) 60 | { 61 | if (!ensure(MeshComp)) 62 | { 63 | return false; 64 | } 65 | 66 | const int NodeNum = Nodes.Num(); 67 | 68 | if (UAnimInstance* AnimInstance = MeshComp->GetAnimInstance()) 69 | { 70 | CollectKawaiiPhysicsNodes(Nodes, AnimInstance, FilterTags, 71 | bFilterExactMatch); 72 | } 73 | 74 | const TArray& LinkedInstances = 75 | const_cast(MeshComp)->GetLinkedAnimInstances(); 76 | for (UAnimInstance* LinkedInstance : LinkedInstances) 77 | { 78 | CollectKawaiiPhysicsNodes(Nodes, LinkedInstance, FilterTags, 79 | bFilterExactMatch); 80 | } 81 | 82 | if (UAnimInstance* PostProcessAnimInstance = MeshComp->GetPostProcessInstance()) 83 | { 84 | CollectKawaiiPhysicsNodes(Nodes, PostProcessAnimInstance, FilterTags, 85 | bFilterExactMatch); 86 | } 87 | 88 | return NodeNum != Nodes.Num(); 89 | } 90 | 91 | FKawaiiPhysicsReference UKawaiiPhysicsLibrary::ResetDynamics(const FKawaiiPhysicsReference& KawaiiPhysics) 92 | { 93 | KawaiiPhysics.CallAnimNodeFunction( 94 | TEXT("ResetDynamics"), 95 | [](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 96 | { 97 | InKawaiiPhysics.ResetDynamics(ETeleportType::ResetPhysics); 98 | }); 99 | 100 | return KawaiiPhysics; 101 | } 102 | 103 | 104 | FKawaiiPhysicsReference UKawaiiPhysicsLibrary::SetRootBoneName(const FKawaiiPhysicsReference& KawaiiPhysics, 105 | FName& RootBoneName) 106 | { 107 | KawaiiPhysics.CallAnimNodeFunction( 108 | TEXT("SetRootBoneName"), 109 | [RootBoneName](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 110 | { 111 | InKawaiiPhysics.RootBone = FBoneReference(RootBoneName); 112 | }); 113 | 114 | return KawaiiPhysics; 115 | } 116 | 117 | FName UKawaiiPhysicsLibrary::GetRootBoneName(const FKawaiiPhysicsReference& KawaiiPhysics) 118 | { 119 | FName RootBoneName; 120 | 121 | KawaiiPhysics.CallAnimNodeFunction( 122 | TEXT("GetRootBoneName"), 123 | [&RootBoneName](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 124 | { 125 | RootBoneName = InKawaiiPhysics.RootBone.BoneName; 126 | }); 127 | 128 | return RootBoneName; 129 | } 130 | 131 | FKawaiiPhysicsReference UKawaiiPhysicsLibrary::SetExcludeBoneNames(const FKawaiiPhysicsReference& KawaiiPhysics, 132 | TArray& ExcludeBoneNames) 133 | { 134 | KawaiiPhysics.CallAnimNodeFunction( 135 | TEXT("SetExcludeBoneNames"), 136 | [&ExcludeBoneNames](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 137 | { 138 | InKawaiiPhysics.ExcludeBones.Empty(); 139 | for (auto& ExcludeBoneName : ExcludeBoneNames) 140 | { 141 | InKawaiiPhysics.ExcludeBones.Add(FBoneReference(ExcludeBoneName)); 142 | } 143 | }); 144 | 145 | return KawaiiPhysics; 146 | } 147 | 148 | TArray UKawaiiPhysicsLibrary::GetExcludeBoneNames(const FKawaiiPhysicsReference& KawaiiPhysics) 149 | { 150 | TArray ExcludeBoneNames; 151 | 152 | KawaiiPhysics.CallAnimNodeFunction( 153 | TEXT("GetExcludeBoneNames"), 154 | [&ExcludeBoneNames](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 155 | { 156 | for (auto& ExcludeBone : InKawaiiPhysics.ExcludeBones) 157 | { 158 | ExcludeBoneNames.Add(ExcludeBone.BoneName); 159 | } 160 | }); 161 | 162 | return ExcludeBoneNames; 163 | } 164 | 165 | FKawaiiPhysicsReference UKawaiiPhysicsLibrary::AddExternalForceWithExecResult( 166 | EKawaiiPhysicsAccessExternalForceResult& ExecResult, 167 | const FKawaiiPhysicsReference& KawaiiPhysics, 168 | FInstancedStruct& ExternalForce, UObject* Owner) 169 | { 170 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::NotValid; 171 | 172 | if (AddExternalForce(KawaiiPhysics, ExternalForce, Owner)) 173 | { 174 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::Valid; 175 | } 176 | 177 | return KawaiiPhysics; 178 | } 179 | 180 | bool UKawaiiPhysicsLibrary::AddExternalForce(const FKawaiiPhysicsReference& KawaiiPhysics, 181 | FInstancedStruct& ExternalForce, UObject* Owner, bool bIsOneShot) 182 | { 183 | bool bResult = false; 184 | 185 | if (ExternalForce.IsValid()) 186 | { 187 | if (auto* ExternalForcePtr = ExternalForce.GetMutablePtr()) 188 | { 189 | ExternalForcePtr->ExternalOwner = Owner; 190 | ExternalForcePtr->bIsOneShot = bIsOneShot; 191 | 192 | KawaiiPhysics.CallAnimNodeFunction( 193 | TEXT("AddExternalForce"), 194 | [&](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 195 | { 196 | InKawaiiPhysics.ExternalForces.Add(ExternalForce); 197 | }); 198 | 199 | bResult = true; 200 | } 201 | } 202 | 203 | return bResult; 204 | } 205 | 206 | bool UKawaiiPhysicsLibrary::AddExternalForcesToComponent(USkeletalMeshComponent* MeshComp, 207 | TArray& ExternalForces, 208 | UObject* Owner, 209 | FGameplayTagContainer& FilterTags, 210 | bool bFilterExactMatch, bool bIsOneShot) 211 | { 212 | bool bResult = false; 213 | 214 | TArray KawaiiPhysicsReferences; 215 | CollectKawaiiPhysicsNodes(KawaiiPhysicsReferences, MeshComp, FilterTags, bFilterExactMatch); 216 | for (auto& KawaiiPhysicsReference : KawaiiPhysicsReferences) 217 | { 218 | for (auto& AExternalForce : ExternalForces) 219 | { 220 | if (AExternalForce.IsValid()) 221 | { 222 | if (AddExternalForce(KawaiiPhysicsReference, AExternalForce, Owner, bIsOneShot)) 223 | { 224 | bResult = true; 225 | } 226 | } 227 | } 228 | } 229 | 230 | return bResult; 231 | } 232 | 233 | bool UKawaiiPhysicsLibrary::RemoveExternalForcesFromComponent(USkeletalMeshComponent* MeshComp, UObject* Owner, 234 | FGameplayTagContainer& FilterTags, bool bFilterExactMatch) 235 | { 236 | bool bResult = false; 237 | 238 | TArray KawaiiPhysicsReferences; 239 | CollectKawaiiPhysicsNodes(KawaiiPhysicsReferences, MeshComp, FilterTags, bFilterExactMatch); 240 | for (auto& KawaiiPhysicsReference : KawaiiPhysicsReferences) 241 | { 242 | KawaiiPhysicsReference.CallAnimNodeFunction( 243 | TEXT("RemoveExternalForce"), 244 | [&](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 245 | { 246 | const int32 NumRemoved = InKawaiiPhysics.ExternalForces.RemoveAll([&](FInstancedStruct& InstancedStruct) 247 | { 248 | const auto* ExternalForcePtr = InstancedStruct.GetMutablePtr(); 249 | return ExternalForcePtr && ExternalForcePtr->ExternalOwner == Owner; 250 | }); 251 | 252 | if (NumRemoved > 0) 253 | { 254 | bResult = true; 255 | } 256 | }); 257 | } 258 | 259 | return bResult; 260 | } 261 | 262 | DEFINE_FUNCTION(UKawaiiPhysicsLibrary::execSetExternalForceWildcardProperty) 263 | { 264 | P_GET_ENUM_REF(EKawaiiPhysicsAccessExternalForceResult, ExecResult); 265 | P_GET_STRUCT_REF(FKawaiiPhysicsReference, KawaiiPhysics); 266 | P_GET_PROPERTY(FIntProperty, ExternalForceIndex); 267 | P_GET_STRUCT_REF(FName, PropertyName); 268 | 269 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::NotValid; 270 | 271 | // Read wildcard Value input. 272 | Stack.MostRecentPropertyAddress = nullptr; 273 | Stack.MostRecentPropertyContainer = nullptr; 274 | Stack.StepCompiledIn(nullptr); 275 | 276 | const FProperty* ValueProp = CastField(Stack.MostRecentProperty); 277 | void* ValuePtr = Stack.MostRecentPropertyAddress; 278 | 279 | KawaiiPhysics.CallAnimNodeFunction( 280 | TEXT("GetExternalForceWildcardProperty"), 281 | [&ExecResult, &ExternalForceIndex, &PropertyName, &ValuePtr](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 282 | { 283 | if (InKawaiiPhysics.ExternalForces.IsValidIndex(ExternalForceIndex) && 284 | InKawaiiPhysics.ExternalForces[ExternalForceIndex].IsValid()) 285 | { 286 | const auto* ScriptStruct = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetScriptStruct(); 287 | auto& Force = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetMutable< 288 | FKawaiiPhysics_ExternalForce>(); 289 | 290 | if (const FProperty* Property = FindFProperty(ScriptStruct, PropertyName)) 291 | { 292 | Property->CopyCompleteValue(Property->ContainerPtrToValuePtr(&Force), ValuePtr); 293 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::Valid; 294 | } 295 | } 296 | }); 297 | 298 | P_FINISH; 299 | } 300 | 301 | DEFINE_FUNCTION(UKawaiiPhysicsLibrary::execGetExternalForceWildcardProperty) 302 | { 303 | P_GET_ENUM_REF(EKawaiiPhysicsAccessExternalForceResult, ExecResult); 304 | P_GET_STRUCT_REF(FKawaiiPhysicsReference, KawaiiPhysics); 305 | P_GET_PROPERTY(FIntProperty, ExternalForceIndex); 306 | P_GET_STRUCT_REF(FName, PropertyName); 307 | 308 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::NotValid; 309 | 310 | // Read wildcard Value input. 311 | Stack.MostRecentPropertyAddress = nullptr; 312 | Stack.MostRecentPropertyContainer = nullptr; 313 | Stack.StepCompiledIn(nullptr); 314 | 315 | const FProperty* ValueProp = CastField(Stack.MostRecentProperty); 316 | void* ValuePtr = Stack.MostRecentPropertyAddress; 317 | 318 | void* Result = nullptr; 319 | KawaiiPhysics.CallAnimNodeFunction( 320 | TEXT("GetExternalForceWildcardProperty"), 321 | [&Result, &ExecResult, &ExternalForceIndex, &PropertyName](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 322 | { 323 | if (InKawaiiPhysics.ExternalForces.IsValidIndex(ExternalForceIndex) && 324 | InKawaiiPhysics.ExternalForces[ExternalForceIndex].IsValid()) 325 | { 326 | const auto* ScriptStruct = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetScriptStruct(); 327 | auto& Force = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetMutable< 328 | FKawaiiPhysics_ExternalForce>(); 329 | 330 | if (const FProperty* Property = FindFProperty(ScriptStruct, PropertyName)) 331 | { 332 | Result = Property->ContainerPtrToValuePtr(&Force); 333 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::Valid; 334 | } 335 | } 336 | }); 337 | 338 | P_FINISH; 339 | 340 | if (ValuePtr && Result) 341 | { 342 | P_NATIVE_BEGIN; 343 | ValueProp->CopyCompleteValue(ValuePtr, Result); 344 | P_NATIVE_END; 345 | } 346 | } 347 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Private/KawaiiPhysicsLimitsDataAsset.cpp: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | 4 | #include "KawaiiPhysicsLimitsDataAsset.h" 5 | #include "AnimNode_KawaiiPhysics.h" 6 | #include "KawaiiPhysics.h" 7 | 8 | DEFINE_LOG_CATEGORY(LogKawaiiPhysics); 9 | 10 | struct FCollisionLimitDataCustomVersion 11 | { 12 | enum Type 13 | { 14 | // FNameからFBoneReferenceに移行 15 | ChangeToBoneReference = 0, 16 | DeprecateLimitData, 17 | 18 | // ------------------------------------------------------ 19 | VersionPlusOne, 20 | LatestVersion = VersionPlusOne - 1 21 | }; 22 | 23 | // The GUID for this custom version number 24 | const static FGuid GUID; 25 | 26 | private: 27 | FCollisionLimitDataCustomVersion() 28 | { 29 | } 30 | }; 31 | 32 | const FGuid FCollisionLimitDataCustomVersion::GUID(0x3A1F7B2E, 0x7B9D6E8C, 0x4C2A9F1D, 0x85B3E4F1); 33 | FCustomVersionRegistration GRegisterCollisionLimitDataCustomVersion(FCollisionLimitDataCustomVersion::GUID, 34 | FCollisionLimitDataCustomVersion::LatestVersion, 35 | TEXT("CollisionLimitData")); 36 | 37 | #if WITH_EDITOR 38 | template 39 | void UpdateCollisionLimit(TArray& CollisionLimitsData, const CollisionLimitType& NewLimit) 40 | { 41 | for (auto& LimitData : CollisionLimitsData) 42 | { 43 | if (LimitData.Guid == NewLimit.Guid) 44 | { 45 | LimitData = NewLimit; 46 | break; 47 | } 48 | } 49 | } 50 | 51 | 52 | void UKawaiiPhysicsLimitsDataAsset::UpdateLimit(FCollisionLimitBase* Limit) 53 | { 54 | switch (Limit->Type) 55 | { 56 | case ECollisionLimitType::Spherical: 57 | UpdateCollisionLimit(SphericalLimits, *static_cast(Limit)); 58 | break; 59 | case ECollisionLimitType::Capsule: 60 | UpdateCollisionLimit(CapsuleLimits, *static_cast(Limit)); 61 | break; 62 | case ECollisionLimitType::Box: 63 | UpdateCollisionLimit(BoxLimits, *static_cast(Limit)); 64 | break; 65 | case ECollisionLimitType::Planar: 66 | UpdateCollisionLimit(PlanarLimits, *static_cast(Limit)); 67 | break; 68 | case ECollisionLimitType::None: 69 | break; 70 | default: 71 | break; 72 | } 73 | 74 | MarkPackageDirty(); 75 | } 76 | 77 | template 78 | void SyncCollisionLimits(const TArray& CollisionLimitData, 79 | TArray& CollisionLimits) 80 | { 81 | CollisionLimits.Empty(); 82 | for (const auto& Data : CollisionLimitData) 83 | { 84 | CollisionLimits.Add(Data.Convert()); 85 | } 86 | } 87 | 88 | void UKawaiiPhysicsLimitsDataAsset::Sync() 89 | { 90 | SyncCollisionLimits(SphericalLimitsData, SphericalLimits); 91 | SyncCollisionLimits(CapsuleLimitsData, CapsuleLimits); 92 | SyncCollisionLimits(BoxLimitsData, BoxLimits); 93 | SyncCollisionLimits(PlanarLimitsData, PlanarLimits); 94 | } 95 | 96 | void UKawaiiPhysicsLimitsDataAsset::PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) 97 | { 98 | Super::PostEditChangeChainProperty(PropertyChangedEvent); 99 | 100 | 101 | FName ArrayPropertyName = PropertyChangedEvent.MemberProperty 102 | ? PropertyChangedEvent.MemberProperty->GetFName() 103 | : NAME_None; 104 | if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ValueSet && 105 | PropertyChangedEvent.PropertyChain.GetActiveMemberNode()) 106 | { 107 | ArrayPropertyName = PropertyChangedEvent.PropertyChain.GetActiveMemberNode()->GetValue()->GetFName(); 108 | } 109 | 110 | auto UpdateLimits = [&](auto& Limits) 111 | { 112 | int32 ArrayIndex = PropertyChangedEvent.GetArrayIndex(ArrayPropertyName.ToString()); 113 | 114 | if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ArrayAdd || 115 | PropertyChangedEvent.ChangeType == EPropertyChangeType::ValueSet) 116 | { 117 | Limits[ArrayIndex].SourceType = ECollisionSourceType::DataAsset; 118 | } 119 | else if (PropertyChangedEvent.ChangeType == EPropertyChangeType::Duplicate) 120 | { 121 | Limits[ArrayIndex].Guid = FGuid::NewGuid(); 122 | } 123 | }; 124 | 125 | if (ArrayPropertyName == GET_MEMBER_NAME_CHECKED(UKawaiiPhysicsLimitsDataAsset, SphericalLimits)) 126 | { 127 | UpdateLimits(SphericalLimits); 128 | } 129 | else if (ArrayPropertyName == GET_MEMBER_NAME_CHECKED(UKawaiiPhysicsLimitsDataAsset, CapsuleLimits)) 130 | { 131 | UpdateLimits(CapsuleLimits); 132 | } 133 | else if (ArrayPropertyName == GET_MEMBER_NAME_CHECKED(UKawaiiPhysicsLimitsDataAsset, BoxLimits)) 134 | { 135 | UpdateLimits(BoxLimits); 136 | } 137 | else if (ArrayPropertyName == GET_MEMBER_NAME_CHECKED(UKawaiiPhysicsLimitsDataAsset, PlanarLimits)) 138 | { 139 | UpdateLimits(PlanarLimits); 140 | } 141 | 142 | OnLimitsChanged.Broadcast(PropertyChangedEvent); 143 | } 144 | #endif 145 | 146 | #if WITH_EDITORONLY_DATA 147 | void UKawaiiPhysicsLimitsDataAsset::Serialize(FStructuredArchiveRecord Record) 148 | { 149 | Super::Serialize(Record); 150 | 151 | Record.GetUnderlyingArchive().UsingCustomVersion(FCollisionLimitDataCustomVersion::GUID); 152 | } 153 | #endif 154 | 155 | USkeleton* UKawaiiPhysicsLimitsDataAsset::GetSkeleton(bool& bInvalidSkeletonIsError, 156 | const IPropertyHandle* PropertyHandle) 157 | { 158 | #if WITH_EDITORONLY_DATA 159 | return Skeleton; 160 | #else 161 | return nullptr; 162 | #endif 163 | } 164 | 165 | void UKawaiiPhysicsLimitsDataAsset::PostLoad() 166 | { 167 | Super::PostLoad(); 168 | 169 | if (GetLinkerCustomVersion(FCollisionLimitDataCustomVersion::GUID) < 170 | FCollisionLimitDataCustomVersion::ChangeToBoneReference) 171 | { 172 | #if WITH_EDITORONLY_DATA 173 | for (auto& Data : SphericalLimitsData) 174 | { 175 | Data.DrivingBoneReference = FBoneReference(Data.DrivingBoneName); 176 | } 177 | for (auto& Data : CapsuleLimitsData) 178 | { 179 | Data.DrivingBoneReference = FBoneReference(Data.DrivingBoneName); 180 | } 181 | for (auto& Data : BoxLimitsData) 182 | { 183 | Data.DrivingBoneReference = FBoneReference(Data.DrivingBoneName); 184 | } 185 | for (auto& Data : PlanarLimitsData) 186 | { 187 | Data.DrivingBoneReference = FBoneReference(Data.DrivingBoneName); 188 | } 189 | UE_LOG(LogKawaiiPhysics, Log, TEXT("Update : BoneName -> BoneReference (%s)"), *this->GetName()); 190 | #endif 191 | } 192 | 193 | if (GetLinkerCustomVersion(FCollisionLimitDataCustomVersion::GUID) < 194 | FCollisionLimitDataCustomVersion::DeprecateLimitData) 195 | { 196 | #if WITH_EDITORONLY_DATA 197 | Sync(); 198 | UE_LOG(LogKawaiiPhysics, Log, TEXT("Update : Deprecate LimitData (%s)"), *this->GetName()); 199 | #endif 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Public/KawaiiPhysics.h: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Modules/ModuleInterface.h" 7 | 8 | DECLARE_LOG_CATEGORY_EXTERN(LogKawaiiPhysics, Log, All); 9 | 10 | class FKawaiiPhysicsModule : public IModuleInterface 11 | { 12 | public: 13 | /** IModuleInterface implementation */ 14 | virtual void StartupModule() override; 15 | virtual void ShutdownModule() override; 16 | }; 17 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Public/KawaiiPhysicsBoneConstraintsDataAsset.h: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AnimNode_KawaiiPhysics.h" 7 | #include "Engine/DataAsset.h" 8 | #include "Interfaces/Interface_BoneReferenceSkeletonProvider.h" 9 | #include "KawaiiPhysicsBoneConstraintsDataAsset.generated.h" 10 | 11 | /** 12 | * Struct representing the data for modifying bone constraints in KawaiiPhysics. 13 | */ 14 | USTRUCT(BlueprintType) 15 | struct KAWAIIPHYSICS_API FModifyBoneConstraintData 16 | { 17 | GENERATED_BODY() 18 | 19 | /** Name of the first bone (deprecated) */ 20 | UPROPERTY() 21 | FName BoneName1; 22 | 23 | /** Name of the second bone (deprecated) */ 24 | UPROPERTY() 25 | FName BoneName2; 26 | 27 | /** Reference to the first bone */ 28 | UPROPERTY(EditAnywhere, category = "KawaiiPhysics") 29 | FBoneReference BoneReference1; 30 | 31 | /** Reference to the second bone */ 32 | UPROPERTY(EditAnywhere, category = "KawaiiPhysics") 33 | FBoneReference BoneReference2; 34 | 35 | /** Whether to override the compliance type */ 36 | UPROPERTY(EditAnywhere, category = "KawaiiPhysics", meta=(InlineEditConditionToggle)) 37 | bool bOverrideCompliance = false; 38 | 39 | /** The compliance type to use if overriding */ 40 | UPROPERTY(EditAnywhere, category = "KawaiiPhysics", meta=(EditCondition="bOverrideCompliance")) 41 | EXPBDComplianceType ComplianceType = EXPBDComplianceType::Leather; 42 | 43 | /** 44 | * Updates the bone constraint data with the given constraint. 45 | * @param BoneConstraint The bone constraint to update from. 46 | */ 47 | void Update(const FModifyBoneConstraint& BoneConstraint); 48 | }; 49 | 50 | /** 51 | * Struct representing a set of regex patterns for bones in KawaiiPhysics. 52 | */ 53 | USTRUCT(BlueprintType) 54 | struct FRegexPatternBoneSet 55 | { 56 | GENERATED_BODY() 57 | 58 | /** Regex pattern for the first bone */ 59 | UPROPERTY(EditAnywhere, Category="Helper") 60 | FString RegexPatternBone1; 61 | 62 | /** Regex pattern for the second bone */ 63 | UPROPERTY(EditAnywhere, Category="Helper") 64 | FString RegexPatternBone2; 65 | }; 66 | 67 | 68 | /** 69 | * Data asset for managing bone constraints in KawaiiPhysics. 70 | */ 71 | UCLASS(Blueprintable) 72 | class KAWAIIPHYSICS_API UKawaiiPhysicsBoneConstraintsDataAsset : public UDataAsset, 73 | public IBoneReferenceSkeletonProvider 74 | { 75 | GENERATED_BODY() 76 | 77 | public: 78 | /** Array of bone constraint data */ 79 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Bone Constraint (Experimental)", 80 | meta=(TitleProperty="{BoneReference1} - {BoneReference2}")) 81 | TArray BoneConstraintsData; 82 | 83 | #if WITH_EDITORONLY_DATA 84 | 85 | /** List of regex patterns for bones */ 86 | UPROPERTY(EditAnywhere, Category="Helper") 87 | TArray RegexPatternList; 88 | 89 | /** Preview skeleton for editor */ 90 | UPROPERTY(EditAnywhere, Category = "Skeleton") 91 | TSoftObjectPtr PreviewSkeleton; 92 | 93 | /** List of preview bones */ 94 | UPROPERTY(VisibleAnywhere, Category = "Skeleton", meta= (EditCondition=false)) 95 | TArray PreviewBoneList; 96 | 97 | /** String representation of the preview bone list */ 98 | UPROPERTY() 99 | FString PreviewBoneListString; 100 | #endif 101 | 102 | // Begin UObject Interface. 103 | virtual void Serialize(FStructuredArchiveRecord Record) override; 104 | virtual void PostLoad() override; 105 | // End UObject Interface. 106 | 107 | // IBoneReferenceSkeletonProvider interface 108 | virtual USkeleton* GetSkeleton(bool& bInvalidSkeletonIsError, const IPropertyHandle* PropertyHandle) override; 109 | 110 | /** Generates bone constraints based on the current data */ 111 | TArray GenerateBoneConstraints(); 112 | 113 | #if WITH_EDITOR 114 | 115 | /** Applies regex patterns to the bone constraints */ 116 | UFUNCTION(BlueprintCallable, CallInEditor, Category="Helper") 117 | void ApplyRegex(); 118 | 119 | /** Updates the preview bone list */ 120 | void UpdatePreviewBoneList(); 121 | 122 | /** Handles property changes in the editor */ 123 | virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override; 124 | #endif 125 | }; 126 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Public/KawaiiPhysicsCustomExternalForce.h: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #pragma once 4 | #include "AnimNode_KawaiiPhysics.h" 5 | #include "Curves/CurveVector.h" 6 | #include "KawaiiPhysicsCustomExternalForce.generated.h" 7 | 8 | 9 | UCLASS(Abstract, Blueprintable, EditInlineNew, CollapseCategories) 10 | class KAWAIIPHYSICS_API UKawaiiPhysics_CustomExternalForce : public UObject 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(DisplayPriority=1), Category="KawaiiPhysics|CustomExternalForce") 16 | bool bIsEnabled = true; 17 | 18 | UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(DisplayPriority=1), Category="KawaiiPhysics|CustomExternalForce") 19 | bool bDrawDebug = false; 20 | 21 | public: 22 | UFUNCTION(BlueprintNativeEvent) 23 | void PreApply(UPARAM(ref) FAnimNode_KawaiiPhysics& Node, 24 | const USkeletalMeshComponent* SkelComp); 25 | 26 | virtual void PreApply_Implementation( 27 | UPARAM(ref) FAnimNode_KawaiiPhysics& Node, const USkeletalMeshComponent* SkelComp)PURE_VIRTUAL(,); 28 | 29 | UFUNCTION(BlueprintNativeEvent) 30 | void Apply(UPARAM(ref) FAnimNode_KawaiiPhysics& Node, int32 ModifyBoneIndex, 31 | const USkeletalMeshComponent* SkelComp, const FTransform& BoneTransform); 32 | 33 | virtual void Apply_Implementation( 34 | UPARAM(ref) FAnimNode_KawaiiPhysics& Node, int32 ModifyBoneIndex, const USkeletalMeshComponent* SkelComp, 35 | const FTransform& BoneTransform) 36 | { 37 | } 38 | 39 | UFUNCTION(BlueprintCallable, Category="KawaiiPhysics|CustomExternalForce") 40 | virtual bool IsDebugEnabled() 41 | { 42 | #if ENABLE_ANIM_DEBUG 43 | if (CVarAnimNodeKawaiiPhysicsDebug.GetValueOnAnyThread()) 44 | { 45 | return bDrawDebug; 46 | } 47 | #endif 48 | 49 | return false; 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Public/KawaiiPhysicsExternalForce.h: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #pragma once 4 | #include "AnimNode_KawaiiPhysics.h" 5 | #include "SceneManagement.h" 6 | #include "Curves/CurveVector.h" 7 | #include "KawaiiPhysicsExternalForce.generated.h" 8 | 9 | /** 10 | * Enum representing the space in which external forces are simulated. 11 | */ 12 | UENUM(BlueprintType) 13 | enum class EExternalForceSpace : uint8 14 | { 15 | /** Simulate in component space. Moving the entire skeletal mesh will have no affect on velocities */ 16 | ComponentSpace, 17 | /** Simulate in world space. Moving the skeletal mesh will generate velocity changes */ 18 | WorldSpace, 19 | /** Simulate in another bone space. Moving the entire skeletal mesh and individually modifying the base bone will have no affect on velocities */ 20 | BoneSpace, 21 | }; 22 | 23 | /** 24 | * Enum representing the evaluation type for external force curves. 25 | */ 26 | UENUM(BlueprintType) 27 | enum class EExternalForceCurveEvaluateType : uint8 28 | { 29 | /** Evaluate the curve at a single point */ 30 | Single, 31 | /** Evaluate the curve by averaging multiple points */ 32 | Average, 33 | /** Evaluate the curve by taking the maximum value from multiple points */ 34 | Max, 35 | /** Evaluate the curve by taking the minimum value from multiple points */ 36 | Min 37 | }; 38 | 39 | 40 | /// 41 | /// Base 42 | /// 43 | USTRUCT(BlueprintType) 44 | struct KAWAIIPHYSICS_API FKawaiiPhysics_ExternalForce 45 | { 46 | GENERATED_BODY() 47 | 48 | /** Whether the external force is enabled */ 49 | UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(DisplayPriority=1), Category="KawaiiPhysics|ExternalForce") 50 | bool bIsEnabled = true; 51 | 52 | /** Whether to draw debug information for the external force */ 53 | UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(DisplayPriority=1), Category="KawaiiPhysics|ExternalForce") 54 | bool bDrawDebug = false; 55 | 56 | /** 57 | * 外力を適応するボーンを指定(=指定しなかったボーンには適応しない) 58 | * Specify the bones to which the external force will be applied (= the force will not be applied to bones that are not specified) 59 | */ 60 | UPROPERTY(EditAnywhere, meta=(DisplayPriority=1), Category="KawaiiPhysics|ExternalForce") 61 | TArray ApplyBoneFilter; 62 | 63 | /** 64 | * 外力を適応しないボーンを指定 65 | * Specify the bones to which the external force will be NOT applied 66 | */ 67 | UPROPERTY(EditAnywhere, meta=(DisplayPriority=1), Category="KawaiiPhysics|ExternalForce") 68 | TArray IgnoreBoneFilter; 69 | 70 | /** The space in which the external force is simulated */ 71 | UPROPERTY(EditAnywhere, meta=(DisplayPriority=1, EditCondition=bCanSelectForceSpace, EditConditionHides), 72 | Category="KawaiiPhysics|ExternalForce") 73 | EExternalForceSpace ExternalForceSpace = EExternalForceSpace::WorldSpace; 74 | 75 | /** Range for randomizing the force scale */ 76 | UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(DisplayPriority=1), Category="KawaiiPhysics|ExternalForce") 77 | FFloatInterval RandomForceScaleRange = FFloatInterval(1.0f, 1.0f); 78 | 79 | /** Owner of the external force */ 80 | UPROPERTY() 81 | TObjectPtr ExternalOwner; 82 | 83 | /** Whether the external force is applied only once */ 84 | UPROPERTY() 85 | bool bIsOneShot = false; 86 | 87 | #if ENABLE_ANIM_DEBUG 88 | /** Length of the debug arrow */ 89 | float DebugArrowLength = 5.0f; 90 | 91 | /** Size of the debug arrow */ 92 | float DebugArrowSize = 1.0f; 93 | 94 | /** Offset for the debug arrow */ 95 | FVector DebugArrowOffset = FVector::Zero(); 96 | 97 | /** Map of bone names to forces for debugging */ 98 | TMap BoneForceMap; 99 | #endif 100 | 101 | protected: 102 | /** Randomized scale of the force */ 103 | UPROPERTY() 104 | float RandomizedForceScale = 0.0f; 105 | 106 | /** The force vector */ 107 | UPROPERTY() 108 | FVector Force = FVector::Zero(); 109 | 110 | /** Transform of the component */ 111 | UPROPERTY() 112 | FTransform ComponentTransform; 113 | 114 | /** Whether the force space can be selected */ 115 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="KawaiiPhysics|ExternalForce") 116 | bool bCanSelectForceSpace = true; 117 | 118 | public: 119 | virtual ~FKawaiiPhysics_ExternalForce() = default; 120 | 121 | virtual void Initialize(const FAnimationInitializeContext& Context) 122 | { 123 | } 124 | 125 | /** Prepares the external force before applying it */ 126 | virtual void PreApply(FAnimNode_KawaiiPhysics& Node, const USkeletalMeshComponent* SkelComp) 127 | { 128 | ComponentTransform = SkelComp->GetComponentTransform(); 129 | RandomizedForceScale = FMath::RandRange(RandomForceScaleRange.Min, RandomForceScaleRange.Max); 130 | } 131 | 132 | /** Applies the external force to a bone */ 133 | virtual void Apply(FKawaiiPhysicsModifyBone& Bone, FAnimNode_KawaiiPhysics& Node, 134 | const FComponentSpacePoseContext& PoseContext, const FTransform& BoneTM = FTransform::Identity) 135 | { 136 | } 137 | 138 | /** Finalizes the external force after applying it */ 139 | virtual void PostApply(FAnimNode_KawaiiPhysics& Node) 140 | { 141 | if (bIsOneShot) 142 | { 143 | Node.ExternalForces.RemoveAll([&](FInstancedStruct& InstancedStruct) 144 | { 145 | const auto* ExternalForcePtr = InstancedStruct.GetMutablePtr(); 146 | return ExternalForcePtr == this; 147 | }); 148 | } 149 | } 150 | 151 | /** Checks if debug information should be drawn */ 152 | virtual bool IsDebugEnabled(bool bInPersona = false) 153 | { 154 | if (bInPersona) 155 | { 156 | return bDrawDebug && bIsEnabled; 157 | } 158 | 159 | #if ENABLE_ANIM_DEBUG 160 | if (CVarAnimNodeKawaiiPhysicsDebug.GetValueOnAnyThread()) 161 | { 162 | return bDrawDebug && bIsEnabled; 163 | } 164 | #endif 165 | 166 | return false; 167 | } 168 | 169 | #if ENABLE_ANIM_DEBUG 170 | /** Draws debug information for the external force */ 171 | virtual void AnimDrawDebug(FKawaiiPhysicsModifyBone& Bone, FAnimNode_KawaiiPhysics& Node, 172 | const FComponentSpacePoseContext& PoseContext) 173 | { 174 | if (IsDebugEnabled() && !Force.IsZero()) 175 | { 176 | const auto AnimInstanceProxy = PoseContext.AnimInstanceProxy; 177 | const FVector ModifyRootBoneLocationWS = AnimInstanceProxy->GetComponentTransform().TransformPosition( 178 | Bone.Location); 179 | 180 | AnimInstanceProxy->AnimDrawDebugDirectionalArrow( 181 | ModifyRootBoneLocationWS + DebugArrowOffset, 182 | ModifyRootBoneLocationWS + DebugArrowOffset + BoneForceMap.Find(Bone.BoneRef.BoneName)->GetSafeNormal() 183 | * 184 | DebugArrowLength, 185 | DebugArrowSize, FColor::Red, false, 0.f, 2); 186 | } 187 | } 188 | #endif 189 | 190 | #if WITH_EDITOR 191 | /** Draws debug information for the external force in edit mode */ 192 | virtual void AnimDrawDebugForEditMode(const FKawaiiPhysicsModifyBone& ModifyBone, 193 | const FAnimNode_KawaiiPhysics& Node, FPrimitiveDrawInterface* PDI) 194 | { 195 | if (IsDebugEnabled(true) && CanApply(ModifyBone) && !Force.IsNearlyZero() && BoneForceMap.Contains( 196 | ModifyBone.BoneRef.BoneName)) 197 | { 198 | const FTransform ArrowTransform = FTransform( 199 | BoneForceMap.Find(ModifyBone.BoneRef.BoneName)->GetSafeNormal().ToOrientationRotator(), 200 | ModifyBone.Location + DebugArrowOffset); 201 | DrawDirectionalArrow(PDI, ArrowTransform.ToMatrixNoScale(), FColor::Red, DebugArrowLength, DebugArrowSize, 202 | SDPG_Foreground, 1.0f); 203 | } 204 | } 205 | #endif 206 | 207 | protected: 208 | /** Checks if the external force can be applied to a bone */ 209 | bool CanApply(const FKawaiiPhysicsModifyBone& Bone) const 210 | { 211 | if (!ApplyBoneFilter.IsEmpty() && !ApplyBoneFilter.Contains(Bone.BoneRef)) 212 | { 213 | return false; 214 | } 215 | 216 | if (!IgnoreBoneFilter.IsEmpty() && IgnoreBoneFilter.Contains(Bone.BoneRef)) 217 | { 218 | return false; 219 | } 220 | 221 | return true; 222 | } 223 | }; 224 | 225 | /// 226 | /// Basic 227 | /// 228 | USTRUCT(BlueprintType, DisplayName = "Basic") 229 | struct KAWAIIPHYSICS_API FKawaiiPhysics_ExternalForce_Basic : public FKawaiiPhysics_ExternalForce 230 | { 231 | GENERATED_BODY() 232 | 233 | /** Direction of the force */ 234 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="KawaiiPhysics|ExternalForce") 235 | FVector ForceDir = FVector::Zero(); 236 | 237 | /** 238 | * 各ボーンに適用するForce Rateを補正。 239 | * 「RootBoneから特定のボーンまでの長さ / RootBoneから末端のボーンまでの長さ」(0.0~1.0)の値におけるカーブの値をForceRateに乗算 240 | * Corrects the Force Rate applied to each bone. 241 | * Multiplies the ForceRate by the curve value for "Length from RootBone to specific bone / Length from RootBone to end bone" (0.0~1.0) 242 | */ 243 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="KawaiiPhysics|ExternalForce") 244 | FRuntimeFloatCurve ForceRateByBoneLengthRate; 245 | 246 | /** Interval for applying the force */ 247 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="KawaiiPhysics|ExternalForce") 248 | float Interval = 0.0f; 249 | 250 | virtual void PreApply(FAnimNode_KawaiiPhysics& Node, const USkeletalMeshComponent* SkelComp) override; 251 | virtual void Apply(FKawaiiPhysicsModifyBone& Bone, FAnimNode_KawaiiPhysics& Node, 252 | const FComponentSpacePoseContext& PoseContext, 253 | const FTransform& BoneTM = FTransform::Identity) override; 254 | 255 | private: 256 | /** Current time */ 257 | UPROPERTY() 258 | float Time = 0.0f; 259 | 260 | /** Previous time */ 261 | UPROPERTY() 262 | float PrevTime = 0.0f; 263 | }; 264 | 265 | /// 266 | /// Gravity 267 | /// 268 | USTRUCT(BlueprintType, DisplayName = "Gravity") 269 | struct KAWAIIPHYSICS_API FKawaiiPhysics_ExternalForce_Gravity : public FKawaiiPhysics_ExternalForce 270 | { 271 | GENERATED_BODY() 272 | 273 | FKawaiiPhysics_ExternalForce_Gravity() 274 | { 275 | bCanSelectForceSpace = false; 276 | ExternalForceSpace = EExternalForceSpace::WorldSpace; 277 | } 278 | 279 | /** 280 | * 各ボーンに適用するForce Rateを補正。 281 | * 「RootBoneから特定のボーンまでの長さ / RootBoneから末端のボーンまでの長さ」(0.0~1.0)の値におけるカーブの値をForceRateに乗算 282 | * Corrects the Force Rate applied to each bone. 283 | * Multiplies the ForceRate by the curve value for "Length from RootBone to specific bone / Length from RootBone to end bone" (0.0~1.0) 284 | */ 285 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="KawaiiPhysics|ExternalForce") 286 | FRuntimeFloatCurve ForceRateByBoneLengthRate; 287 | 288 | /** 289 | * Character側で設定されたCustomGravityDirectionを使用するフラグ(UE5.4以降) 290 | * Flag to use CustomGravityDirection set on the Character side (UE5.4 and later) 291 | */ 292 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="KawaiiPhysics|ExternalForce") 293 | bool bUseCharacterGravityDirection = false; 294 | 295 | /** 296 | * Character側で設定されたGravityScaleを使用するフラグ 297 | * Flag to use GravityScale set on the Character side 298 | */ 299 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="KawaiiPhysics|ExternalForce") 300 | bool bUseCharacterGravityScale = false; 301 | 302 | /** 303 | * Direction to override the gravity. 304 | * This direction is used when bUseOverrideGravityDirection is true. 305 | */ 306 | UPROPERTY(EditAnywhere, BlueprintReadWrite, 307 | meta = (EditCondition = "bUseOverrideGravityDirection"), Category="KawaiiPhysics|ExternalForce") 308 | FVector OverrideGravityDirection = FVector::Zero(); 309 | 310 | /** 311 | * Flag to determine whether to use the override gravity direction. 312 | * If true, the gravity direction will be overridden by OverrideGravityDirection. 313 | */ 314 | UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (InlineEditConditionToggle), 315 | Category="KawaiiPhysics|ExternalForce") 316 | bool bUseOverrideGravityDirection = false; 317 | 318 | virtual void PreApply(FAnimNode_KawaiiPhysics& Node, const USkeletalMeshComponent* SkelComp) override; 319 | virtual void Apply(FKawaiiPhysicsModifyBone& Bone, FAnimNode_KawaiiPhysics& Node, 320 | const FComponentSpacePoseContext& PoseContext, 321 | const FTransform& BoneTM = FTransform::Identity) override; 322 | }; 323 | 324 | /// 325 | /// Curve 326 | /// 327 | USTRUCT(BlueprintType, DisplayName = "Curve") 328 | struct KAWAIIPHYSICS_API FKawaiiPhysics_ExternalForce_Curve : public FKawaiiPhysics_ExternalForce 329 | { 330 | GENERATED_BODY() 331 | 332 | /** 333 | * 時間に応じて変化する外力をカーブで設定。X軸:Time Y軸:Force 334 | * Set the external force that changes over time using a curve. X-axis: Time Y-axis: Force 335 | */ 336 | UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (XAxisName="Time", YAxisName="Force"), 337 | Category="KawaiiPhysics|ExternalForce") 338 | FRuntimeVectorCurve ForceCurve; 339 | 340 | /** 341 | * カーブの評価方式。 342 | * Single以外に設定した場合:前フレームからの経過時間をSubstepCountで分割し、 343 | * 分割後の各時間におけるカーブの値の平均・最大値・最小値を外力として使用 344 | * Curve evaluation method 345 | * If set to anything other than Single: The time elapsed from the previous frame is divided by SubstepCount, 346 | * and the Average, Maximum, or Minimum values of the curve at each time point after division are used as external forces. 347 | */ 348 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="KawaiiPhysics|ExternalForce") 349 | EExternalForceCurveEvaluateType CurveEvaluateType = EExternalForceCurveEvaluateType::Single; 350 | 351 | /** 352 | * 経過時間の分割数 353 | * Number of divisions of elapsed time 354 | */ 355 | UPROPERTY(EditAnywhere, BlueprintReadWrite, 356 | meta=(EditCondition="CurveEvaluateType!=EExternalForceCurveEvaluateType::Single"), 357 | Category="KawaiiPhysics|ExternalForce") 358 | int SubstepCount = 10; 359 | 360 | /** 361 | * Scale factor for the time. 362 | * This value is used to scale the time for the external force. 363 | */ 364 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category ="KawaiiPhysics|ExternalForce") 365 | float TimeScale = 1.0f; 366 | 367 | /** 368 | * 各ボーンに適用するForce Rateを補正。 369 | * 「RootBoneから特定のボーンまでの長さ / RootBoneから末端のボーンまでの長さ」(0.0~1.0)の値におけるカーブの値をForceRateに乗算 370 | * Corrects the Force Rate applied to each bone. 371 | * Multiplies the ForceRate by the curve value for "Length from RootBone to specific bone / Length from RootBone to end bone" (0.0~1.0) 372 | */ 373 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="KawaiiPhysics|ExternalForce") 374 | FRuntimeFloatCurve ForceRateByBoneLengthRate; 375 | 376 | private: 377 | /** 378 | * Current time. 379 | * This value is used to track the current time for the external force. 380 | */ 381 | UPROPERTY() 382 | float Time = 0.0f; 383 | 384 | /** 385 | * Previous time. 386 | * This value is used to track the previous time for the external force. 387 | */ 388 | UPROPERTY() 389 | float PrevTime = 0.0f; 390 | 391 | /** 392 | * Maximum curve time. 393 | * This value is used to track the maximum time for the force curve. 394 | */ 395 | UPROPERTY() 396 | float MaxCurveTime = 0.0f; 397 | 398 | public: 399 | /** 400 | * Initializes the maximum curve time. 401 | * This function calculates the maximum time value from the ForceCurve and sets it to MaxCurveTime. 402 | */ 403 | void InitMaxCurveTime(); 404 | 405 | virtual void Initialize(const FAnimationInitializeContext& Context) override; 406 | virtual void PreApply(FAnimNode_KawaiiPhysics& Node, const USkeletalMeshComponent* SkelComp) override; 407 | virtual void Apply(FKawaiiPhysicsModifyBone& Bone, FAnimNode_KawaiiPhysics& Node, 408 | const FComponentSpacePoseContext& PoseContext, 409 | const FTransform& BoneTM = FTransform::Identity) override; 410 | }; 411 | 412 | /// 413 | /// Wind 414 | /// 415 | USTRUCT(BlueprintType, DisplayName = "Wind") 416 | struct KAWAIIPHYSICS_API FKawaiiPhysics_ExternalForce_Wind : public FKawaiiPhysics_ExternalForce 417 | { 418 | GENERATED_BODY() 419 | 420 | FKawaiiPhysics_ExternalForce_Wind() 421 | { 422 | bCanSelectForceSpace = false; 423 | ExternalForceSpace = EExternalForceSpace::WorldSpace; 424 | } 425 | 426 | /** 427 | * 各ボーンに適用するForce Rateを補正。 428 | * 「RootBoneから特定のボーンまでの長さ / RootBoneから末端のボーンまでの長さ」(0.0~1.0)の値におけるカーブの値をForceRateに乗算 429 | * Corrects the Force Rate applied to each bone. 430 | * Multiplies the ForceRate by the curve value for "Length from RootBone to specific bone / Length from RootBone to end bone" (0.0~1.0) 431 | */ 432 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="KawaiiPhysics|ExternalForce") 433 | FRuntimeFloatCurve ForceRateByBoneLengthRate; 434 | 435 | private: 436 | /** 437 | * Pointer to the world. 438 | * This is used to access the world context for the external force. 439 | */ 440 | UPROPERTY() 441 | TObjectPtr World; 442 | 443 | public: 444 | virtual void PreApply(FAnimNode_KawaiiPhysics& Node, const USkeletalMeshComponent* SkelComp) override; 445 | virtual void Apply(FKawaiiPhysicsModifyBone& Bone, FAnimNode_KawaiiPhysics& Node, 446 | const FComponentSpacePoseContext& PoseContext, 447 | const FTransform& BoneTM = FTransform::Identity) override; 448 | }; 449 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Public/KawaiiPhysicsLibrary.h: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AnimNode_KawaiiPhysics.h" 7 | #include "KawaiiPhysicsExternalForce.h" 8 | #include "Animation/AnimNodeReference.h" 9 | #include "Kismet/BlueprintFunctionLibrary.h" 10 | #include "KawaiiPhysicsLibrary.generated.h" 11 | 12 | UENUM() 13 | enum class EKawaiiPhysicsAccessExternalForceResult : uint8 14 | { 15 | Valid, 16 | NotValid, 17 | }; 18 | 19 | #define KAWAIIPHYSICS_VALUE_SETTER(PropertyType, PropertyName) \ 20 | { \ 21 | KawaiiPhysics.CallAnimNodeFunction( \ 22 | TEXT("Set" #PropertyName), \ 23 | [PropertyName](FAnimNode_KawaiiPhysics& InKawaiiPhysics) { \ 24 | InKawaiiPhysics.PropertyName = PropertyName; \ 25 | }); \ 26 | return KawaiiPhysics; \ 27 | } 28 | 29 | #define KAWAIIPHYSICS_VALUE_GETTER(PropertyType, PropertyName) \ 30 | { \ 31 | PropertyType Value; \ 32 | KawaiiPhysics.CallAnimNodeFunction( \ 33 | TEXT("Get" #PropertyName), \ 34 | [&Value](FAnimNode_KawaiiPhysics& InKawaiiPhysics) { \ 35 | Value = InKawaiiPhysics.PropertyName; \ 36 | }); \ 37 | return Value; \ 38 | } 39 | 40 | 41 | USTRUCT(BlueprintType) 42 | struct FKawaiiPhysicsReference : public FAnimNodeReference 43 | { 44 | GENERATED_BODY() 45 | 46 | using FInternalNodeType = FAnimNode_KawaiiPhysics; 47 | }; 48 | 49 | /** 50 | * Exposes operations to be performed on a blend space anim node. 51 | */ 52 | UCLASS() 53 | class KAWAIIPHYSICS_API UKawaiiPhysicsLibrary : public UBlueprintFunctionLibrary 54 | { 55 | GENERATED_BODY() 56 | 57 | public: 58 | /** Get a KawaiiPhysics from an anim node */ 59 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 60 | meta = (BlueprintThreadSafe, ExpandEnumAsExecs = "Result")) 61 | static FKawaiiPhysicsReference ConvertToKawaiiPhysics(const FAnimNodeReference& Node, 62 | EAnimNodeReferenceConversionResult& Result); 63 | 64 | /** Get a KawaiiPhysics from an anim node (pure). */ 65 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", 66 | meta = (BlueprintThreadSafe, DisplayName = "Convert to Kawaii Physics (Pure)")) 67 | static void ConvertToKawaiiPhysicsPure(const FAnimNodeReference& Node, FKawaiiPhysicsReference& KawaiiPhysics, 68 | bool& Result) 69 | { 70 | EAnimNodeReferenceConversionResult ConversionResult; 71 | KawaiiPhysics = ConvertToKawaiiPhysics(Node, ConversionResult); 72 | Result = (ConversionResult == EAnimNodeReferenceConversionResult::Succeeded); 73 | } 74 | 75 | /** Collect KawaiiPhysics Node References from AnimInstance(ABP) */ 76 | static bool CollectKawaiiPhysicsNodes(TArray& Nodes, 77 | UAnimInstance* AnimInstance, const FGameplayTagContainer& FilterTags, 78 | bool bFilterExactMatch); 79 | 80 | /** Collect KawaiiPhysics Node References from SkeletalMeshComponent */ 81 | static bool CollectKawaiiPhysicsNodes(TArray& Nodes, 82 | USkeletalMeshComponent* MeshComp, const FGameplayTagContainer& FilterTags, 83 | bool bFilterExactMatch); 84 | 85 | /** ResetDynamics */ 86 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 87 | static FKawaiiPhysicsReference ResetDynamics(const FKawaiiPhysicsReference& KawaiiPhysics); 88 | 89 | /** Set RootBone */ 90 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 91 | static FKawaiiPhysicsReference SetRootBoneName(const FKawaiiPhysicsReference& KawaiiPhysics, 92 | UPARAM(ref) FName& RootBoneName); 93 | /** Get RootBone */ 94 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 95 | static FName GetRootBoneName(const FKawaiiPhysicsReference& KawaiiPhysics); 96 | 97 | /** Set ExcludeBones */ 98 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 99 | static FKawaiiPhysicsReference SetExcludeBoneNames(const FKawaiiPhysicsReference& KawaiiPhysics, 100 | UPARAM(ref) TArray& ExcludeBoneNames); 101 | /** Get ExcludeBones */ 102 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 103 | static TArray GetExcludeBoneNames(const FKawaiiPhysicsReference& KawaiiPhysics); 104 | 105 | // PhysicsSettings 106 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 107 | static FKawaiiPhysicsReference SetPhysicsSettings(const FKawaiiPhysicsReference& KawaiiPhysics, 108 | UPARAM(ref) FKawaiiPhysicsSettings& PhysicsSettings) 109 | { 110 | KAWAIIPHYSICS_VALUE_SETTER(FKawaiiPhysicsSettings, PhysicsSettings); 111 | } 112 | 113 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 114 | static FKawaiiPhysicsSettings GetPhysicsSettings(const FKawaiiPhysicsReference& KawaiiPhysics) 115 | { 116 | KAWAIIPHYSICS_VALUE_GETTER(FKawaiiPhysicsSettings, PhysicsSettings); 117 | } 118 | 119 | // DummyBoneLength 120 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 121 | static FKawaiiPhysicsReference SetDummyBoneLength(const FKawaiiPhysicsReference& KawaiiPhysics, 122 | float DummyBoneLength) 123 | { 124 | KAWAIIPHYSICS_VALUE_SETTER(float, DummyBoneLength); 125 | } 126 | 127 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 128 | static float GetDummyBoneLength(const FKawaiiPhysicsReference& KawaiiPhysics) 129 | { 130 | KAWAIIPHYSICS_VALUE_GETTER(float, DummyBoneLength); 131 | } 132 | 133 | /** TeleportDistanceThreshold */ 134 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 135 | static FKawaiiPhysicsReference SetTeleportDistanceThreshold(const FKawaiiPhysicsReference& KawaiiPhysics, 136 | float TeleportDistanceThreshold) 137 | { 138 | KAWAIIPHYSICS_VALUE_SETTER(float, TeleportDistanceThreshold); 139 | } 140 | 141 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 142 | static float GetTeleportDistanceThreshold(const FKawaiiPhysicsReference& KawaiiPhysics) 143 | { 144 | KAWAIIPHYSICS_VALUE_GETTER(float, TeleportDistanceThreshold); 145 | } 146 | 147 | /** TeleportRotationThreshold */ 148 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 149 | static FKawaiiPhysicsReference SetTeleportRotationThreshold(const FKawaiiPhysicsReference& KawaiiPhysics, 150 | float TeleportRotationThreshold) 151 | { 152 | KAWAIIPHYSICS_VALUE_SETTER(float, TeleportRotationThreshold); 153 | } 154 | 155 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 156 | static float GetTeleportRotationThreshold(const FKawaiiPhysicsReference& KawaiiPhysics) 157 | { 158 | KAWAIIPHYSICS_VALUE_GETTER(float, TeleportRotationThreshold); 159 | } 160 | 161 | /** Gravity */ 162 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 163 | static FKawaiiPhysicsReference SetGravity(const FKawaiiPhysicsReference& KawaiiPhysics, FVector Gravity) 164 | { 165 | KAWAIIPHYSICS_VALUE_SETTER(FVector, Gravity); 166 | } 167 | 168 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 169 | static FVector GetGravity(const FKawaiiPhysicsReference& KawaiiPhysics) 170 | { 171 | KAWAIIPHYSICS_VALUE_GETTER(FVector, Gravity); 172 | } 173 | 174 | /** EnableWind */ 175 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 176 | static FKawaiiPhysicsReference SetEnableWind(const FKawaiiPhysicsReference& KawaiiPhysics, bool bEnableWind) 177 | { 178 | KAWAIIPHYSICS_VALUE_SETTER(bool, bEnableWind); 179 | } 180 | 181 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 182 | static bool GetEnableWind(const FKawaiiPhysicsReference& KawaiiPhysics) 183 | { 184 | KAWAIIPHYSICS_VALUE_GETTER(bool, bEnableWind); 185 | } 186 | 187 | /** WindScale */ 188 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 189 | static FKawaiiPhysicsReference SetWindScale(const FKawaiiPhysicsReference& KawaiiPhysics, float WindScale) 190 | { 191 | KAWAIIPHYSICS_VALUE_SETTER(float, WindScale); 192 | } 193 | 194 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 195 | static float GetWindScale(const FKawaiiPhysicsReference& KawaiiPhysics) 196 | { 197 | KAWAIIPHYSICS_VALUE_GETTER(float, WindScale); 198 | } 199 | 200 | /** AllowWorldCollision */ 201 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 202 | static FKawaiiPhysicsReference SetAllowWorldCollision(const FKawaiiPhysicsReference& KawaiiPhysics, 203 | bool bAllowWorldCollision) 204 | { 205 | KAWAIIPHYSICS_VALUE_SETTER(bool, bAllowWorldCollision); 206 | } 207 | 208 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 209 | static bool GetAllowWorldCollision(const FKawaiiPhysicsReference& KawaiiPhysics) 210 | { 211 | KAWAIIPHYSICS_VALUE_GETTER(bool, bAllowWorldCollision); 212 | } 213 | 214 | /** NeedWarmUp */ 215 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 216 | static FKawaiiPhysicsReference SetNeedWarmUp(const FKawaiiPhysicsReference& KawaiiPhysics, bool bNeedWarmUp) 217 | { 218 | KAWAIIPHYSICS_VALUE_SETTER(bool, bNeedWarmUp); 219 | } 220 | 221 | /** NeedWarmUp */ 222 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 223 | static bool GetNeedWarmUp(const FKawaiiPhysicsReference& KawaiiPhysics) 224 | { 225 | KAWAIIPHYSICS_VALUE_GETTER(bool, bNeedWarmUp); 226 | } 227 | 228 | /** LimitsDataAsset */ 229 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 230 | static FKawaiiPhysicsReference SetLimitsDataAsset(const FKawaiiPhysicsReference& KawaiiPhysics, 231 | UKawaiiPhysicsLimitsDataAsset* LimitsDataAsset) 232 | { 233 | KAWAIIPHYSICS_VALUE_SETTER(TObjectPtr, LimitsDataAsset); 234 | } 235 | 236 | /** LimitsDataAsset */ 237 | UFUNCTION(BlueprintPure, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 238 | static UKawaiiPhysicsLimitsDataAsset* GetLimitsDataAsset(const FKawaiiPhysicsReference& KawaiiPhysics) 239 | { 240 | KAWAIIPHYSICS_VALUE_GETTER(TObjectPtr, LimitsDataAsset); 241 | } 242 | 243 | /** Add ExternalForce With ExecResult */ 244 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 245 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 246 | static FKawaiiPhysicsReference AddExternalForceWithExecResult(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 247 | const FKawaiiPhysicsReference& KawaiiPhysics, 248 | FInstancedStruct& ExternalForce, UObject* Owner); 249 | 250 | /** Add ExternalForce */ 251 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 252 | static bool AddExternalForce(const FKawaiiPhysicsReference& KawaiiPhysics, 253 | FInstancedStruct& ExternalForce, UObject* Owner, bool bIsOneShot = false); 254 | 255 | /** Add ExternalForces to SkeletalMeshComponent */ 256 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 257 | static bool AddExternalForcesToComponent(USkeletalMeshComponent* MeshComp, 258 | UPARAM(ref) TArray& ExternalForces, UObject* Owner, 259 | UPARAM(ref) FGameplayTagContainer& FilterTags, 260 | bool bFilterExactMatch = false, 261 | bool bIsOneShot = false); 262 | 263 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", meta=(BlueprintThreadSafe)) 264 | static bool RemoveExternalForcesFromComponent(USkeletalMeshComponent* MeshComp, UObject* Owner, 265 | UPARAM(ref) FGameplayTagContainer& FilterTags, 266 | bool bFilterExactMatch = false); 267 | 268 | 269 | /** Set ExternalForceParameter template */ 270 | template 271 | static FKawaiiPhysicsReference SetExternalForceProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 272 | const FKawaiiPhysicsReference& KawaiiPhysics, 273 | int ExternalForceIndex, FName PropertyName, 274 | ValueType Value); 275 | /** Get ExternalForceParameter template */ 276 | template 277 | static ValueType GetExternalForceProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 278 | const FKawaiiPhysicsReference& KawaiiPhysics, int ExternalForceIndex, 279 | FName PropertyName); 280 | 281 | /** Set ExternalForceParameter template struct */ 282 | template 283 | static FKawaiiPhysicsReference SetExternalForceStructProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 284 | const FKawaiiPhysicsReference& KawaiiPhysics, 285 | int ExternalForceIndex, FName PropertyName, 286 | ValueType Value); 287 | /** Get ExternalForceParameter template struct */ 288 | template 289 | static ValueType GetExternalForceStructProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 290 | const FKawaiiPhysicsReference& KawaiiPhysics, 291 | int ExternalForceIndex, 292 | FName PropertyName); 293 | 294 | /** Set ExternalForceParameter bool */ 295 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 296 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 297 | static FKawaiiPhysicsReference SetExternalForceBoolProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 298 | const FKawaiiPhysicsReference& KawaiiPhysics, 299 | int ExternalForceIndex, FName PropertyName, 300 | bool Value) 301 | { 302 | return SetExternalForceProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, 303 | PropertyName, Value); 304 | } 305 | 306 | /** Get ExternalForceParameter bool */ 307 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 308 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 309 | static bool GetExternalForceBoolProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 310 | const FKawaiiPhysicsReference& KawaiiPhysics, int ExternalForceIndex, 311 | FName PropertyName) 312 | { 313 | return GetExternalForceProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, PropertyName); 314 | } 315 | 316 | /** Set ExternalForceParameter int */ 317 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 318 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 319 | static FKawaiiPhysicsReference SetExternalForceIntProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 320 | const FKawaiiPhysicsReference& KawaiiPhysics, 321 | int ExternalForceIndex, FName PropertyName, 322 | int32 Value) 323 | { 324 | return SetExternalForceProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, 325 | PropertyName, Value); 326 | } 327 | 328 | /** Get ExternalForceParameter int */ 329 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 330 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 331 | static int32 GetExternalForceIntProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 332 | const FKawaiiPhysicsReference& KawaiiPhysics, int ExternalForceIndex, 333 | FName PropertyName) 334 | { 335 | return GetExternalForceProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, PropertyName); 336 | } 337 | 338 | /** Set ExternalForceParameter float */ 339 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 340 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 341 | static FKawaiiPhysicsReference SetExternalForceFloatProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 342 | const FKawaiiPhysicsReference& KawaiiPhysics, 343 | int ExternalForceIndex, FName PropertyName, 344 | float Value) 345 | { 346 | return SetExternalForceProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, 347 | PropertyName, Value); 348 | } 349 | 350 | /** Get ExternalForceParameter float */ 351 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 352 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 353 | static float GetExternalForceFloatProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 354 | const FKawaiiPhysicsReference& KawaiiPhysics, int ExternalForceIndex, 355 | FName PropertyName) 356 | { 357 | return GetExternalForceProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, PropertyName); 358 | } 359 | 360 | /** Get ExternalForceParameter Vector */ 361 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 362 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 363 | static FKawaiiPhysicsReference SetExternalForceVectorProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 364 | const FKawaiiPhysicsReference& KawaiiPhysics, 365 | int ExternalForceIndex, FName PropertyName, 366 | FVector Value) 367 | { 368 | return SetExternalForceStructProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, 369 | PropertyName, Value); 370 | } 371 | 372 | /** Get ExternalForceParameter Vector */ 373 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 374 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 375 | static FVector GetExternalForceVectorProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 376 | const FKawaiiPhysicsReference& KawaiiPhysics, int ExternalForceIndex, 377 | FName PropertyName) 378 | { 379 | return GetExternalForceStructProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, PropertyName); 380 | } 381 | 382 | /** Get ExternalForceParameter Rotator */ 383 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 384 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 385 | static FKawaiiPhysicsReference SetExternalForceRotatorProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 386 | const FKawaiiPhysicsReference& KawaiiPhysics, 387 | int ExternalForceIndex, FName PropertyName, 388 | FRotator Value) 389 | { 390 | return SetExternalForceStructProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, 391 | PropertyName, Value); 392 | } 393 | 394 | /** Get ExternalForceParameter Rotator */ 395 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 396 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 397 | static FRotator GetExternalForceRotatorProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 398 | const FKawaiiPhysicsReference& KawaiiPhysics, 399 | int ExternalForceIndex, 400 | FName PropertyName) 401 | { 402 | return GetExternalForceStructProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, PropertyName); 403 | } 404 | 405 | /** Get ExternalForceParameter Transform */ 406 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 407 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 408 | static FKawaiiPhysicsReference SetExternalForceTransformProperty( 409 | EKawaiiPhysicsAccessExternalForceResult& ExecResult, 410 | const FKawaiiPhysicsReference& KawaiiPhysics, 411 | int ExternalForceIndex, FName PropertyName, 412 | FTransform Value) 413 | { 414 | return SetExternalForceStructProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, 415 | PropertyName, Value); 416 | } 417 | 418 | /** Get ExternalForceParameter Transform */ 419 | UFUNCTION(BlueprintCallable, Category = "Kawaii Physics", 420 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult")) 421 | static FTransform GetExternalForceTransformProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 422 | const FKawaiiPhysicsReference& KawaiiPhysics, 423 | int ExternalForceIndex, 424 | FName PropertyName) 425 | { 426 | return GetExternalForceStructProperty(ExecResult, KawaiiPhysics, ExternalForceIndex, PropertyName); 427 | } 428 | 429 | /** Set ExternalForceParameter Wildcard */ 430 | UFUNCTION(BlueprintCallable, CustomThunk, Category = "Kawaii Physics", 431 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult", CustomStructureParam = "Value")) 432 | static void SetExternalForceWildcardProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 433 | const FKawaiiPhysicsReference& KawaiiPhysics, int ExternalForceIndex, 434 | FName PropertyName, const int32& Value) 435 | { 436 | checkNoEntry(); 437 | } 438 | 439 | 440 | /** Get ExternalForceParameter Wildcard */ 441 | UFUNCTION(BlueprintCallable, CustomThunk, Category = "Kawaii Physics", 442 | meta=(BlueprintThreadSafe, ExpandEnumAsExecs = "ExecResult", CustomStructureParam = "Value")) 443 | static void GetExternalForceWildcardProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 444 | const FKawaiiPhysicsReference& KawaiiPhysics, int ExternalForceIndex, 445 | FName PropertyName, int32& Value) 446 | { 447 | checkNoEntry(); 448 | } 449 | 450 | private: 451 | DECLARE_FUNCTION(execSetExternalForceWildcardProperty); 452 | DECLARE_FUNCTION(execGetExternalForceWildcardProperty); 453 | }; 454 | 455 | template 456 | FKawaiiPhysicsReference UKawaiiPhysicsLibrary::SetExternalForceProperty( 457 | EKawaiiPhysicsAccessExternalForceResult& ExecResult, const FKawaiiPhysicsReference& KawaiiPhysics, 458 | int ExternalForceIndex, FName PropertyName, ValueType Value) 459 | { 460 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::NotValid; 461 | 462 | KawaiiPhysics.CallAnimNodeFunction( 463 | TEXT("SetExternalForceProperty"), 464 | [&ExecResult, &ExternalForceIndex, &PropertyName, &Value](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 465 | { 466 | if (InKawaiiPhysics.ExternalForces.IsValidIndex(ExternalForceIndex) && 467 | InKawaiiPhysics.ExternalForces[ExternalForceIndex].IsValid()) 468 | { 469 | const auto* ScriptStruct = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetScriptStruct(); 470 | auto& Force = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetMutable< 471 | FKawaiiPhysics_ExternalForce>(); 472 | 473 | if (const PropertyType* Property = FindFProperty(ScriptStruct, PropertyName)) 474 | { 475 | if (void* ValuePtr = Property->template ContainerPtrToValuePtr(&Force)) 476 | { 477 | Property->SetPropertyValue(ValuePtr, Value); 478 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::Valid; 479 | } 480 | } 481 | } 482 | }); 483 | 484 | return KawaiiPhysics; 485 | } 486 | 487 | template 488 | ValueType UKawaiiPhysicsLibrary::GetExternalForceProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 489 | const FKawaiiPhysicsReference& KawaiiPhysics, 490 | int ExternalForceIndex, FName PropertyName) 491 | { 492 | ValueType Result; 493 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::NotValid; 494 | 495 | KawaiiPhysics.CallAnimNodeFunction( 496 | TEXT("GetExternalForceProperty"), 497 | [&Result, &ExecResult, &ExternalForceIndex, &PropertyName](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 498 | { 499 | if (InKawaiiPhysics.ExternalForces.IsValidIndex(ExternalForceIndex) && 500 | InKawaiiPhysics.ExternalForces[ExternalForceIndex].IsValid()) 501 | { 502 | const auto* ScriptStruct = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetScriptStruct(); 503 | const auto& Force = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetMutable< 504 | FKawaiiPhysics_ExternalForce>(); 505 | 506 | if (const FProperty* Property = FindFProperty(ScriptStruct, PropertyName)) 507 | { 508 | Result = *(Property->ContainerPtrToValuePtr(&Force)); 509 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::Valid; 510 | } 511 | } 512 | }); 513 | 514 | return Result; 515 | } 516 | 517 | template 518 | FKawaiiPhysicsReference UKawaiiPhysicsLibrary::SetExternalForceStructProperty( 519 | EKawaiiPhysicsAccessExternalForceResult& ExecResult, const FKawaiiPhysicsReference& KawaiiPhysics, 520 | int ExternalForceIndex, FName PropertyName, ValueType Value) 521 | { 522 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::NotValid; 523 | 524 | KawaiiPhysics.CallAnimNodeFunction( 525 | TEXT("SetExternalForceStructProperty"), 526 | [&ExecResult, &ExternalForceIndex, &PropertyName, &Value](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 527 | { 528 | if (InKawaiiPhysics.ExternalForces.IsValidIndex(ExternalForceIndex) && 529 | InKawaiiPhysics.ExternalForces[ExternalForceIndex].IsValid()) 530 | { 531 | const auto* ScriptStruct = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetScriptStruct(); 532 | auto& Force = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetMutable< 533 | FKawaiiPhysics_ExternalForce>(); 534 | 535 | if (const FStructProperty* StructProperty = FindFProperty( 536 | ScriptStruct, PropertyName)) 537 | { 538 | if (StructProperty->Struct == TBaseStructure::Get()) 539 | { 540 | if (void* ValuePtr = StructProperty->ContainerPtrToValuePtr(&Force)) 541 | { 542 | StructProperty->CopyCompleteValue(ValuePtr, &Value); 543 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::Valid; 544 | } 545 | } 546 | } 547 | } 548 | }); 549 | 550 | return KawaiiPhysics; 551 | } 552 | 553 | template 554 | ValueType UKawaiiPhysicsLibrary::GetExternalForceStructProperty(EKawaiiPhysicsAccessExternalForceResult& ExecResult, 555 | const FKawaiiPhysicsReference& KawaiiPhysics, 556 | int ExternalForceIndex, FName PropertyName) 557 | { 558 | ValueType Result; 559 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::NotValid; 560 | 561 | KawaiiPhysics.CallAnimNodeFunction( 562 | TEXT("GetExternalForceStructProperty"), 563 | [&Result, &ExecResult, &ExternalForceIndex, &PropertyName](FAnimNode_KawaiiPhysics& InKawaiiPhysics) 564 | { 565 | if (InKawaiiPhysics.ExternalForces.IsValidIndex(ExternalForceIndex) && 566 | InKawaiiPhysics.ExternalForces[ExternalForceIndex].IsValid()) 567 | { 568 | const auto* ScriptStruct = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetScriptStruct(); 569 | const auto& Force = InKawaiiPhysics.ExternalForces[ExternalForceIndex].GetMutable< 570 | FKawaiiPhysics_ExternalForce>(); 571 | 572 | if (const FStructProperty* StructProperty = FindFProperty( 573 | ScriptStruct, PropertyName)) 574 | { 575 | if (StructProperty->Struct == TBaseStructure::Get()) 576 | { 577 | Result = *(StructProperty->ContainerPtrToValuePtr(&Force)); 578 | ExecResult = EKawaiiPhysicsAccessExternalForceResult::Valid; 579 | } 580 | } 581 | } 582 | }); 583 | 584 | return Result; 585 | } 586 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysics/Public/KawaiiPhysicsLimitsDataAsset.h: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AnimNode_KawaiiPhysics.h" 7 | #include "Engine/DataAsset.h" 8 | #include "Interfaces/Interface_BoneReferenceSkeletonProvider.h" 9 | #include "KawaiiPhysicsLimitsDataAsset.generated.h" 10 | 11 | DECLARE_MULTICAST_DELEGATE_OneParam(FOnLimitsChanged, struct FPropertyChangedEvent&); 12 | 13 | // Deprecated 14 | USTRUCT() 15 | struct FCollisionLimitDataBase 16 | { 17 | GENERATED_BODY() 18 | 19 | UPROPERTY(meta=(DeprecatedProperty)) 20 | FBoneReference DrivingBoneReference; 21 | 22 | UPROPERTY(meta=(DeprecatedProperty)) 23 | FName DrivingBoneName; 24 | 25 | UPROPERTY(meta=(DeprecatedProperty)) 26 | FVector OffsetLocation = FVector::ZeroVector; 27 | 28 | UPROPERTY(meta=(DeprecatedProperty)) 29 | FRotator OffsetRotation = FRotator::ZeroRotator; 30 | 31 | UPROPERTY(meta=(DeprecatedProperty)) 32 | FVector Location = FVector::ZeroVector; 33 | 34 | UPROPERTY(meta=(DeprecatedProperty)) 35 | FQuat Rotation = FQuat::Identity; 36 | 37 | UPROPERTY(meta=(DeprecatedProperty, IgnoreForMemberInitializationTest)) 38 | FGuid Guid = FGuid::NewGuid(); 39 | 40 | protected: 41 | void ConvertBase(FCollisionLimitBase& Limit) const 42 | { 43 | Limit.DrivingBone.BoneName = DrivingBoneReference.BoneName; 44 | Limit.OffsetLocation = OffsetLocation; 45 | Limit.OffsetRotation = OffsetRotation; 46 | Limit.Location = Location; 47 | Limit.Rotation = Rotation; 48 | 49 | #if WITH_EDITORONLY_DATA 50 | Limit.SourceType = ECollisionSourceType::DataAsset; 51 | Limit.Guid = Guid; 52 | #endif 53 | } 54 | }; 55 | 56 | // Deprecated 57 | USTRUCT() 58 | struct FSphericalLimitData : public FCollisionLimitDataBase 59 | { 60 | GENERATED_BODY() 61 | 62 | /** Radius of the sphere */ 63 | UPROPERTY(meta=(DeprecatedProperty)) 64 | float Radius = 5.0f; 65 | 66 | /** Whether to lock bodies inside or outside of the sphere */ 67 | UPROPERTY(meta=(DeprecatedProperty)) 68 | ESphericalLimitType LimitType = ESphericalLimitType::Outer; 69 | 70 | FSphericalLimit Convert() const 71 | { 72 | FSphericalLimit Limit; 73 | ConvertBase(Limit); 74 | Limit.Radius = Radius; 75 | Limit.LimitType = LimitType; 76 | 77 | return Limit; 78 | } 79 | }; 80 | 81 | // Deprecated 82 | USTRUCT() 83 | struct FCapsuleLimitData : public FCollisionLimitDataBase 84 | { 85 | GENERATED_BODY() 86 | 87 | UPROPERTY(meta=(DeprecatedProperty)) 88 | float Radius = 5.0f; 89 | 90 | UPROPERTY(meta=(DeprecatedProperty)) 91 | float Length = 10.0f; 92 | 93 | FCapsuleLimit Convert() const 94 | { 95 | FCapsuleLimit Limit; 96 | ConvertBase(Limit); 97 | Limit.Radius = Radius; 98 | Limit.Length = Length; 99 | 100 | return Limit; 101 | } 102 | }; 103 | 104 | // Deprecated 105 | USTRUCT() 106 | struct FBoxLimitData : public FCollisionLimitDataBase 107 | { 108 | GENERATED_BODY() 109 | 110 | UPROPERTY(meta=(DeprecatedProperty)) 111 | FVector Extent = FVector(5.0f, 5.0f, 5.0f); 112 | 113 | FBoxLimit Convert() const 114 | { 115 | FBoxLimit Limit; 116 | ConvertBase(Limit); 117 | Limit.Extent = Extent; 118 | 119 | return Limit; 120 | } 121 | }; 122 | 123 | // Deprecated 124 | USTRUCT() 125 | struct FPlanarLimitData : public FCollisionLimitDataBase 126 | { 127 | GENERATED_BODY() 128 | 129 | UPROPERTY(meta=(DeprecatedProperty)) 130 | FPlane Plane = FPlane(0, 0, 0, 0); 131 | 132 | FPlanarLimit Convert() const 133 | { 134 | FPlanarLimit Limit; 135 | ConvertBase(Limit); 136 | Limit.Plane = Plane; 137 | 138 | return Limit; 139 | } 140 | }; 141 | 142 | /** 143 | * 144 | */ 145 | UCLASS(Blueprintable) 146 | class KAWAIIPHYSICS_API UKawaiiPhysicsLimitsDataAsset : public UDataAsset, public IBoneReferenceSkeletonProvider 147 | 148 | { 149 | GENERATED_BODY() 150 | 151 | public: 152 | #if WITH_EDITORONLY_DATA 153 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Skeleton") 154 | TObjectPtr Skeleton; 155 | 156 | // Deprecated 157 | UPROPERTY(meta=(DeprecatedProperty)) 158 | TArray SphericalLimitsData; 159 | UPROPERTY(meta=(DeprecatedProperty)) 160 | TArray CapsuleLimitsData; 161 | UPROPERTY(meta=(DeprecatedProperty)) 162 | TArray BoxLimitsData; 163 | UPROPERTY(meta=(DeprecatedProperty)) 164 | TArray PlanarLimitsData; 165 | 166 | #endif 167 | 168 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spherical Limits") 169 | TArray SphericalLimits; 170 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capsule Limits") 171 | TArray CapsuleLimits; 172 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Box Limits") 173 | TArray BoxLimits; 174 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Planar Limits") 175 | TArray PlanarLimits; 176 | 177 | // Begin UObject Interface. 178 | #if WITH_EDITORONLY_DATA 179 | virtual void Serialize(FStructuredArchiveRecord Record) override; 180 | #endif 181 | virtual void PostLoad() override; 182 | // End UObject Interface. 183 | 184 | // IBoneReferenceSkeletonProvider interface 185 | virtual USkeleton* GetSkeleton(bool& bInvalidSkeletonIsError, const IPropertyHandle* PropertyHandle) override; 186 | 187 | #if WITH_EDITOR 188 | void UpdateLimit(FCollisionLimitBase* Limit); 189 | 190 | FOnLimitsChanged OnLimitsChanged; 191 | virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) override; 192 | #endif 193 | 194 | private: 195 | #if WITH_EDITOR 196 | void Sync(); 197 | #endif 198 | }; 199 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysicsEd/KawaiiPhysicsEd.Build.cs: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | using UnrealBuildTool; 4 | 5 | public class KawaiiPhysicsEd : ModuleRules 6 | { 7 | public KawaiiPhysicsEd(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PrivateDependencyModuleNames.AddRange(new[] { "Core", "CoreUObject", "Engine", "InputCore", "KawaiiPhysics" }); 12 | PrivateDependencyModuleNames.AddRange(new[] 13 | { 14 | "AnimGraph", "BlueprintGraph", "Persona", "UnrealEd", "AnimGraphRuntime", "Slate", "SlateCore", 15 | "StructUtils" 16 | }); 17 | 18 | BuildVersion Version; 19 | if (BuildVersion.TryRead(BuildVersion.GetDefaultFileName(), out Version)) 20 | if (Version.MajorVersion == 5) 21 | { 22 | PrivateDependencyModuleNames.AddRange(new[] { "EditorFramework" }); 23 | 24 | // From UE5.1, BaseClass of EditMode move to new Module 25 | if (Version.MinorVersion >= 1) PrivateDependencyModuleNames.AddRange(new[] { "AnimationEditMode" }); 26 | } 27 | 28 | // Uncomment if you are using Slate UI 29 | // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); 30 | 31 | // Uncomment if you are using online features 32 | // PrivateDependencyModuleNames.Add("OnlineSubsystem"); 33 | 34 | // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true 35 | } 36 | } -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysicsEd/Private/AnimGraphNode_KawaiiPhysics.cpp: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #include "AnimGraphNode_KawaiiPhysics.h" 4 | 5 | #include "Subsystems/AssetEditorSubsystem.h" 6 | #include "AssetToolsModule.h" 7 | #include "DetailCategoryBuilder.h" 8 | #include "DetailLayoutBuilder.h" 9 | #include "DetailWidgetRow.h" 10 | #include "KawaiiPhysicsBoneConstraintsDataAsset.h" 11 | #include "KawaiiPhysicsLimitsDataAsset.h" 12 | #include "Widgets/Input/SButton.h" 13 | #include "Framework/Notifications/NotificationManager.h" 14 | #include "Selection.h" 15 | #include "Widgets/Text/STextBlock.h" 16 | #include "Widgets/Notifications/SNotificationList.h" 17 | #include "AssetRegistry/AssetRegistryModule.h" 18 | #include "Dialogs/DlgPickAssetPath.h" 19 | #include "Kismet2/CompilerResultsLog.h" 20 | #include "Widgets/Layout/SUniformGridPanel.h" 21 | 22 | #define LOCTEXT_NAMESPACE "KawaiiPhysics" 23 | 24 | // ---------------------------------------------------------------------------- 25 | UAnimGraphNode_KawaiiPhysics::UAnimGraphNode_KawaiiPhysics(const FObjectInitializer& ObjectInitializer) 26 | : Super(ObjectInitializer) 27 | { 28 | } 29 | 30 | FText UAnimGraphNode_KawaiiPhysics::GetControllerDescription() const 31 | { 32 | return LOCTEXT("Kawaii Physics", "Kawaii Physics"); 33 | } 34 | 35 | 36 | // ---------------------------------------------------------------------------- 37 | FText UAnimGraphNode_KawaiiPhysics::GetNodeTitle(ENodeTitleType::Type TitleType) const 38 | { 39 | if ((TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle)) 40 | { 41 | return GetControllerDescription(); 42 | } 43 | // @TODO: the bone can be altered in the property editor, so we have to 44 | // choose to mark this dirty when that happens for this to properly work 45 | //if (!CachedNodeTitles.IsTitleCached(TitleType, this)) 46 | 47 | FFormatNamedArguments Args; 48 | Args.Add(TEXT("ControllerDescription"), GetControllerDescription()); 49 | Args.Add(TEXT("RootBoneName"), FText::FromName(Node.RootBone.BoneName)); 50 | Args.Add(TEXT("Tag"), FText::FromString(Node.KawaiiPhysicsTag.ToString())); 51 | 52 | // FText::Format() is slow, so we cache this to save on performance 53 | if (TitleType == ENodeTitleType::ListView || TitleType == ENodeTitleType::MenuTitle) 54 | { 55 | const FText Title = Node.KawaiiPhysicsTag.IsValid() 56 | ? FText::Format( 57 | LOCTEXT("AnimGraphNode_KawaiiPhysics_ListTitle", 58 | "{ControllerDescription} - Root: {RootBoneName} - Tag: {Tag}"), Args) 59 | : FText::Format( 60 | LOCTEXT("AnimGraphNode_KawaiiPhysics_ListTitle", 61 | "{ControllerDescription} - Root: {RootBoneName}"), Args); 62 | 63 | CachedNodeTitles.SetCachedTitle(TitleType, Title, this); 64 | } 65 | else 66 | { 67 | const FText Title = Node.KawaiiPhysicsTag.IsValid() 68 | ? FText::Format( 69 | LOCTEXT("AnimGraphNode_KawaiiPhysics_Title", 70 | "{ControllerDescription}\nRoot: {RootBoneName}\nTag: {Tag} "), Args) 71 | : FText::Format( 72 | LOCTEXT("AnimGraphNode_KawaiiPhysics_Title", 73 | "{ControllerDescription}\nRoot: {RootBoneName}"), Args); 74 | 75 | CachedNodeTitles.SetCachedTitle(TitleType, Title, this); 76 | } 77 | return CachedNodeTitles[TitleType]; 78 | } 79 | 80 | void UAnimGraphNode_KawaiiPhysics::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) 81 | { 82 | Super::PostEditChangeProperty(PropertyChangedEvent); 83 | 84 | Node.ModifyBones.Empty(); 85 | ReconstructNode(); 86 | } 87 | 88 | FEditorModeID UAnimGraphNode_KawaiiPhysics::GetEditorMode() const 89 | { 90 | return "AnimGraph.SkeletalControl.KawaiiPhysics"; 91 | } 92 | 93 | void UAnimGraphNode_KawaiiPhysics::ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, 94 | UAnimBlueprintGeneratedClass* CompiledClass, 95 | int32 CompiledNodeIndex) 96 | { 97 | UAnimGraphNode_SkeletalControlBase::ValidateAnimNodePostCompile(MessageLog, CompiledClass, CompiledNodeIndex); 98 | 99 | Node.RootBone.Initialize(CompiledClass->TargetSkeleton); 100 | if (Node.RootBone.BoneIndex >= 0) 101 | { 102 | if (Node.ExcludeBones.Contains(Node.RootBone)) 103 | { 104 | MessageLog.Warning(TEXT("@@ ExcludeBones should NOT has RootBone."), this); 105 | } 106 | } 107 | // for template ABP 108 | else if (CompiledClass->TargetSkeleton) 109 | { 110 | MessageLog.Warning(TEXT("@@ RootBone is empty."), this); 111 | } 112 | } 113 | 114 | void UAnimGraphNode_KawaiiPhysics::CopyNodeDataToPreviewNode(FAnimNode_Base* AnimNode) 115 | { 116 | FAnimNode_KawaiiPhysics* KawaiiPhysics = static_cast(AnimNode); 117 | 118 | // pushing properties to preview instance, for live editing 119 | // Default 120 | KawaiiPhysics->RootBone = Node.RootBone; 121 | KawaiiPhysics->ExcludeBones = Node.ExcludeBones; 122 | KawaiiPhysics->AdditionalRootBones = Node.AdditionalRootBones; 123 | KawaiiPhysics->TargetFramerate = Node.TargetFramerate; 124 | KawaiiPhysics->OverrideTargetFramerate = Node.OverrideTargetFramerate; 125 | 126 | // Physics Settings 127 | KawaiiPhysics->PhysicsSettings = Node.PhysicsSettings; 128 | KawaiiPhysics->DampingCurveData = Node.DampingCurveData; 129 | KawaiiPhysics->WorldDampingLocationCurveData = Node.WorldDampingLocationCurveData; 130 | KawaiiPhysics->WorldDampingRotationCurveData = Node.WorldDampingRotationCurveData; 131 | KawaiiPhysics->StiffnessCurveData = Node.StiffnessCurveData; 132 | KawaiiPhysics->RadiusCurveData = Node.RadiusCurveData; 133 | KawaiiPhysics->LimitAngleCurveData = Node.LimitAngleCurveData; 134 | KawaiiPhysics->bUpdatePhysicsSettingsInGame = Node.bUpdatePhysicsSettingsInGame; 135 | KawaiiPhysics->PlanarConstraint = Node.PlanarConstraint; 136 | KawaiiPhysics->ResetBoneTransformWhenBoneNotFound = Node.ResetBoneTransformWhenBoneNotFound; 137 | 138 | // DummyBone 139 | KawaiiPhysics->DummyBoneLength = Node.DummyBoneLength; 140 | KawaiiPhysics->BoneForwardAxis = Node.BoneForwardAxis; 141 | 142 | // Limits 143 | KawaiiPhysics->SphericalLimits = Node.SphericalLimits; 144 | KawaiiPhysics->CapsuleLimits = Node.CapsuleLimits; 145 | KawaiiPhysics->BoxLimits = Node.BoxLimits; 146 | KawaiiPhysics->PlanarLimits = Node.PlanarLimits; 147 | KawaiiPhysics->LimitsDataAsset = Node.LimitsDataAsset; 148 | KawaiiPhysics->PhysicsAssetForLimits = Node.PhysicsAssetForLimits; 149 | 150 | // ExternalForce 151 | KawaiiPhysics->Gravity = Node.Gravity; 152 | KawaiiPhysics->ExternalForces = Node.ExternalForces; 153 | KawaiiPhysics->CustomExternalForces = Node.CustomExternalForces; 154 | 155 | // Wind 156 | KawaiiPhysics->bEnableWind = Node.bEnableWind; 157 | KawaiiPhysics->WindScale = Node.WindScale; 158 | 159 | // BoneConstraint 160 | KawaiiPhysics->BoneConstraintGlobalComplianceType = Node.BoneConstraintGlobalComplianceType; 161 | KawaiiPhysics->BoneConstraintIterationCountBeforeCollision = Node.BoneConstraintIterationCountBeforeCollision; 162 | KawaiiPhysics->BoneConstraintIterationCountAfterCollision = Node.BoneConstraintIterationCountAfterCollision; 163 | KawaiiPhysics->bAutoAddChildDummyBoneConstraint = Node.bAutoAddChildDummyBoneConstraint; 164 | KawaiiPhysics->BoneConstraints = Node.BoneConstraints; 165 | KawaiiPhysics->BoneConstraintsDataAsset = Node.BoneConstraintsDataAsset; 166 | 167 | // Reset for sync without compile 168 | KawaiiPhysics->ModifyBones.Empty(); 169 | } 170 | 171 | void UAnimGraphNode_KawaiiPhysics::CustomizeDetailTools(IDetailLayoutBuilder& DetailBuilder) 172 | { 173 | IDetailCategoryBuilder& ViewportCategory = DetailBuilder.EditCategory(TEXT("Kawaii Physics Tools")); 174 | FDetailWidgetRow& WidgetRow = ViewportCategory.AddCustomRow(LOCTEXT("KawaiiPhysics", "KawaiiPhysicsTools")); 175 | 176 | WidgetRow 177 | [ 178 | SNew(SUniformGridPanel) 179 | .SlotPadding(FMargin(2, 0, 2, 0)) 180 | + SUniformGridPanel::Slot(0, 0) 181 | [ 182 | SNew(SButton) 183 | .HAlign(HAlign_Center) 184 | .VAlign(VAlign_Center) 185 | .OnClicked_Lambda([this]() 186 | { 187 | this->ExportLimitsDataAsset(); 188 | return FReply::Handled(); 189 | }) 190 | .Content() 191 | [ 192 | SNew(STextBlock) 193 | .Text(FText::FromString(TEXT("Export Limits"))) 194 | ] 195 | ] 196 | + SUniformGridPanel::Slot(1, 0) 197 | [ 198 | SNew(SButton) 199 | .HAlign(HAlign_Center) 200 | .VAlign(VAlign_Center) 201 | .OnClicked_Lambda([this]() 202 | { 203 | this->ExportBoneConstraintsDataAsset(); 204 | return FReply::Handled(); 205 | }) 206 | .Content() 207 | [ 208 | SNew(STextBlock) 209 | .Text(FText::FromString(TEXT("Export BoneConstraints"))) 210 | ] 211 | ] 212 | ]; 213 | } 214 | 215 | void UAnimGraphNode_KawaiiPhysics::CustomizeDetailDebugVisualizations(IDetailLayoutBuilder& DetailBuilder) 216 | { 217 | IDetailCategoryBuilder& ViewportCategory = DetailBuilder.EditCategory(TEXT("Debug Visualization")); 218 | FDetailWidgetRow& WidgetRow = ViewportCategory.AddCustomRow( 219 | LOCTEXT("ToggleDebugVisualizationButtonRow", "DebugVisualization")); 220 | 221 | WidgetRow 222 | [ 223 | SNew(SUniformGridPanel) 224 | .SlotPadding(FMargin(2, 0, 2, 0)) 225 | // Show/Hide Bones button. 226 | + SUniformGridPanel::Slot(0, 0) 227 | [ 228 | SNew(SButton) 229 | .HAlign(HAlign_Center) 230 | .VAlign(VAlign_Center) 231 | .OnClicked_Lambda([this]() 232 | { 233 | this->bEnableDebugDrawBone = !this->bEnableDebugDrawBone; 234 | return FReply::Handled(); 235 | }) 236 | .ButtonColorAndOpacity_Lambda([this]() 237 | { 238 | return this->bEnableDebugDrawBone 239 | ? FAppStyle::Get().GetSlateColor("Colors.AccentGreen") 240 | : FAppStyle::Get().GetSlateColor("Colors.AccentRed"); 241 | }) 242 | .Content() 243 | [ 244 | SNew(STextBlock) 245 | .Text_Lambda([this]() { return LOCTEXT("ShowBoneText", "Bone"); }) 246 | ] 247 | ] 248 | // Show/Hide LengthRate button. 249 | + SUniformGridPanel::Slot(1, 0) 250 | [ 251 | SNew(SButton) 252 | .HAlign(HAlign_Center) 253 | .VAlign(VAlign_Center) 254 | .OnClicked_Lambda([this]() 255 | { 256 | this->bEnableDebugBoneLengthRate = !this->bEnableDebugBoneLengthRate; 257 | return FReply::Handled(); 258 | }) 259 | .ButtonColorAndOpacity_Lambda([this]() 260 | { 261 | return this->bEnableDebugBoneLengthRate 262 | ? FAppStyle::Get().GetSlateColor("Colors.AccentGreen") 263 | : FAppStyle::Get().GetSlateColor("Colors.AccentRed"); 264 | }) 265 | .Content() 266 | [ 267 | SNew(STextBlock) 268 | .Text_Lambda([this]() { return LOCTEXT("ShowLengthRateText", "Length Rate"); }) 269 | ] 270 | ] 271 | // Show/Hide AngleLimit button. 272 | + SUniformGridPanel::Slot(2, 0) 273 | [ 274 | SNew(SButton) 275 | .HAlign(HAlign_Center) 276 | .VAlign(VAlign_Center) 277 | .OnClicked_Lambda([this]() 278 | { 279 | this->bEnableDebugDrawLimitAngle = !this->bEnableDebugDrawLimitAngle; 280 | return FReply::Handled(); 281 | }) 282 | .ButtonColorAndOpacity_Lambda([this]() 283 | { 284 | return this->bEnableDebugDrawLimitAngle 285 | ? FAppStyle::Get().GetSlateColor("Colors.AccentGreen") 286 | : FAppStyle::Get().GetSlateColor("Colors.AccentRed"); 287 | }) 288 | .Content() 289 | [ 290 | SNew(STextBlock) 291 | .Text_Lambda([this]() { return LOCTEXT("ShowLimitAngleText", "Limit Angle"); }) 292 | ] 293 | ] 294 | // Show/Hide SphereLimit button. 295 | + SUniformGridPanel::Slot(0, 1) 296 | [ 297 | SNew(SButton) 298 | .HAlign(HAlign_Center) 299 | .VAlign(VAlign_Center) 300 | .OnClicked_Lambda([this]() 301 | { 302 | this->bEnableDebugDrawSphereLimit = !this->bEnableDebugDrawSphereLimit; 303 | return FReply::Handled(); 304 | }) 305 | .ButtonColorAndOpacity_Lambda([this]() 306 | { 307 | return this->bEnableDebugDrawSphereLimit 308 | ? FAppStyle::Get().GetSlateColor("Colors.AccentGreen") 309 | : FAppStyle::Get().GetSlateColor("Colors.AccentRed"); 310 | }) 311 | .Content() 312 | [ 313 | SNew(STextBlock) 314 | .Text_Lambda([this]() { return LOCTEXT("ShowSphereLimitText", "Sphere Limit"); }) 315 | ] 316 | ] 317 | // Show/Hide CapsuleLimit button. 318 | + SUniformGridPanel::Slot(1, 1) 319 | [ 320 | SNew(SButton) 321 | .HAlign(HAlign_Center) 322 | .VAlign(VAlign_Center) 323 | .OnClicked_Lambda([this]() 324 | { 325 | this->bEnableDebugDrawCapsuleLimit = !this->bEnableDebugDrawCapsuleLimit; 326 | return FReply::Handled(); 327 | }) 328 | .ButtonColorAndOpacity_Lambda([this]() 329 | { 330 | return this->bEnableDebugDrawCapsuleLimit 331 | ? FAppStyle::Get().GetSlateColor("Colors.AccentGreen") 332 | : FAppStyle::Get().GetSlateColor("Colors.AccentRed"); 333 | }) 334 | .Content() 335 | [ 336 | SNew(STextBlock) 337 | .Text_Lambda([this]() { return LOCTEXT("ShowCapsuleLimitText", "Capsule Limit"); }) 338 | ] 339 | ] 340 | // Show/Hide BoxLimit button. 341 | + SUniformGridPanel::Slot(2, 1) 342 | [ 343 | SNew(SButton) 344 | .HAlign(HAlign_Center) 345 | .VAlign(VAlign_Center) 346 | .OnClicked_Lambda([this]() 347 | { 348 | this->bEnableDebugDrawBoxLimit = !this->bEnableDebugDrawBoxLimit; 349 | return FReply::Handled(); 350 | }) 351 | .ButtonColorAndOpacity_Lambda([this]() 352 | { 353 | return this->bEnableDebugDrawBoxLimit 354 | ? FAppStyle::Get().GetSlateColor("Colors.AccentGreen") 355 | : FAppStyle::Get().GetSlateColor("Colors.AccentRed"); 356 | }) 357 | .Content() 358 | [ 359 | SNew(STextBlock) 360 | .Text_Lambda([this]() { return LOCTEXT("ShowBoxLimitText", "Box Limit"); }) 361 | ] 362 | ] 363 | // Show/Hide PlanerLimit button. 364 | + SUniformGridPanel::Slot(0, 2) 365 | [ 366 | SNew(SButton) 367 | .HAlign(HAlign_Center) 368 | .VAlign(VAlign_Center) 369 | .OnClicked_Lambda([this]() 370 | { 371 | this->bEnableDebugDrawPlanerLimit = !this->bEnableDebugDrawPlanerLimit; 372 | return FReply::Handled(); 373 | }) 374 | .ButtonColorAndOpacity_Lambda([this]() 375 | { 376 | return this->bEnableDebugDrawPlanerLimit 377 | ? FAppStyle::Get().GetSlateColor("Colors.AccentGreen") 378 | : FAppStyle::Get().GetSlateColor("Colors.AccentRed"); 379 | }) 380 | .Content() 381 | [ 382 | SNew(STextBlock) 383 | .Text_Lambda([this]() { return LOCTEXT("ShowPlanerLimitText", "Planer Limit"); }) 384 | ] 385 | ] 386 | // Show/Hide BoneConstraint button. 387 | + SUniformGridPanel::Slot(1, 2) 388 | [ 389 | SNew(SButton) 390 | .HAlign(HAlign_Center) 391 | .VAlign(VAlign_Center) 392 | .OnClicked_Lambda([this]() 393 | { 394 | this->bEnableDebugDrawBoneConstraint = !this->bEnableDebugDrawBoneConstraint; 395 | return FReply::Handled(); 396 | }) 397 | .ButtonColorAndOpacity_Lambda([this]() 398 | { 399 | return this->bEnableDebugDrawBoneConstraint 400 | ? FAppStyle::Get().GetSlateColor("Colors.AccentGreen") 401 | : FAppStyle::Get().GetSlateColor("Colors.AccentRed"); 402 | }) 403 | .Content() 404 | [ 405 | SNew(STextBlock) 406 | .Text_Lambda([this]() { return LOCTEXT("ShowBoneConstraintText", "Bone Constraint"); }) 407 | ] 408 | ] 409 | // Show/Hide ExternalForce button. 410 | + SUniformGridPanel::Slot(2, 2) 411 | [ 412 | SNew(SButton) 413 | .HAlign(HAlign_Center) 414 | .VAlign(VAlign_Center) 415 | .OnClicked_Lambda([this]() 416 | { 417 | this->bEnableDebugDrawExternalForce = !this->bEnableDebugDrawExternalForce; 418 | return FReply::Handled(); 419 | }) 420 | .ButtonColorAndOpacity_Lambda([this]() 421 | { 422 | return this->bEnableDebugDrawExternalForce 423 | ? FAppStyle::Get().GetSlateColor("Colors.AccentGreen") 424 | : FAppStyle::Get().GetSlateColor("Colors.AccentRed"); 425 | }) 426 | .Content() 427 | [ 428 | SNew(STextBlock) 429 | .Text_Lambda([this]() { return LOCTEXT("ShowExternalForceText", "External Force"); }) 430 | ] 431 | ] 432 | ]; 433 | } 434 | 435 | void UAnimGraphNode_KawaiiPhysics::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) 436 | { 437 | Super::CustomizeDetails(DetailBuilder); 438 | 439 | CustomizeDetailTools(DetailBuilder); 440 | CustomizeDetailDebugVisualizations(DetailBuilder); 441 | 442 | // Force order of details panel categories - Must set order for all of them as any that are edited automatically move to the top. 443 | auto CategorySorter = [](const TMap& Categories) 444 | { 445 | int32 Order = 0; 446 | auto SafeSetOrder = [&Categories, &Order](const FName& CategoryName) 447 | { 448 | if (IDetailCategoryBuilder* const* Builder = Categories.Find(CategoryName)) 449 | { 450 | (*Builder)->SetSortOrder(Order++); 451 | } 452 | }; 453 | 454 | // Tools, Debug 455 | SafeSetOrder(FName("Kawaii Physics Tools")); 456 | SafeSetOrder(FName("Debug Visualization")); 457 | SafeSetOrder(FName("Functions")); 458 | 459 | // Basic 460 | SafeSetOrder(FName("Bones")); 461 | SafeSetOrder(FName("Physics Settings")); 462 | SafeSetOrder(FName("Physics Settings Advanced")); 463 | 464 | // Limits 465 | SafeSetOrder(FName("Limits")); 466 | SafeSetOrder(FName("Bone Constraint (Experimental)")); 467 | 468 | // Other 469 | SafeSetOrder(FName("World Collision")); 470 | SafeSetOrder(FName("ExternalForce")); 471 | 472 | // AnimNode 473 | SafeSetOrder(FName("Tag")); 474 | SafeSetOrder(FName("Alpha")); 475 | }; 476 | 477 | DetailBuilder.SortCategories(CategorySorter); 478 | } 479 | 480 | struct FKawaiiPhysicsVersion 481 | { 482 | enum Type 483 | { 484 | BeforeCustomVersionWasAdded, 485 | UseRuntimeFloatCurve, 486 | // ------------------------------------------------------ 487 | VersionPlusOne, 488 | LatestVersion = VersionPlusOne - 1 489 | }; 490 | 491 | // The GUID for this custom version number 492 | const static FGuid GUID; 493 | 494 | private: 495 | FKawaiiPhysicsVersion() 496 | { 497 | }; 498 | }; 499 | 500 | const FGuid FKawaiiPhysicsVersion::GUID(0x4B2D3E25, 0xCD681D29, 0x2DB298D7, 0xAD3E55FA); 501 | 502 | const FCustomVersionRegistration GRegisterKawaiiPhysCustomVersion(FKawaiiPhysicsVersion::GUID, 503 | FKawaiiPhysicsVersion::LatestVersion, 504 | TEXT("Kawaii-Phys")); 505 | 506 | void UAnimGraphNode_KawaiiPhysics::Serialize(FArchive& Ar) 507 | { 508 | Super::Serialize(Ar); 509 | 510 | Ar.UsingCustomVersion(FKawaiiPhysicsVersion::GUID); 511 | 512 | if (Ar.CustomVer(FKawaiiPhysicsVersion::GUID) < FKawaiiPhysicsVersion::UseRuntimeFloatCurve) 513 | { 514 | Node.DampingCurveData.ExternalCurve = Node.DampingCurve_DEPRECATED; 515 | Node.WorldDampingLocationCurveData.ExternalCurve = Node.WorldDampingLocationCurve_DEPRECATED; 516 | Node.WorldDampingRotationCurveData.ExternalCurve = Node.WorldDampingRotationCurve_DEPRECATED; 517 | Node.StiffnessCurveData.ExternalCurve = Node.StiffnessCurve_DEPRECATED; 518 | Node.RadiusCurveData.ExternalCurve = Node.RadiusCurve_DEPRECATED; 519 | Node.LimitAngleCurveData.ExternalCurve = Node.LimitAngleCurve_DEPRECATED; 520 | } 521 | } 522 | 523 | void UAnimGraphNode_KawaiiPhysics::CreateExportDataAssetPath(FString& PackageName, const FString& DefaultSuffix) const 524 | { 525 | FString AssetName; 526 | const FString AnimBlueprintPath = GetAnimBlueprint()->GetPackage()->GetName(); 527 | const FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked("AssetTools"); 528 | AssetToolsModule.Get().CreateUniqueAssetName(AnimBlueprintPath, DefaultSuffix, PackageName, AssetName); 529 | } 530 | 531 | UPackage* UAnimGraphNode_KawaiiPhysics::CreateDataAssetPackage(const FString& DialogTitle, const FString& DefaultSuffix, 532 | FString& AssetName) const 533 | { 534 | FString PackageName; 535 | CreateExportDataAssetPath(PackageName, DefaultSuffix); 536 | 537 | const TSharedRef NewAssetDlg = 538 | SNew(SDlgPickAssetPath) 539 | .Title(FText::FromString(DialogTitle)) 540 | .DefaultAssetPath(FText::FromString(PackageName)); 541 | 542 | if (NewAssetDlg->ShowModal() == EAppReturnType::Cancel) 543 | { 544 | return nullptr; 545 | } 546 | 547 | const FString PackagePath(NewAssetDlg->GetFullAssetPath().ToString()); 548 | AssetName = NewAssetDlg->GetAssetName().ToString(); 549 | 550 | return CreatePackage(*PackagePath); 551 | } 552 | 553 | void UAnimGraphNode_KawaiiPhysics::ShowExportAssetNotification(UObject* NewAsset, 554 | FText NotificationText) 555 | { 556 | FNotificationInfo NotificationInfo(NotificationText); 557 | NotificationInfo.ExpireDuration = 5.0f; 558 | NotificationInfo.Hyperlink = FSimpleDelegate::CreateLambda([NewAsset]() 559 | { 560 | GEditor->GetEditorSubsystem()->OpenEditorForAsset(NewAsset); 561 | }); 562 | NotificationInfo.HyperlinkText = LOCTEXT("OpenCreatedAsset", "Open Created Asset"); 563 | 564 | TSharedPtr NotificationItem = FSlateNotificationManager::Get().AddNotification( 565 | NotificationInfo); 566 | NotificationItem->SetCompletionState(SNotificationItem::CS_Success); 567 | } 568 | 569 | void UAnimGraphNode_KawaiiPhysics::ExportLimitsDataAsset() 570 | { 571 | FString AssetName; 572 | UPackage* Package = CreateDataAssetPackage( 573 | TEXT("Choose Location for Collision Data Asset"), TEXT("_Collision"), AssetName); 574 | if (!Package) 575 | { 576 | return; 577 | } 578 | 579 | if (UKawaiiPhysicsLimitsDataAsset* NewDataAsset = 580 | NewObject(Package, UKawaiiPhysicsLimitsDataAsset::StaticClass(), 581 | FName(AssetName), RF_Public | RF_Standalone)) 582 | { 583 | // look for a valid component in the object being debugged, 584 | // we might be set to something other than the preview. 585 | if (UObject* ObjectBeingDebugged = GetAnimBlueprint()->GetObjectBeingDebugged()) 586 | { 587 | if (const UAnimInstance* InstanceBeingDebugged = Cast(ObjectBeingDebugged)) 588 | { 589 | NewDataAsset->Skeleton = InstanceBeingDebugged->CurrentSkeleton; 590 | } 591 | } 592 | 593 | // copy data 594 | auto CopyLimits = [&](auto& DataLimits, auto& SourceLimits) 595 | { 596 | DataLimits = SourceLimits; 597 | for (auto& DataLimit : DataLimits) 598 | { 599 | DataLimit.SourceType = ECollisionSourceType::DataAsset; 600 | } 601 | }; 602 | CopyLimits(NewDataAsset->SphericalLimits, Node.SphericalLimits); 603 | CopyLimits(NewDataAsset->CapsuleLimits, Node.CapsuleLimits); 604 | CopyLimits(NewDataAsset->BoxLimits, Node.BoxLimits); 605 | CopyLimits(NewDataAsset->PlanarLimits, Node.PlanarLimits); 606 | 607 | // select new asset 608 | USelection* SelectionSet = GEditor->GetSelectedObjects(); 609 | SelectionSet->DeselectAll(); 610 | SelectionSet->Select(NewDataAsset); 611 | 612 | FAssetRegistryModule::AssetCreated(NewDataAsset); 613 | Package->MarkPackageDirty(); 614 | 615 | // Add Notification 616 | FText NotificationText = FText::Format( 617 | LOCTEXT("ExportedLimitsDataAsset", "Exposted Limits Data Asset: {0}"), FText::FromString(AssetName)); 618 | ShowExportAssetNotification(NewDataAsset, NotificationText); 619 | } 620 | } 621 | 622 | void UAnimGraphNode_KawaiiPhysics::ExportBoneConstraintsDataAsset() 623 | { 624 | FString AssetName; 625 | UPackage* Package = CreateDataAssetPackage( 626 | TEXT("Choose Location for BoneConstraints Data Asset"), TEXT("_BoneConstraint"), AssetName); 627 | if (!Package) 628 | { 629 | return; 630 | } 631 | 632 | if (UKawaiiPhysicsBoneConstraintsDataAsset* NewDataAsset = 633 | NewObject( 634 | Package, UKawaiiPhysicsBoneConstraintsDataAsset::StaticClass(), 635 | FName(AssetName), RF_Public | RF_Standalone)) 636 | { 637 | // look for a valid component in the object being debugged, 638 | // we might be set to something other than the preview. 639 | if (UObject* ObjectBeingDebugged = GetAnimBlueprint()->GetObjectBeingDebugged()) 640 | { 641 | if (const UAnimInstance* InstanceBeingDebugged = Cast(ObjectBeingDebugged)) 642 | { 643 | NewDataAsset->PreviewSkeleton = InstanceBeingDebugged->CurrentSkeleton; 644 | NewDataAsset->UpdatePreviewBoneList(); 645 | } 646 | } 647 | 648 | // copy data 649 | NewDataAsset->BoneConstraintsData.SetNum(Node.BoneConstraints.Num()); 650 | for (int32 i = 0; i < Node.BoneConstraints.Num(); i++) 651 | { 652 | NewDataAsset->BoneConstraintsData[i].Update(Node.BoneConstraints[i]); 653 | } 654 | 655 | // select new asset 656 | USelection* SelectionSet = GEditor->GetSelectedObjects(); 657 | SelectionSet->DeselectAll(); 658 | SelectionSet->Select(NewDataAsset); 659 | 660 | FAssetRegistryModule::AssetCreated(NewDataAsset); 661 | Package->MarkPackageDirty(); 662 | 663 | // Add Notification 664 | FText NotificationText = FText::Format( 665 | LOCTEXT("ExportedBoneConstraintsDataAsset", "Exposted BoneConstraints Data Asset: {0}"), 666 | FText::FromString(AssetName)); 667 | ShowExportAssetNotification(NewDataAsset, NotificationText); 668 | } 669 | } 670 | 671 | #undef LOCTEXT_NAMESPACE 672 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysicsEd/Private/KawaiiPhysicsEd.cpp: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #include "KawaiiPhysicsEd.h" 4 | #include "Modules/ModuleManager.h" 5 | #include "Textures/SlateIcon.h" 6 | #include "KawaiiPhysicsEditMode.h" 7 | 8 | #define LOCTEXT_NAMESPACE "FKawaiiPhysicsModuleEd" 9 | 10 | 11 | void FKawaiiPhysicsEdModule::StartupModule() 12 | { 13 | FEditorModeRegistry::Get().RegisterMode("AnimGraph.SkeletalControl.KawaiiPhysics", 14 | LOCTEXT("FKawaiiPhysicsEditMode", "Kawaii Physics"), 15 | FSlateIcon(), false); 16 | } 17 | 18 | 19 | void FKawaiiPhysicsEdModule::ShutdownModule() 20 | { 21 | FEditorModeRegistry::Get().UnregisterMode("AnimGraph.SkeletalControl.KawaiiPhysics"); 22 | } 23 | 24 | #undef LOCTEXT_NAMESPACE 25 | 26 | IMPLEMENT_MODULE(FKawaiiPhysicsEdModule, KawaiiPhysicsEd) 27 | //IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, KawaiiPhysicsEd, "KawaiiPhysicsEd" ); 28 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysicsEd/Public/AnimGraphNode_KawaiiPhysics.h: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #pragma once 4 | 5 | #include "AnimGraphNode_Base.h" 6 | #include "AnimNode_KawaiiPhysics.h" 7 | #include "AnimGraphNode_SkeletalControlBase.h" 8 | #include "EdGraph/EdGraphNodeUtils.h" 9 | 10 | #include "AnimGraphNode_KawaiiPhysics.generated.h" 11 | 12 | class FCompilerResultsLog; 13 | 14 | UCLASS() 15 | class UAnimGraphNode_KawaiiPhysics : public UAnimGraphNode_SkeletalControlBase 16 | { 17 | GENERATED_UCLASS_BODY() 18 | UPROPERTY(EditAnywhere, Category = Settings) 19 | FAnimNode_KawaiiPhysics Node; 20 | 21 | virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; 22 | 23 | // UObject interface 24 | virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override; 25 | 26 | protected: 27 | // UAnimGraphNode_Base interface 28 | virtual FEditorModeID GetEditorMode() const override; 29 | virtual void ValidateAnimNodePostCompile(FCompilerResultsLog& MessageLog, 30 | UAnimBlueprintGeneratedClass* CompiledClass, 31 | int32 CompiledNodeIndex) override; 32 | virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* AnimNode) override; 33 | virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override; 34 | // End of UAnimGraphNode_Base interface 35 | 36 | //virtual FText GetControllerDescription() const override; 37 | virtual FText GetControllerDescription() const override; 38 | virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; } 39 | // End of UAnimGraphNode_SkeletalControlBase interface 40 | 41 | // UObject interface 42 | virtual void Serialize(FArchive& Ar) override; 43 | 44 | // End of UObject interface 45 | 46 | virtual void CustomizeDetailTools(IDetailLayoutBuilder& DetailBuilder); 47 | virtual void CustomizeDetailDebugVisualizations(IDetailLayoutBuilder& DetailBuilder); 48 | 49 | private: 50 | /** Creates the export data asset path. */ 51 | void CreateExportDataAssetPath(FString& PackageName, const FString& DefaultSuffix) const; 52 | 53 | /** Creates the data asset package. */ 54 | UPackage* CreateDataAssetPackage(const FString& DialogTitle, const FString& DefaultSuffix, 55 | FString& AssetName) const; 56 | 57 | /** Shows the export asset notification. */ 58 | void ShowExportAssetNotification(UObject* NewAsset, FText NotificationText); 59 | 60 | /** Exports the limits data asset. */ 61 | void ExportLimitsDataAsset(); 62 | 63 | /** Exports the bone constraints data asset. */ 64 | void ExportBoneConstraintsDataAsset(); 65 | 66 | public: 67 | /** Enables or disables debug drawing for bones. */ 68 | UPROPERTY() 69 | bool bEnableDebugDrawBone = true; 70 | 71 | /** Enables or disables debug drawing for bone length rate. */ 72 | UPROPERTY() 73 | bool bEnableDebugBoneLengthRate = true; 74 | 75 | /** Enables or disables debug drawing for limit angles. */ 76 | UPROPERTY() 77 | bool bEnableDebugDrawLimitAngle = true; 78 | 79 | /** Enables or disables debug drawing for spherical limits. */ 80 | UPROPERTY() 81 | bool bEnableDebugDrawSphereLimit = true; 82 | 83 | /** Enables or disables debug drawing for capsule limits. */ 84 | UPROPERTY() 85 | bool bEnableDebugDrawCapsuleLimit = true; 86 | 87 | /** Enables or disables debug drawing for box limits. */ 88 | UPROPERTY() 89 | bool bEnableDebugDrawBoxLimit = true; 90 | 91 | /** Enables or disables debug drawing for planar limits. */ 92 | UPROPERTY() 93 | bool bEnableDebugDrawPlanerLimit = true; 94 | 95 | /** Enables or disables debug drawing for bone constraints. */ 96 | UPROPERTY() 97 | bool bEnableDebugDrawBoneConstraint = true; 98 | 99 | /** Enables or disables debug drawing for external forces. */ 100 | UPROPERTY() 101 | bool bEnableDebugDrawExternalForce = true; 102 | 103 | private: 104 | /** Constructing FText strings can be costly, so we cache the node's title */ 105 | FNodeTitleTextTable CachedNodeTitles; 106 | }; 107 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysicsEd/Public/KawaiiPhysicsEd.h: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | class FKawaiiPhysicsEdModule : public IModuleInterface 8 | { 9 | public: 10 | /** IModuleInterface implementation */ 11 | virtual void StartupModule() override; 12 | virtual void ShutdownModule() override; 13 | }; 14 | -------------------------------------------------------------------------------- /Plugins/KawaiiPhysics/Source/KawaiiPhysicsEd/Public/KawaiiPhysicsEditMode.h: -------------------------------------------------------------------------------- 1 | // KawaiiPhysics : Copyright (c) 2019-2024 pafuhana1213, MIT License 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AnimNodeEditMode.h" 7 | #include "AnimGraphNode_KawaiiPhysics.h" 8 | #include "AnimNode_KawaiiPhysics.h" 9 | 10 | #define UE_WIDGET UE::Widget 11 | 12 | class FEditorViewportClient; 13 | class FPrimitiveDrawInterface; 14 | class USkeletalMeshComponent; 15 | struct FViewportClick; 16 | 17 | class FKawaiiPhysicsEditMode : public FAnimNodeEditMode 18 | { 19 | public: 20 | FKawaiiPhysicsEditMode(); 21 | 22 | /** IAnimNodeEditMode interface */ 23 | virtual void EnterMode(class UAnimGraphNode_Base* InEditorNode, struct FAnimNode_Base* InRuntimeNode) override; 24 | virtual void ExitMode() override; 25 | virtual FVector GetWidgetLocation() const override; 26 | virtual UE_WIDGET::EWidgetMode GetWidgetMode() const override; 27 | virtual ECoordSystem GetWidgetCoordinateSystem() const override; 28 | virtual void DoTranslation(FVector& InTranslation) override; 29 | virtual void DoRotation(FRotator& InRotation) override; 30 | virtual void DoScale(FVector& InScale) override; 31 | 32 | /** FEdMode interface */ 33 | virtual void Render(const FSceneView* View, FViewport* Viewport, FPrimitiveDrawInterface* PDI) override; 34 | virtual bool HandleClick(FEditorViewportClient* InViewportClient, HHitProxy* HitProxy, 35 | const FViewportClick& Click) override; 36 | virtual bool GetCustomDrawingCoordinateSystem(FMatrix& InMatrix, void* InData) override; 37 | virtual bool InputKey(FEditorViewportClient* InViewportClient, FViewport* InViewport, FKey InKey, 38 | EInputEvent InEvent) override; 39 | virtual bool ShouldDrawWidget() const override; 40 | virtual void DrawHUD(FEditorViewportClient* ViewportClient, FViewport* Viewport, const FSceneView* View, 41 | FCanvas* Canvas) override; 42 | 43 | protected: 44 | void OnExternalNodePropertyChange(FPropertyChangedEvent& InPropertyEvent); 45 | FDelegateHandle NodePropertyDelegateHandle; 46 | 47 | void OnLimitDataAssetPropertyChange(FPropertyChangedEvent& InPropertyEvent); 48 | bool IsSelectAnimNodeCollision() const; 49 | FDelegateHandle LimitsDataAssetPropertyDelegateHandle; 50 | 51 | private: 52 | void RenderModifyBones(FPrimitiveDrawInterface* PDI) const; 53 | void RenderLimitAngle(FPrimitiveDrawInterface* PDI) const; 54 | 55 | /** Render each collisions */ 56 | void RenderSphericalLimits(FPrimitiveDrawInterface* PDI) const; 57 | void RenderCapsuleLimit(FPrimitiveDrawInterface* PDI) const; 58 | void RenderBoxLimit(FPrimitiveDrawInterface* PDI) const; 59 | void RenderPlanerLimit(FPrimitiveDrawInterface* PDI); 60 | 61 | void RenderBoneConstraint(FPrimitiveDrawInterface* PDI) const; 62 | void RenderExternalForces(FPrimitiveDrawInterface* PDI) const; 63 | 64 | /** Helper function for GetWidgetLocation() and joint rendering */ 65 | FVector GetWidgetLocation(ECollisionLimitType CollisionType, int32 Index) const; 66 | 67 | // methods to find a valid widget mode for gizmo because doesn't need to show gizmo when the mode is "Ignore" 68 | UE_WIDGET::EWidgetMode FindValidWidgetMode(UE_WIDGET::EWidgetMode InWidgetMode) const; 69 | 70 | /** Checking if a collision is selected and the collision is valid */ 71 | bool IsValidSelectCollision() const; 72 | 73 | // Get Select Colliison Info 74 | FCollisionLimitBase* GetSelectCollisionLimitRuntime() const; 75 | FCollisionLimitBase* GetSelectCollisionLimitGraph() const; 76 | 77 | /** Draw text func for DrawHUD */ 78 | void DrawTextItem(const FText& Text, FCanvas* Canvas, float X, float& Y, float FontHeight); 79 | void Draw3DTextItem(const FText& Text, FCanvas* Canvas, const FSceneView* View, const FViewport* Viewport, 80 | FVector Location); 81 | 82 | /** Cache the typed nodes */ 83 | struct FAnimNode_KawaiiPhysics* RuntimeNode; 84 | UAnimGraphNode_KawaiiPhysics* GraphNode; 85 | 86 | /** The current bone selection mode */ 87 | ECollisionLimitType SelectCollisionType = ECollisionLimitType::None; 88 | int32 SelectCollisionIndex = -1; 89 | ECollisionSourceType SelectCollisionSourceType = ECollisionSourceType::AnimNode; 90 | 91 | // storing current widget mode 92 | mutable UE_WIDGET::EWidgetMode CurWidgetMode; 93 | 94 | // physics asset body material 95 | TObjectPtr PhysicsAssetBodyMaterial; 96 | }; 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kawaii Physics 2 | 3 | 画像 4 | 5 | 6 | Demo : https://youtu.be/0f-l-SP07Mo 7 | 8 | English doc 9 | https://github.com/pafuhana1213/KawaiiPhysics/blob/master/README_en.md 10 | 11 | ダウンロード(C++ビルド環境がない方向け) 12 | Github : https://github.com/pafuhana1213/KawaiiPhysics/releases/ 13 | Booth : [https://pafuhana1213.booth.pm/items/5943534](https://pafuhana1213.booth.pm/items/5943534) 14 | (ストアアカウントをフォローするとアップデート通知あり) 15 | 16 | ディスカッション 17 | - [アップデート情報](https://github.com/pafuhana1213/KawaiiPhysics/discussions/categories/announcements-%E3%82%A2%E3%83%8A%E3%82%A6%E3%83%B3%E3%82%B9) 18 | - [要望・アイデア](https://github.com/pafuhana1213/KawaiiPhysics/discussions/categories/ideas-%E8%A6%81%E6%9C%9B-%E3%82%A2%E3%82%A4%E3%83%87%E3%82%A2) 19 | - [質問・Q&A](https://github.com/pafuhana1213/KawaiiPhysics/discussions/categories/q-a) 20 | - [あなたの作品を教えてください!](https://github.com/pafuhana1213/KawaiiPhysics/discussions/65) 21 | - [設定方法などについての雑談・相談の場](https://github.com/pafuhana1213/KawaiiPhysics/discussions/66) 22 | - [機能やサンプルのリクエスト方法について](https://github.com/pafuhana1213/KawaiiPhysics/discussions/67) 23 | 24 | 不具合報告 25 | - https://github.com/pafuhana1213/KawaiiPhysics/issues 26 | 27 | 採用実績 28 | - https://github.com/pafuhana1213/KawaiiPhysics/wiki/%E6%8E%A1%E7%94%A8%E5%AE%9F%E7%B8%BE-Adoption 29 | 30 | ## はじめに 31 | Kawaii Physicsは UnrealEngine4,5用に作成した疑似物理プラグインです。 32 | 髪、スカート、胸などの揺れものを「かんたんに」「かわいく」揺らすことができます。 33 | 34 | ![](https://github.com/pafuhana1213/Screenshot/blob/master/KawaiiPhysics1.gif) 35 | お借りしたキャラクタ:Gray ちゃん http://rarihoma.xvs.jp/products/graychan 36 | 37 | ![](https://github.com/pafuhana1213/Screenshot/blob/master/KawaiiPhysics0.gif) 38 | https://www.youtube.com/watch?v=UvpEIBGegvs 39 | お借りしたキャラクタ:ミライ小町 https://www.bandainamcostudios.com/works/miraikomachi/ 40 | 41 | ## 特徴 42 | ![](https://github.com/pafuhana1213/Screenshot/blob/master/KawaiiPhysics2.jpg) 43 | ![](https://github.com/pafuhana1213/Screenshot/blob/master/KawaiiPhysics4.gif) 44 | - 元の形状を尊重しつつ、アニメーションやSkeletalMeshComponentの移動・回転を元に物理制御を行います。 45 | - プラグインに含まれる「KawaiiPhysicsノード」をAnimationBPのAnimGraphで使う形です。 46 | - 指定したボーンとそれ以下のボーンをキャラクタの動きに合わせて揺らせます。 47 | - 物理制御用のパラメータは2種類だけなので、エンジン標準の[AnimDynamics](https://docs.unrealengine.com/ja/Engine/Animation/NodeReference/SkeletalControls/AnimDynamics/index.html)に比べて簡単にセットアップできます。 48 | - 球・カプセル・平面コリジョンを追加することができます 49 | - アニメーションエディタのビューポート上で各コリジョンの位置・向き・大きさを調整できます 50 | - 骨の長さを維持するため、仮に計算が破綻しても骨が伸び縮みすることがありません。 51 | - PhysXは使わずにシンプルなアルゴリズムを使用しているため、エンジン標準の物理システムに比べて負荷が低い(はず)です。 52 | 53 | 物理挙動を実装するにあたって参考にした資料 54 | [次期アイドルマスター グラフィクス&アニメーション プログラミング プレビュー](https://cedil.cesa.or.jp/cedil_sessions/view/416) 55 | 56 | ## 動作環境 57 | - UE5.3 ~ 5.5 58 | https://github.com/pafuhana1213/KawaiiPhysics/releases/ 59 | 60 | - UE4.27 61 | https://github.com/pafuhana1213/KawaiiPhysics/releases/tag/20230830-v1.11.1 62 | - UE4.26以前(Pluginのみ) 63 | https://github.com/pafuhana1213/KawaiiPhysics/releases/tag/20201202-v1.7.0 64 | 65 | UE4.26以前でビルドする際は、GetSkeleton()をSkeletonに修正する必要があります。 66 | 67 | UE4.21以前でビルドする場合は、KawaiiPhysicsEditMode.cpp における 68 | GEngine->ConstraintLimitMaterialPrismatic->GetRenderProxy () を 69 | GEngine->ConstraintLimitMaterialPrismatic->GetRenderProxy (false) に修正する必要があります。 70 | 71 | UE4.23以前でビルドする場合は、awaiiPhysics.uplugin における 72 | "Type": "UncookedOnly", を "Type": "DeveloperTool", に修正する必要があります(たぶん)。 73 | 74 | ## 使い方 75 | - **プロジェクト**のPluginsフォルダにKawaiiPhysicsフォルダを入れてください 76 | - 各パラメータについて:[https://github.com/pafuhana1213/KawaiiPhysics/wiki/%E5%90%84%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6](https://github.com/pafuhana1213/KawaiiPhysics/wiki/%E5%90%84%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6--About-each-parameters) 77 | 78 | - BPプロジェクトの場合、パッケージ時にエラーが発生します。お手数ですが、C++プロジェクトに変換するか、下記記事で紹介されている方法をお試しください。 79 | [UE5 KawaiiPhysicsをBlueprintプロジェクトでもpkg化する方法 - PaperSloth’s diary -](https://papersloth.hatenablog.com/entry/2024/02/14/201629) 80 | 81 | ### BPプロジェクトをC++プロジェクトに変換するには 82 | 「C++ クラス ウィザード」からC++コードを追加することで C++プロジェクトに変換可能です。 83 | https://docs.unrealengine.com/5.0/ja/using-the-cplusplus-class-wizard-in-unreal-engine/ 84 | 85 | ただし、Visual StudioなどのC++をビルドできる環境を準備する必要があります。 86 | https://docs.unrealengine.com/5.0/ja/setting-up-visual-studio-development-environment-for-cplusplus-projects-in-unreal-engine/ 87 | 88 | ## サンプル 89 | ![](https://github.com/pafuhana1213/Screenshot/blob/master/KawaiiPhysics3.jpg) 90 | - Content/KawaiiPhysicsSample/KawaiiPhysicsSample 91 | - お借りしたキャラクタ:Gray ちゃん http://rarihoma.xvs.jp/products/graychan 92 | 93 | ## 解説記事・動画 94 | ### 公式 95 | - [揺れ骨用自作AnimNode「Kawaii Physics」の内部実装解説的なもの その1](http://pafuhana1213.hatenablog.com/entry/2019/07/26/171046) 96 | - [#ControlRig を使ったスカートの突き抜け対策と#KawaiiPhysics を併用してみるテスト](https://twitter.com/pafuhana1213/status/1300454762542817280) 97 | 98 | ### 非公式( ありがとうございます!) 99 | - [揺れモノ超ド素人がKawaiiPhysicsを使って、感覚を頼りに女性キャラクターモデルのKawaiiを増す方法まとめ](https://qiita.com/YuukiOgino/items/7f3198a90dab43019f26) 100 | - [揺れものとコントロールリグ UEを使用したバーチャルライブでの実例](https://www.docswell.com/s/indieusgames/K4Q2XJ-2024-06-14-175045) 101 | - [【UE】揺れ物設定(Kawaii Physics)](https://techblog.sumelagi.co.jp/unrealengine/147/) 102 | - 補足:骨ごとの影響度調整は「◯◯◯ by bone length rate」プロパティである程度実現可能です 103 | - [【UE4】Kawaii Physicsチュートリアル#1](https://www.youtube.com/watch?v=hlgXuVML_is) 104 | - [How To Setup Kawaii Physics in Unreal Engine 5](https://dev.epicgames.com/community/learning/tutorials/d1Z9/unreal-engine-how-to-setup-kawaii-physics-in-unreal) 105 | 106 | ## ライセンス 107 | MIT 108 | 109 | ## 作者 110 | [おかず@pafuhana1213](https://twitter.com/pafuhana1213) 111 | 112 | ## ハッシュタグ 113 | [#KawaiiPhysics](https://twitter.com/search?q=%23kawaiiphysics&src=typed_query&f=live) 114 | 115 | ## 履歴 116 | - 2024/12/1 v1.18.0 [詳細はこちら](https://github.com/pafuhana1213/KawaiiPhysics/discussions/150) 117 | - UE5.5 support 118 | - Fix any issues 119 | - 2024/8/16 v1.17.0 [詳細はこちら](https://github.com/pafuhana1213/KawaiiPhysics/discussions/137) 120 | - Additional RootBones 121 | - Box Limit 122 | - PhysicsAsset for Limits 123 | - AnimNotify / AnimNotifyState for NewExternalForce 124 | - BP nodes for NewExternalForce 125 | - NewExternalForce Wind 126 | - Export BoneConstraint DataAsset 127 | - 2024/7/19 v1.16.0 [詳細はこちら](https://github.com/pafuhana1213/KawaiiPhysics/discussions/128) 128 | - New External Force 129 | - 詳細パネルの整理・機能追加 130 | - コンソール変数を追加(レベル上でのデバッグ用) 131 | - DataAsset Update 132 | - 2024/2/8 v1.15.0 [詳細はこちら](https://github.com/pafuhana1213/KawaiiPhysics/discussions/117) 133 | - UE5.4に対応しました 134 | - 2024/2/8 v1.14.0 135 | - 骨間の距離拘束を行う BoneConstraint機能 を実験的に追加しました 136 | - ![image](https://github.com/pafuhana1213/KawaiiPhysics/assets/8957600/af5845e4-65aa-41c1-ba0e-ae466e90d19f) 137 | - 指定した骨間(BoneConstraints/Bone1, 2)の距離を維持しようとします(XPBDを使用)。なお、指定する骨はKawaiiPhysicsの制御対象である必要があります。 138 | - Bone Constrain Iteration Count Before(After) Collision で拘束処理の実行回数を指定できます(結果を収束させるため)。 139 | - DataAssetでも設定可能にしました。試験的にDataAssetに正規表現で拘束対象の骨セットを設定できるようにしています。 140 | ![image](https://github.com/pafuhana1213/KawaiiPhysics/assets/8957600/a43faf14-181e-4b95-8d16-5eb4b687dd12) 141 | - KawaiiPhysicsのAnimNodeが持つDataAssetをピンに公開できるようにしました 142 | - Planar Limitの処理に無駄があったので修正 https://github.com/pafuhana1213/KawaiiPhysics/pull/108 143 | - BoneConstraint対応に伴い、物理処理部分のコードをリファクタリング 144 | - 2023/9/15 v1.13.0 145 | - 物理の空回し(Warm Up)機能・サンプルを追加しました 146 | - https://www.youtube.com/watch?v=stIOjZQh3Qw 147 | - image 148 | - Need Warm Up が true かつ Warm Up Frame( 空回しするフレーム数 ) が 1以上だと Warm Up 処理が行われます 149 | - 実行後は Need Warm Upは false になります 150 | - Warm up Frameが大きいほど安定しますが、物理計算の回数がその分増えるので負荷が上がります 151 | - ![image](https://github.com/pafuhana1213/KawaiiPhysics/assets/8957600/ef55a7fd-699b-48ba-9bd8-13be62d23961) 152 | v1.12.0から対応したAnimNode関数からWarm Upを有効にすることも可能です 153 | - 2023/9/8 v1.12.0 154 | - UE5.3に対応 155 | - といっても、特に何もしていないです 156 | - AnimNode関数から各パラメータの変更・取得を可能に 157 | - ![image](https://github.com/pafuhana1213/KawaiiPhysics/assets/8957600/6ae6098a-64f3-4138-8822-704426dd70f4) 158 | - サンプルを追加(AnimBP_GrayChanKawaiiPhysicsAnimNodeFunction) 159 | - AnimNode関数への対応に伴い、UE4.27のサポートを終了 160 | - 2023/8/30 v1.11.1 161 | - LevelSequence・ControlRigと併用した際のクラッシュを修正 https://github.com/pafuhana1213/KawaiiPhysics/commit/5a2fd868d9ccbd87b3727614faeb861cd7854d8a 162 | - AdjustByAngleLimitを正規化するように https://github.com/pafuhana1213/KawaiiPhysics/commit/9a0576cfa06d37eb0c1b35f57757737ac61288b8 163 | - LimitAngleがピンに公開されてなかった不具合を修正 https://github.com/pafuhana1213/KawaiiPhysics/commit/937a1247f96190700fe06ca7559274059e62d111 164 | - 2023/5/28 v1.11.0 165 | - UE5.2に対応 166 | - といっても、特に何もしていないです 167 | - KawaiiPhysicsとSequencerを併用するサンプルを追加 168 | - SkeletalMeshComponentのAnimClassをAnimBlueprintに設定することと、AnimGraphにSlotノードがあるかを要チェック 169 | - コンパイルしなくてもプロパティの変更を挙動に反映できるように 170 | - CopyNodeDataToPreviewNodeの対応が抜けていたので追加 171 | - UE5.1にてコライダー(~Limits系)のプレビューが上手く動作しない不具合(2つ目以降がコンパイルしないと出てこない)を修正 https://github.com/pafuhana1213/KawaiiPhysics/issues/84 172 | - コライダー(~Limits系)の回転を編集したときにクラッシュする事がある不具合を修正 https://github.com/pafuhana1213/KawaiiPhysics/issues/86 173 | - DataAssetからのLimitsをDeleteで消した際のクラッシュを修正 https://github.com/pafuhana1213/KawaiiPhysics/issues/72 174 | - コライダー(~Limits系)のDrivingBoneに指定しているボーンがLODによって除去された際にクラッシュする不具合を修正 https://github.com/pafuhana1213/KawaiiPhysics/issues/87 175 | - Control Rig, AnimationLayer と併用した際のクラッシュを(たぶん)修正 https://github.com/pafuhana1213/KawaiiPhysics/issues/56 176 | - サンプルのモデルにLOD1・2を追加しました(動作チェック用) 177 | - 2022/12/03 v1.10.0 178 | - UE5.1に対応 179 | - LODでボーン除去している場合に発生するクラッシュの修正 180 | - 一部コードをRider様によってリファクタリング 181 | - 2022/4/11 v1.9.0 182 | - カーブアセットを作らなくても、カーブでのパラメーター編集ができるようになりました https://github.com/pafuhana1213/KawaiiPhysics/pull/32 183 | - ワールドコリジョン機能が入りました。サンプルにも追加してます https://github.com/pafuhana1213/KawaiiPhysics/pull/26 184 | - LOD設定などにより末端のボーンが機能しない場合、DummyBoneが生成されない不具合を修正しました https://github.com/pafuhana1213/KawaiiPhysics/pull/26 185 | - ResetPhysics時に物理設定がリセットされる不具合を修正しました https://github.com/pafuhana1213/KawaiiPhysics/issues/38 186 | - LOD切り替え時のあらぶりを抑える(かもしれない)処理を追加しました。ResetBoneTransformWhenBoneNotFoundを有効にしたら以前の処理に戻ります https://github.com/pafuhana1213/KawaiiPhysics/issues/44 187 | - 2022/4/11 v1.8.0 188 | - UE5正式版に対応 189 | - UE4.26以下のサポートを一旦切りました。 190 | - 2020/12/2 v1.7.0 191 | - UAnimInstance::ResetDynamics(ETeleportType::ResetPhysics)呼び出しでのリセットに対応 192 | - 説明:https://twitter.com/pafuhana1213/status/1334141624666910722 193 | - https://github.com/pafuhana1213/KawaiiPhysics/pull/30 194 | - KazumasaOhashi様、ありがとうございました! 195 | - サンプルレベルの2キーでテストできるようにしました 196 | - 2020/11/17 v.1.6.2 197 | - FKawaiiPhysicsEditMode::DrawHUDが正常に動作していない不具合を修正 198 | - 2020/9/4 v1.6.1 199 | - プロパティのカテゴリ指定忘れによるパッケージ作成エラーの修正 200 | - 2020/8/29 v1.6.0 201 | - 専用のDataAsset(KawaiiPhysicsLimitsDataAsset)でコリジョン設定を管理・流用できるようになりました 202 | - 使い方:https://youtu.be/jnJqRu7zn3c 203 | - 動作実績があまりないのでExperimentalということでお願いします 204 | - UE4.25.3をデフォルトにしました 205 | - 2020/7/28 v1.5.3 206 | - MeshとSkeletonのBoneIndexが違う場合に、正しい長さが取得できなくて、カーブでのパラメータが正常に動作しなくなる不具合修正 207 | - https://github.com/pafuhana1213/KawaiiPhysics/pull/21 208 | - nkinta 様ありがとうございました! 209 | - 2020/5/29 v1.5.2 210 | - v1.5.1 における対応がDummyBoneを考慮してなかった不具合の修正 211 | - 2020/5/29 v1.5.1 212 | - bEnableDebugBoneLengthRate によるデバッグ表示の表示位置がズレていた不具合の修正 213 | - ↑のデバッグ表示のテキスト形式をエンジン標準のボーン名表示と同じに 214 | - https://twitter.com/pafuhana1213/status/1266264162788765696 215 | - 2020/5/29 v1.5.0 216 | - ボーンの向きを設定するBoneForwardAxisプロパティを追加。これはDummyBoneの挙動にのみ影響します 217 | (SAM-tak 様、ありがとうございました!) 218 | - https://twitter.com/pafuhana1213/status/1266224108657762307 219 | - 2020/5/15 v1.4.6 220 | - Rootと同じボーンをExcludeBoneに指定するとクラッシュする不具合を修正 221 | - 不正な設定の場合はノードをWarning または Error表示にする処理を追加 222 | - 技術解説:http://pafuhana1213.hatenablog.com/entry/2020/05/16/173837 223 | - 2020/5/15 v1.4.5 224 | - GravityをComponentSpaceで動作するように変更 225 | (dxd39 様、ありがとうございました!) 226 | - 2020/3/13 v1.4.4 227 | - MacOSでビルドに失敗する不具合の修正 228 | (melMass 様、ありがとうございました!) 229 | - 2020/3/13 v1.4.3 230 | - Package作成に失敗する不具合を修正 231 | - 2020/2/16 v1.4.2 232 | - Standalone実行時に正常に動作しない不具合を修正 233 | - 2020/1/31 v1.4.1 234 | - **SphereLimitのLimitTypeがInnerの場合、Outer設定時に異なりBoneのRadius設定を考慮してなかった不具合の修正 235 | 1.3.1以前の挙動に戻したい方は CVarEnableOldPhysicsMethodSphereLimit を 1 に設定してください** 236 | - 2020/1/31 v1.4.0 237 | - **重力変数の位置更新の計算がgt^2でなくgtになっていたので修正 238 | 1.3.1以前の重力計算を使用したい場合は p.KawaiiPhysics.EnableOldPhysicsMethodGravity を 1 に設定してください** 239 | - 2020/1/31 v1.3.1 240 | - TeleportRotationThresholdの計算にてラジアンと度が混在していたことでWorldRotationのテレポート対応がほぼ機能してなかった不具合を修正 241 | (monguri 様、ありがとうございました!) 242 | - 2020/1/31 v1.3.0 243 | - UE4.24.2 に対応 244 | (TheHoodieGuy02 様、ありがとうございました!) 245 | - 2019/10/29 v1.2.1 246 | - World Damping系を従来処理に差し戻し。30fps時の挙動が更に安定しました 247 | (@seiko_dev 様、ありがとうございました!) 248 | - 2019/10/26 v1.2.0 249 | - 簡易可変フレームレート対応。フレームレート低下時の挙動が少し安定するようになったはず 250 | (@seiko_dev 様、ありがとうございました!) 251 | - 基準フレームレートを設定できるようにしました(デフォルト:60)(正直テスト不足です。何かあったらissueへ 252 | - カーブの調整用に各ボーンの始点からの長さの割合をデバッグ表示するようにしました 253 | - 2019/10/19 v1.1.2 254 | - BoneのScaleが(1,1,1)以外の環境に対応できてなかったので修正 255 | (shop-0761様、ありがとうございました!) 256 | - 2019/9/11 v1.1.1 257 | - Bone.LengthFromRoot の計算が間違っていたのを修正 258 | (KazumasaOhashi様、ありがとうございました!) 259 | - 2019/8/26 v1.1 260 | - WindDirectionalSourceに対応しました(注意:従来のWind設定に対して破壊的変更が入ります) 261 | - 2019/7/20 v1.0.1 262 | - CollisionのOffsetLocationがボーンのRotationを考慮していない不具合の修正 263 | (v1.0 におけるOffsetLocationの挙動が大きく変化します) 264 | - 2019/7/2 v1.0 公開 v1.0 265 | -------------------------------------------------------------------------------- /README_en.md: -------------------------------------------------------------------------------- 1 | # Kawaii Physics 2 | 3 | Japanese doc: 4 | [Japanese Documentation](https://github.com/pafuhana1213/KawaiiPhysics) 5 | 6 | Download (for those without a C++ build environment): 7 | Github : https://github.com/pafuhana1213/KawaiiPhysics/releases/ 8 | Booth : https://pafuhana1213.booth.pm/items/5943534 9 | 10 | ## Discussions 11 | - [Update Information](https://github.com/pafuhana1213/KawaiiPhysics/discussions/categories/announcements-%E3%82%A2%E3%83%8A%E3%82%A6%E3%83%B3%E3%82%B9) 12 | - [Requests & Ideas](https://github.com/pafuhana1213/KawaiiPhysics/discussions/categories/ideas-%E8%A6%81%E6%9C%9B-%E3%82%A2%E3%82%A4%E3%83%87%E3%82%A2) 13 | - [Questions & Q&A](https://github.com/pafuhana1213/KawaiiPhysics/discussions/categories/q-a) 14 | - [Share Your Work!](https://github.com/pafuhana1213/KawaiiPhysics/discussions/65) 15 | - [General Discussion & Advice](https://github.com/pafuhana1213/KawaiiPhysics/discussions/66) 16 | - [Feature and Sample Requests](https://github.com/pafuhana1213/KawaiiPhysics/discussions/67) 17 | 18 | ## Bug Reports 19 | [Report Bugs](https://github.com/pafuhana1213/KawaiiPhysics/issues) 20 | 21 | ## Adoption Records 22 | [Adoption Records](https://github.com/pafuhana1213/KawaiiPhysics/wiki/%E6%8E%A1%E7%94%A8%E5%AE%9F%E7%B8%BE-Adoption) 23 | 24 | ## Introduction 25 | Kawaii Physics is a pseudo-physics plugin for Unreal Engine 4 and 5. It allows you to create simple and cute animations for objects like hair, skirts, and breasts. 26 | 27 | ![Kawaii Physics 1](https://github.com/pafuhana1213/Screenshot/blob/master/KawaiiPhysics1.gif) 28 | Character used: Gray-chan [Gray-chan](http://rarihoma.xvs.jp/products/graychan) 29 | 30 | ![Kawaii Physics 0](https://github.com/pafuhana1213/Screenshot/blob/master/KawaiiPhysics0.gif) 31 | [YouTube Video](https://www.youtube.com/watch?v=UvpEIBGegvs) 32 | Character used: Mirai Komachi [Mirai Komachi](https://www.bandainamcostudios.com/works/miraikomachi/) 33 | 34 | ## Features 35 | ![Kawaii Physics 2](https://github.com/pafuhana1213/Screenshot/blob/master/KawaiiPhysics2.jpg) 36 | ![Kawaii Physics 4](https://github.com/pafuhana1213/Screenshot/blob/master/KawaiiPhysics4.gif) 37 | - Respects the original shape while controlling physics based on the animation and movement/rotation of the SkeletalMeshComponent. 38 | - Use the "KawaiiPhysics Node" included in the plugin in the AnimGraph of AnimationBP. 39 | - You can make specified bones and their child bones move according to the character's motion. 40 | - With only two types of physics control parameters, it is easier to set up compared to the engine's standard [AnimDynamics](https://docs.unrealengine.com/en-US/Engine/Animation/NodeReference/SkeletalControls/AnimDynamics/index.html). 41 | - You can add sphere, capsule, and plane collisions. 42 | - Adjust the position, orientation, and size of each collision in the animation editor's viewport. 43 | - Maintains bone length, preventing bones from stretching or shrinking even if calculations fail. 44 | - Uses a simple algorithm without PhysX, which should result in lower overhead compared to the engine's standard physics system. 45 | 46 | ## Reference Material for Implementing Physics Behavior 47 | [Next Generation Idolmaster Graphics & Animation Programming Preview](https://cedil.cesa.or.jp/cedil_sessions/view/416) 48 | 49 | ## Operating Environment 50 | - UE5.3 ~ 5.5 51 | [KawaiiPhysics Releases](https://github.com/pafuhana1213/KawaiiPhysics/releases/) 52 | - UE4.27 53 | [KawaiiPhysics Release for UE4.27](https://github.com/pafuhana1213/KawaiiPhysics/releases/tag/20230830-v1.11.1) 54 | - UE4.26 and earlier (Plugin only) 55 | [KawaiiPhysics Release for UE4.26 and earlier](https://github.com/pafuhana1213/KawaiiPhysics/releases/tag/20201202-v1.7.0) 56 | 57 | When building for UE4.26 and earlier, you need to modify GetSkeleton() to Skeleton. 58 | 59 | When building for UE4.21 and earlier, you need to modify GEngine->ConstraintLimitMaterialPrismatic->GetRenderProxy() to GEngine->ConstraintLimitMaterialPrismatic->GetRenderProxy(false) in KawaiiPhysicsEditMode.cpp. 60 | 61 | When building for UE4.23 and earlier, you need to modify "Type": "UncookedOnly" to "Type": "DeveloperTool" in KawaiiPhysics.uplugin (probably). 62 | 63 | ## How to Use 64 | - Place the KawaiiPhysics folder in your project's Plugins folder. 65 | - About each parameter: [Parameter Details]([https://github.com/pafuhana1213/KawaiiPhysics/wiki/%E5%90%84%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6](https://github.com/pafuhana1213/KawaiiPhysics/wiki/%E5%90%84%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6--About-each-parameters)) 66 | 67 | - For BP projects, errors occur during packaging. Please either convert to a C++ project or try the method introduced in the following article. 68 | [How to Package UE5 KawaiiPhysics for Blueprint Projects - PaperSloth’s Diary](https://papersloth.hatenablog.com/entry/2024/02/14/201629) 69 | 70 | ### Converting BP Projects to C++ Projects 71 | You can convert to a C++ project by adding C++ code from the "C++ Class Wizard". 72 | [C++ Class Wizard Documentation](https://docs.unrealengine.com/5.0/en-US/using-the-cplusplus-class-wizard-in-unreal-engine/) 73 | 74 | However, you need to prepare an environment that can build C++, such as Visual Studio. 75 | [Setting Up Visual Studio Development Environment for C++ Projects](https://docs.unrealengine.com/5.0/en-US/setting-up-visual-studio-development-environment-for-cplusplus-projects-in-unreal-engine/) 76 | 77 | ## Samples 78 | ![Kawaii Physics 3](https://github.com/pafuhana1213/Screenshot/blob/master/KawaiiPhysics3.jpg) 79 | - Content/KawaiiPhysicsSample/KawaiiPhysicsSample 80 | - Character used: Gray-chan [Gray-chan](http://rarihoma.xvs.jp/products/graychan) 81 | 82 | ## Articles & Videos 83 | ### Official 84 | - [Explanation of the Internal Implementation of Custom AnimNode "Kawaii Physics" Part 1](http://pafuhana1213.hatenablog.com/entry/2019/07/26/171046) 85 | - [Test of Using #ControlRig to Prevent Skirt Clipping and Combining with #KawaiiPhysics](https://twitter.com/pafuhana1213/status/1300454762542817280) 86 | 87 | ### Unofficial (Thank you!) 88 | - [How a Complete Amateur in Jiggle Physics Used KawaiiPhysics to Make a Female Character Model More Kawaii Based on Intuition](https://qiita.com/YuukiOgino/items/7f3198a90dab43019f26) 89 | - [Jiggle Physics and Control Rig Examples from a Virtual Live Using UE](https://www.docswell.com/s/indieusgames/K4Q2XJ-2024-06-14-175045) 90 | - [Setting Jiggle Physics with Kawaii Physics in UE](https://techblog.sumelagi.co.jp/unrealengine/147/) 91 | - Note: You can adjust the influence per bone to some extent with the "◯◯◯ by bone length rate" property. 92 | - [Kawaii Physics Tutorial #1](https://www.youtube.com/watch?v=hlgXuVML_is) 93 | - [How to Set Up Kawaii Physics in Unreal Engine 5](https://dev.epicgames.com/community/learning/tutorials/d1Z9/unreal-engine-how-to-setup-kawaii-physics-in-unreal) 94 | 95 | ## License 96 | MIT 97 | 98 | ## Author 99 | [Okazu @pafuhana1213](https://twitter.com/pafuhana1213) 100 | 101 | ## Hashtag 102 | [#KawaiiPhysics](https://twitter.com/search?q=%23kawaiiphysics&src=typed_query&f=live) 103 | 104 | ## History 105 | - 2024/12/1 v1.18.0 [Details Here](https://github.com/pafuhana1213/KawaiiPhysics/discussions/150) 106 | - UE5.5 support 107 | - fix any issues 108 | - 2024/8/16 v1.17.0 [Details Here](https://github.com/pafuhana1213/KawaiiPhysics/discussions/137) 109 | - Additional RootBones 110 | - Box Limit 111 | - PhysicsAsset for Limits 112 | - AnimNotify / AnimNotifyState for NewExternalForce 113 | - BP nodes for NewExternalForce 114 | - NewExternalForce Wind 115 | - Export BoneConstraint DataAsset 116 | - 2024/7/19 v1.16.0 [Details Here](https://github.com/pafuhana1213/KawaiiPhysics/discussions/128) 117 | - New External Force 118 | - Organized and added functions to the Details Panel 119 | - Added console variables for debugging at the level 120 | - DataAsset Update 121 | - 2024/2/8 v1.15.0 [Details Here](https://github.com/pafuhana1213/KawaiiPhysics/discussions/117) 122 | - Added support for UE5.4 123 | - 2024/2/8 v1.14.0 124 | - Experimental addition of BoneConstraint function to constrain distances between bones 125 | - ![image](https://github.com/pafuhana1213/KawaiiPhysics/assets/8957600/af5845e4-65aa-41c1-ba0e-ae466e90d19f) 126 | - Maintains the distance between specified bones (BoneConstraints/Bone1, 2) using XPBD. Note that the specified bones must be controlled by KawaiiPhysics. 127 | - You can specify the number of iterations for constraint processing with Bone Constrain Iteration Count Before(After) Collision. 128 | - Now configurable in DataAsset. Added experimental feature to set bone sets for constraints using regular expressions. 129 | ![image](https://github.com/pafuhana1213/KawaiiPhysics/assets/8957600/a43faf14-181e-4b95-8d16-5eb4b687dd12) 130 | - Exposed the DataAsset held by KawaiiPhysics AnimNode to the pin 131 | - Fixed inefficiencies in Planar Limit processing [PR 108](https://github.com/pafuhana1213/KawaiiPhysics/pull/108) 132 | - Refactored the code of the physics processing part to accommodate BoneConstraint 133 | - 2023/9/15 v1.13.0 134 | - Added warm-up function and sample for initial physical calculations 135 | - [Warm Up Video](https://www.youtube.com/watch?v=stIOjZQh3Qw) 136 | - ![image](https://github.com/pafuhana1213/KawaiiPhysics/assets/8957600/e140f3b9-232a-4026-a0b0-c8e1e54a492f) 137 | - Warm Up is enabled when Need Warm Up is true and Warm Up Frame (number of frames for warm-up) is 1 or more. 138 | - Need Warm Up becomes false after execution. 139 | - Larger Warm Up Frame results in more stability, but increases the load due to more physical calculations. 140 | - ![image](https://github.com/pafuhana1213/KawaiiPhysics/assets/8957600/ef55a7fd-699b-48ba-9bd8-13be62d23961) 141 | Warm Up can also be enabled from the AnimNode function since v1.12.0. 142 | - 2023/9/8 v1.12.0 143 | - Support for UE5.3 144 | - Nothing specific was done. 145 | - Parameters can now be changed and retrieved from AnimNode functions. 146 | - ![image](https://github.com/pafuhana1213/KawaiiPhysics/assets/8957600/6ae6098a-64f3-4138-8822-704426dd70f4) 147 | - Added sample (AnimBP_GrayChanKawaiiPhysicsAnimNodeFunction). 148 | - Ended support for UE4.27 due to support for AnimNode functions. 149 | - 2023/8/30 v1.11.1 150 | - Fixed crash when used with LevelSequence and ControlRig [Commit](https://github.com/pafuhana1213/KawaiiPhysics/commit/5a2fd868d9ccbd87b3727614faeb861cd7854d8a) 151 | - Normalize AdjustByAngleLimit [Commit](https://github.com/pafuhana1213/KawaiiPhysics/commit/9a0576cfa06d37eb0c1b35f57757737ac61288b8) 152 | - Fixed issue where LimitAngle was not exposed to the pin [Commit](https://github.com/pafuhana1213/KawaiiPhysics/commit/937a1247f96190700fe06ca7559274059e62d111) 153 | - 2023/5/28 v1.11.0 154 | - Support for UE5.2 155 | - Nothing specific was done. 156 | - Added sample combining KawaiiPhysics and Sequencer. 157 | - Check if the SkeletalMeshComponent's AnimClass is set to AnimBlueprint and if there is a Slot node in the AnimGraph. 158 | - Made property changes reflect in behavior without compilation. 159 | - Added support for CopyNodeDataToPreviewNode which was missing. 160 | - Fixed issue where collider (Limits) preview did not work properly in UE5.1 (second and subsequent colliders did not appear without compilation) [Issue 84](https://github.com/pafuhana1213/KawaiiPhysics/issues/84) 161 | - Fixed crash when editing rotation of collider (Limits) [Issue 86](https://github.com/pafuhana1213/KawaiiPhysics/issues/86) 162 | - Fixed crash when deleting Limits from DataAsset [Issue 72](https://github.com/pafuhana1213/KawaiiPhysics/issues/72) 163 | - Fixed crash when DrivingBone of collider (Limits) is removed by LOD [Issue 87](https://github.com/pafuhana1213/KawaiiPhysics/issues/87) 164 | - (Probably) fixed crash when used with Control Rig and AnimationLayer [Issue 56](https://github.com/pafuhana1213/KawaiiPhysics/issues/56) 165 | - Added LOD1 and 2 to sample model for operation check. 166 | - 2022/12/03 v1.10.0 167 | - Support for UE5.1 168 | - Fixed crash when bones are removed by LOD. 169 | - Some code refactored by Rider. 170 | - 2022/4/11 v1.9.0 171 | - Parameters can now be edited with curves without creating a curve asset [PR 32](https://github.com/pafuhana1213/KawaiiPhysics/pull/32) 172 | - Added world collision feature and sample [PR 26](https://github.com/pafuhana1213/KawaiiPhysics/pull/26) 173 | - Fixed issue where DummyBone is not generated when the terminal bone does not function due to LOD settings [PR 26](https://github.com/pafuhana1213/KawaiiPhysics/pull/26) 174 | - Fixed issue where physics settings are reset during ResetPhysics [Issue 38](https://github.com/pafuhana1213/KawaiiPhysics/issues/38) 175 | - Added process to suppress erratic behavior during LOD switching. ResetBoneTransformWhenBoneNotFound can be enabled to revert to the previous process [Issue 44](https://github.com/pafuhana1213/KawaiiPhysics/issues/44) 176 | - 2022/4/11 v1.8.0 177 | - Support for UE5 official release. 178 | - Temporarily dropped support for UE4.26 and earlier. 179 | - 2020/12/2 v1.7.0 180 | - Added support for UAnimInstance::ResetDynamics(ETeleportType::ResetPhysics). 181 | - Explanation: [Twitter](https://twitter.com/pafuhana1213/status/1334141624666910722) 182 | - [PR 30](https://github.com/pafuhana1213/KawaiiPhysics/pull/30) 183 | - Thanks to KazumasaOhashi! 184 | - You can test with key 2 in the sample level. 185 | - 2020/11/17 v.1.6.2 186 | - Fixed issue where FKawaiiPhysicsEditMode::DrawHUD was not functioning correctly. 187 | - 2020/9/4 v1.6.1 188 | - Fixed error in package creation due to missing property category specification. 189 | - 2020/8/29 v1.6.0 190 | - Added functionality to manage and reuse collision settings with a dedicated DataAsset (KawaiiPhysicsLimitsDataAsset). 191 | - Usage: [Video](https://youtu.be/jnJqRu7zn3c) 192 | - Not much operational experience, so consider it experimental. 193 | - Set UE4.25.3 as default. 194 | - 2020/7/28 v1.5.3 195 | - Fixed issue where correct length could not be obtained and parameters with curves did not work properly when BoneIndex of Mesh and Skeleton differ [PR 21](https://github.com/pafuhana1213/KawaiiPhysics/pull/21) 196 | - Thanks to nkinta! 197 | - 2020/5/29 v1.5.2 198 | - Fixed issue where response in v1.5.1 did not consider DummyBone. 199 | - 2020/5/29 v1.5.1 200 | - Fixed issue where debug display by bEnableDebugBoneLengthRate was misaligned. 201 | - Unified text format of debug display with engine standard bone name display [Twitter](https://twitter.com/pafuhana1213/status/1266264162788765696) 202 | - 2020/5/29 v1.5.0 203 | - Added BoneForwardAxis property to set bone orientation, affecting DummyBone behavior only. 204 | (Thanks to SAM-tak!) 205 | - [Twitter](https://twitter.com/pafuhana1213/status/1266224108657762307) 206 | - 2020/5/15 v1.4.6 207 | - Fixed crash when the same bone as Root is specified in ExcludeBone. 208 | - Added process to display node as Warning or Error in case of invalid settings. 209 | - Technical explanation: [Blog](http://pafuhana1213.hatenablog.com/entry/2020/05/16/173837) 210 | - 2020/5/15 v1.4.5 211 | - Changed Gravity to operate in ComponentSpace. 212 | (Thanks to dxd39!) 213 | - 2020/3/13 v1.4.4 214 | - Fixed build failure on MacOS. 215 | (Thanks to melMass!) 216 | - 2020/3/13 v1.4.3 217 | - Fixed issue with package creation failure. 218 | - 2020/2/16 v1.4.2 219 | - Fixed issue where it did not function properly during standalone execution. 220 | - 2020/1/31 v1.4.1 221 | - Fixed issue where Radius setting of bone was not considered when LimitType of SphereLimit was Inner. 222 | Set CVarEnableOldPhysicsMethodSphereLimit to 1 to revert to behavior before v1.3.1. 223 | - 2020/1/31 v1.4.0 224 | - Fixed calculation of position update of gravity variable to gt instead of gt^2. 225 | Set p.KawaiiPhysics.EnableOldPhysicsMethodGravity to 1 to use gravity calculation before v1.3.1. 226 | - 2020/1/31 v1.3.1 227 | - Fixed issue where radian and degree were mixed in the calculation of TeleportRotationThreshold, causing almost no function of WorldRotation teleport support. 228 | (Thanks to monguri!) 229 | - 2020/1/31 v1.3.0 230 | - Support for UE4.24.2. 231 | (Thanks to TheHoodieGuy02!) 232 | - 2019/10/29 v1.2.1 233 | - Reverted World Damping to previous processing, making behavior more stable at 30fps. 234 | (Thanks to @seiko_dev!) 235 | - 2019/10/26 v1.2.0 236 | - Added simple variable frame rate support. Behavior should be slightly more stable during frame rate drops. 237 | (Thanks to @seiko_dev!) 238 | - You can now set the reference frame rate (default: 60). (Honestly, this is under-tested. If there are any issues, please report them to the issue tracker.) 239 | - Added debug display of the percentage of length from the starting point of each bone for curve adjustment. 240 | - 2019/10/19 v1.1.2 241 | - Fixed issue where Bone.Scale was not supported for scales other than (1,1,1). 242 | (Thanks to shop-0761!) 243 | - 2019/9/11 v1.1.1 244 | - Fixed incorrect calculation of Bone.LengthFromRoot. 245 | (Thanks to KazumasaOhashi!) 246 | - 2019/8/26 v1.1 247 | - Added support for WindDirectionalSource (Note: destructive changes to existing Wind settings). 248 | - 2019/7/20 v1.0.1 249 | - Fixed issue where Collision's OffsetLocation did not consider bone rotation. 250 | (Behavior of OffsetLocation changes significantly from v1.0.) 251 | - 2019/7/2 v1.0 Initial release. 252 | --------------------------------------------------------------------------------