Final IK

It has a target but not an aim transform. It has both and works correctly with weapons though (at least it does with the pistol I tested).
 
Hi I followed the steps from the Final IK integration guide lines: https://opsive.com/support/documentation/ultimate-character-controller/integrations/final-ik/ but I am having an issue with the interaction system.

It says that simply by adding the interaction system to the character and an interaction object to the interactable it should work. But when I interact with my button it moves the platform but the IK interaction does not happen.

Looking at the code I realised that I was suppose to add a Ability IK Target to the interactable. It is probably a good idea to add that in the docs, because I heard of other people saying they couldn't get it to work. I mean it sounds obvious now but for people who never used IK before it might not be.

I am also getting an error once the ability finishes. I think you are missing a "return" somewhere.

This is your code:

C#:
public override void SetAbilityIKTarget(Transform target, IKGoal ikGoal, float duration)
        {
            if (m_InteractionSystem == null) {
                Debug.LogError("Error: The character must have the Interaction System component in order for the ability to set an IK target.");
                return;
            }

            if (target == null) {
                m_InteractionSystem.PauseInteraction(IKGoalToEffector(ikGoal));
            }

            var interactionObject = target.gameObject.GetCachedComponent<InteractionObject>();
            if (interactionObject == null) {
                Debug.LogError("Error: The target " + target.name + " must have the FinalIK Interaction Object attached.");
                return;
            }

            m_InteractionSystem.StartInteraction(IKGoalToEffector(ikGoal), interactionObject, false);
        }

When the target is null then calling target.gameObject will return an error. I am not sure what you should do to fix this the correct way. My guess is add a return statement if target is null.

I added the return in your source code and it seems to work wothout any problems now
 
I spoke too soon, I get a weird behavior if I interact again while the animation is playing. The character starts pressing in the look direction. No idea how I would fix this except make the interact ability not start until it has finished. But I don't know how to do that either.
 
Last edited:
You're right - it needs a return and I'll add a note about the Ability IK Target.

I get a weird behavior if I interact again while the animation is playing.
So you are interacting, and then you try to interact again while the current interact ability is active? The interact ability isn't concurrent so it shouldn't be able to start a second time.
 
I believe I found the cause of all the problems I had making the IK interaction.

First of all the interaction should stop and not pause when the target is null. So I changed this functions in the Final IK bridge component.

C#:
public override void SetAbilityIKTarget(Transform target, IKGoal ikGoal, float duration)
        {
            if (m_InteractionSystem == null) {
                Debug.LogError("Error: The character must have the Interaction System component in order for the ability to set an IK target.");
                return;
            }

            if (target == null) {
                m_InteractionSystem.StopInteraction(IKGoalToEffector(ikGoal));
                //m_InteractionSystem.PauseInteraction(IKGoalToEffector(ikGoal));
                return;
            }

            var interactionObject = target.gameObject.GetCachedComponent<InteractionObject>();
            if (interactionObject == null) {
                Debug.LogError("Error: The target " + target.name + " must have the FinalIK Interaction Object attached.");
                return;
            }

            m_InteractionSystem.StartInteraction(IKGoalToEffector(ikGoal), interactionObject, false);
        }

