• RuntimesUnreal
  • IK GroundConstraint Unreal Engine( currently using UE5.4 )

Hi everyone, I'm looking to replicate the SkeletonUtility GroundConstraint feature, as demonstrated in this video, but within Unreal Engine. Could anyone assist me with this?

  • jetmouse ответили на это сообщение.
    Related Discussions
    ...

    To replicate the SkeletonUtility GroundConstraint feature in Unreal Engine, you can follow these steps:

    1. Understand the Concept: The SkeletonUtilityGroundConstraint in Unity modifies the position of a bone, typically an IK target bone, to ensure it stays above the ground. This is achieved by performing raycasts to detect the ground and adjusting the bone's position accordingly.

    2. Set Up IK in Spine: Ensure your character's skeleton in Spine has IK constraints set up for the feet. This will allow you to control the feet positions programmatically.

    3. Implement Raycasting in Unreal:

      • Perform raycasts from the feet towards the ground to detect the ground's position.
      • Adjust the IK target bones' positions based on the raycast results to keep the feet above the ground.
    4. Modify Bone Positions in Unreal:

      • Use the USpineSkeletonComponent to access and modify the skeleton's bones.
      • You can get the spine::Skeleton from the USpineSkeletonComponent via USpineSkeletonComponent::GetSkeleton().
      • Find the IK constraints by name using spine::Skeleton::findIkConstraint().
      • Set the new positions for the IK target bones using IkConstraint::setMix().

    Here is a basic example of how you might implement this in C++:

    #include "YourGameCharacter.h"
    #include "SpineSkeletonComponent.h"
    #include "Engine/World.h"
    #include "DrawDebugHelpers.h"
    
    void AYourGameCharacter::UpdateFootIK()
    {
        USpineSkeletonComponent* SpineComponent = FindComponentByClass<USpineSkeletonComponent>();
        if (!SpineComponent) return;
    
        spine::Skeleton* Skeleton = SpineComponent->GetSkeleton();
        if (!Skeleton) return;
    
        spine::IkConstraint* LeftFootIK = Skeleton->findIkConstraint("leftFootIK");
        spine::IkConstraint* RightFootIK = Skeleton->findIkConstraint("rightFootIK");
    
        FVector LeftFootPosition = GetBoneWorldPosition("leftFoot");
        FVector RightFootPosition = GetBoneWorldPosition("rightFoot");
    
        FVector LeftFootGroundPosition = PerformRaycast(LeftFootPosition);
        FVector RightFootGroundPosition = PerformRaycast(RightFootPosition);
    
        if (LeftFootIK)
        {
            LeftFootIK->getTarget()->setX(LeftFootGroundPosition.X);
            LeftFootIK->getTarget()->setY(LeftFootGroundPosition.Y);
        }
    
        if (RightFootIK)
        {
            RightFootIK->getTarget()->setX(RightFootGroundPosition.X);
            RightFootIK->getTarget()->setY(RightFootGroundPosition.Y);
        }
    }
    
    FVector AYourGameCharacter::PerformRaycast(FVector StartPosition)
    {
        FVector EndPosition = StartPosition - FVector(0, 0, 1000); // Cast downwards
        FHitResult HitResult;
        GetWorld()->LineTraceSingleByChannel(HitResult, StartPosition, EndPosition, ECC_Visibility);
    
        if (HitResult.bBlockingHit)
        {
            return HitResult.Location;
        }
    
        return StartPosition; // Return original position if no hit
    }
    
    FVector AYourGameCharacter::GetBoneWorldPosition(FName BoneName)
    {
        USpineSkeletonComponent* SpineComponent = FindComponentByClass<USpineSkeletonComponent>();
        if (!SpineComponent) return FVector::ZeroVector;
    
        FTransform BoneTransform = SpineComponent->GetBoneTransform(BoneName);
        return BoneTransform.GetLocation();
    }

    This code performs raycasts from the feet to the ground and adjusts the IK target bones' positions accordingly. You will need to adapt it to your specific setup and ensure the bone names and IK constraint names match those in your Spine project.

    • jetmouse ответили на это сообщение.

      Spinebot already tried ChatGPT and gave me the same result...

      jetmouse can you show me how to do it in blueprint class ?

      You'd need to replicate the logic in the spine-unity SkeletonUtilityGroundConstraint example, source code here:
      EsotericSoftware/spine-runtimesblob/4.2/spine-unity/Assets/Spine%20Examples/Scripts/Sample%20Components/SkeletonUtility%20Modules/SkeletonUtilityGroundConstraint.cs

      Doing that in UE might be pretty involved, at least as much as it is in Unity. My colleague Mario may have more input, but Friday is over in his time zone so he probably won't be along until Monday.

      I still need help with this can someone show me an example how to do in unreal?
      I'd appreciate that.

      This is currently not possible with Blueprints. Not just because of Spine, but also because of UE, which doesn't expose all of the necessary API as Blueprint callable functions. Sadly, Blueprints lurs in people from Unity with C# experience, only for them to find out, that Blueprints aren't great for anything complex. I'm afraid you'll have to either bite the C++ bullet, in which case Spinebot's suggestion is spot on, or you'll have to consider going with Unity.