Then the on the Ability IK Target component (attached to the interactable object), you have to make sure its "duration" is just above (Lower or equal won't work) the Interaction Object component (by Final IK) duration (controlled by the "Weight Curves" max length).

The next issue is with the interaction OnAnimatorInteractionComplete Event. The interaction ability can stop while the IK Interaction still hasn't finished. This means the ability can start again even though the IK interaction hasn't completed which result in weird behaviors. Instead of using the animator event to complete the ability you can use the duration of the interaction (as long as the duration is the same for all interaction that's fine, otherwise just add another interaction ability to your character and assign it a different ID).

I think the only way to fix the duration disparity between Interact Ability / Ability IK Target / Interaction Object would be to change the code even more... not sure if it is worth it though since you can deal with it just by being careful.

I hope that helps.
 
Actually, I hadn't realised before because the interaction was so fast. There is definitely some jitter. Especially in the head of the character. Which makes me think that the look At IK and interaction system are fighting each other to move the character IK. Maybe they are updated at the same time?
I'll need some free time to look into it in more detail, if anyone fins the cause please let us know here.
 
I think I found the cause of the Jitter!

The Interaction system updates the look At during Update, not sure why:

C#:
void Update() {
            if (fullBody == null) return;
            
            UpdateTriggerEventBroadcasting();
            
            Raycasting();
            
            // Finding the triggers in contact and in range
            triggersInRange.Clear();
            bestRangeIndexes.Clear();

            for (int i = 0; i < inContact.Count; i++) {
                int bestRangeIndex = -1;

                if (inContact[i] != null && inContact[i].gameObject.activeInHierarchy && inContact[i].enabled && ContactIsInRange(i, out bestRangeIndex)) {
                    triggersInRange.Add(inContact[i]);
                    bestRangeIndexes.Add(bestRangeIndex);
                }
            }

            // Update LookAt
            lookAt.Update();
        }

This clashes with Final IK bridge the wants Look At to be only updated in Fixed update.

So how do we fix this?

The easy solution is to comment out the "lookAt.Update();" line but if possible I do not want to change the Final IK source code. Be aware that if you did that then the "Look At Target" on the Interaction Object won't work anymore.

Solution two would have been to disable the Interaction System component and copy the content of the Update function from InteractionSystem to Final IK bridge. The problem is that some methods in Update are private, so due to restriction levels, that is not possible.

Solution 3 contact the devs at RootMotion and ask them for guidance.

@Justin if you come up with other ideas do let me know
 
The next issue is with the interaction OnAnimatorInteractionComplete Event. The interaction ability can stop while the IK Interaction still hasn't finished. This means the ability can start again even though the IK interaction hasn't completed which result in weird behaviors. Instead of using the animator event to complete the ability you can use the duration of the interaction (as long as the duration is the same for all interaction that's fine, otherwise just add another interaction ability to your character and assign it a different ID).
That's a good catch. In the interact ability I'll track the scheduled event for disabling the target and if the interact has been completed before the ik duration then it'll stop the interaction early.

This clashes with Final IK bridge the wants Look At to be only updated in Fixed update.
Interesting. I think contacting RootMotion is a good option to see why that is the case, but maybe there is a way to check if the FinalIK interaction component is active and if it is then LookAt shouldn't be called?
 
I found another weird thing with FinalIK grounder and moving platforms.

I haven't really looked into why it happens but the character goes through the platform:

MovingPlatformIKBug.gif
When I change the parameter "Max step" my character goes more or less through the platform (higher max step then more I go through the platform).
When the max step is set to something very high (example 5) my character falls through the platform.

I haven't really checked but my guess is that the grounder FBBIK component updates in Update while the character/moving platform update in FixedUpdate. Shouldn't grounder FBBIK be disabled and then updated manually in FinalIK Bridge like the other IK scripts?
 
The controller doesn't directly need to set anything on the grounder component and during my testing I found that it worked without any issues so that's why I didn't manually update it. I didn't try a moving platform though - if you're finding that it does need to be manually updated I can include that.
 
I was actually looking too much into it, thinking that something was wrong with the code. It took me a few hours of tinkering with the code to realize everything was good. The GrounderFBBIK component always updates at the same rate as FBBIK.

It turns out I had to add the "MovingPlatform" layer to the grounder solver... I wish I had thought of that before modifying the source code.

Everything works fine now.
 
I am trying to get a normal Humanoid FBBIK and Pseudo3D (2.5D) Aim IK and Look At IK set up along with a Grounder for the feet. Ive got everything pretty much done and working however, the Aim and/or Look At IK(s) seem to be giving some issues as the arms dont seem to add up in the same positions and rotations compared to aiming with the normal Character IK script and end up throwing the hands off center from the head and the torso making it impossible to position the gun in a position and rotation that fits the hands of the character while being centered. Is there a specific way to set up the Final IK setup to be closer to the normal Character IK script and is there a way to properly set it up for a Pseudo 3D setup where the character's Aim Rotation is limited to one axis (I do have the Restrict Rotation ability added).

I read about the Limb IK but I cant get it to work without causing bone position/rotation glitches.

Here are some screenshots on how my character is set up:



Please any help on the matter would be greatly appreciated.
 

Attachments

  • UCC_FinalIK_AimIssue_1.jpg
    UCC_FinalIK_AimIssue_1.jpg
    212.3 KB · Views: 15
  • UCC_FinalIK_AimIssue_2.jpg
    UCC_FinalIK_AimIssue_2.jpg
    176.3 KB · Views: 13
  • UCC_FinalIK_AimIssue_3.jpg
    UCC_FinalIK_AimIssue_3.jpg
    180 KB · Views: 12
Here is the rest of my setup:
 

Attachments

  • UCC_FinalIK_AimIssue_4.jpg
    UCC_FinalIK_AimIssue_4.jpg
    181.1 KB · Views: 10
  • UCC_FinalIK_AimIssue_5.jpg
    UCC_FinalIK_AimIssue_5.jpg
    204.6 KB · Views: 11
  • UCC_FinalIK_AimIssue_6.jpg
    UCC_FinalIK_AimIssue_6.jpg
    153.1 KB · Views: 11
Can TPC use Final IK's Interactions Triggers when using the Interaction system? I downloaded the integration package but there is no scene with it. It would be great if a small scene was included just demonstrating how you have set up your character to use the Interaction system in conjunction with interact abilities (as mentioned in the documentation).
 
Hi @Deckard_89,

I'm not sure what you mean by interaction triggers. I personally made it work for a button with the following scripts:
"Interactable" "Interaction Object" "Ability Start Location" "Ability IK Target" and "Interaction Target"

You can read the posts I made just above to see how I achieved it, and what problems I had to overcome and why.

I do agree with you that a little demo scene would be nice, because it's not straight forward.

Let me know if you have problems. One that comes up in my head is the rotation speed to set the character in front of the button. You will probably need a state that increases the "Motor Rotation Speed" when the Interact ability is active.
 
Hi @Deckard_89,

I'm not sure what you mean by interaction triggers. I personally made it work for a button with the following scripts:
"Interactable" "Interaction Object" "Ability Start Location" "Ability IK Target" and "Interaction Target"

You can read the posts I made just above to see how I achieved it, and what problems I had to overcome and why.

I do agree with you that a little demo scene would be nice, because it's not straight forward.

Let me know if you have problems. One that comes up in my head is the rotation speed to set the character in front of the button. You will probably need a state that increases the "Motor Rotation Speed" when the Interact ability is active.

Hi, thanks for your input. Final IK's Interaction Triggers allow the Interaction System to be used while also limiting the interaction itself to the player being at a certain angle, to prevent improper stretching and other glitches. I assume this would be faster than having to use the Ability Start Location and Move To abilities, because the interaction would start immediately without the character having to move into a certain position. A tutorial can be found here:

 
Hi @Deckard_89,

I see... To me it seems like Ability start Location and Final Ik Interaction trigger have the same purpose. You would use one or the other depending on the result you want.

The interact ability on the Characer Controller has built-in functionality to make sure it works with Ability start Location. Once you are inside the trigger and press the interact button your character is moved to a valid position and rotation before the interaction animation starts. This is very useful for interaction animations that are not IK since the character needs to be in the perfect position/rotation.

If you do not like this approach my guess would be to create your own interaction ability that works with Interaction trigger. It should not be too complicated. Simply copy the default interaction ability script and change some of the functions. The main one would be CanUse (I think that's the name) where you would check if the character has a valid position/rotation from the FinalIK interaction trigger from the list of triggers.

Feel free to post your solution here since it might help other people.
 
Top