IK Controls are now out of beta!

Hi,

I’ve been messing around with IKControls for our new game and it seems that IK done on the client does not replicate to the server or other clients the same way normal animations do. For reference, the IKControl instances are all created on the server, but controlled on the client.
If the Target property is set on the server it does however replicate correctly to all clients but this is not usable for us.
Is this intended behavior?

cc @sg3cko

3 Likes

It depends. Is your target instance created on the server?

Everything is created on the server, yes. I’m trying to set the target property on the client though, setting it on the server and some players getting several hundred milliseconds of latency for their movements would not work for our use case

1 Like

The target property or the CFrame of the target? How would setting the target property on the server cause latency?

The target property. We have predefined target attachments that the players IK should switch between based on player input. If the property has to be set on the server and the player has 100ms ping (which is pretty normal) thats 100+100=200ms of unnecessary latency for client->server->client and the player seeing their own action. This is the type of thing that Roblox already handles for normal animations and I’m wondering why/if IKControls act differently.

1 Like

I recommend designing your system to only have one for each IK that changes its CFrame instead of having predefined different targets. Target does not replicate, but I heard the CFrame of it does. It might be worth trying out.

Why doesn’t IKControl replicate from client to server? I would expect these instances to function similarly to Animator instances, since they deal with manipulating motor6Ds for animation. The server lags behind on the target transforms, and its resulting in some weird IK animations when I move.

3 Likes

The method I found for dealing with this problem currently (without using the script that sg3cko provided) is to create a single-frame animation that acts as the default pose. This means (as long as the IKControl’s “Weight” property isn’t set to max, at most 0.999) the IKControl will try to resemble this default pose while still adjusting the rig to reach the EndEffector.

Notes
  • The defualt pose does not nessisarly need to be single framed, you could add a slight bit of movement to act as an idle animation if you wanted. Just remember that the IKControl will overide the majority of it in most cases.
  • If your defualt pose is affecting the Inverse Kinematics too much you should turn up the Weight property on your IKControl. (.999 works best in most cases)

I accomplish this by first creating the animation with the joints set to my desired pose and then save it to roblox, remembering to save the asset ID for when I create the script to run the animation. Make sure it is a looping animation. For my case I am using this default pose for a head turning script. I only need to create animation keyframes for joints that are directly affected by my IKControl (any joints between and including your ChainRoot and EndEffector,) so I create a keyframe for my upper torso and my head.

After this, run the animation to the character’s animator inside your script and it will automatically begin affecting the IKControl.

Repeat this process for each IKControl which requires a default pose, or create a default pose that includes keyframes for all required joints (though this method may make implementing this solution in some use cases more difficult).

Code Example

This is an extremely basic script that I can use to run the animation. Remember to change the ID to match the ID of your default animation pose. You would likely need additional code or modifications to make it work with any systems you have created relating to the setup of your IKControl’s.

--LocalScript in StarterCharacterScripts named "Animate", naming it this will pervent roblox's built in animate script from being inserted into the character.
--Need to make a defualt keyframe so the IK will favor returning to it when it can.
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local character = player.Character
if not character or not character.Parent then
	character = player.CharacterAdded:Wait()
end

-- Ensure that the character's humanoid contains an "Animator" object
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")

-- Create a new "Animation" instance and assign an animation asset ID
local defualtPoseAnimation = Instance.new("Animation")
defualtPoseAnimation.AnimationId = "rbxassetid://0" --Replace ID with your default pose ID

-- Load the animation onto the animator
local defualtPoseAnimation = animator:LoadAnimation(defualtPoseAnimation)

-- Play the animation track
defualtPoseAnimation:Play()

This system is not flawless though, as there may be cases where it does not provide the desired result, however I have not personally had any problems with it. I believe the best solution would be a completely procedural system that has an internal solution to this problem, though that’s obviously much more complicated. It is possible that in the future this method may no longer work or there will be a better method then this. You could also settle for sg3cko’s solution instead.

Hope this helps though!

1 Like

I’m still having issues with interpolating the weight, it keeps snapping. The position enum is still active even when weight is set to 0.

IKControls seem to have too much priority over Animations to where any IK Control that is controlling anything other than the Hand, will look not very good with any movement animation.

So this makes making any Character LookAt feature with IKControls not look very good if you start moving with a walk or run animation playing. Weight does not help this.

I took a break for a few hours and all of a sudden IKControl doesn’t seem to work.
The problem seems to be with the pole property:
Before:
(I have no footage of before, Imagine the After video, but without the arms ufasyew-ing)

After:

(I haven’t changed any code related to the IKControl)
Just last night it was working fine, then this morning it stopped.

1 Like

I’m attempting to follow the steps for testing IK in the official guide but I’m not achieving the intended results. I got the basic arm movement working, and completed the steps for adding an elbow constraint. However, behavior is unchanged. The elbow can still rotate along all axes. The attachments diverge rendering the HingeConstraint ineffective and bringing up the red warning arrows. In the guide, a video at the end of the elbow constraint section shows the intended result where the HingeConstraint limits the axis the elbow can rotate along. Is there something I’ve missing, or perhaps the guide steps are inaccurate? I’ve attached pictures showing my rig before runtime (HingeConstraint as normal) and during runtime (Hinge Constraint broken), as well as my setup per instructions and ROBLOX’s own example of the HingeConstraint and its attachments remaining intact during runtime.




2 Likes

i tried now, not working
Is there a place we missed?

Set the Workspace property IKControlConstraintSupport to Enabled.
CC: @virtuaLsc

2 Likes

Thank you very much @thebrickplanetboy
Are constraints used on custom boned characters?

1 Like

Yes it does: IKControl Joint Constraint [Beta] - #79 by donutmotion

1 Like

Is the EndEffectorOffset supposed to be hidden in the properties panel? It works fine but can only be set via script.

i just have to mention this… what the hell is this supposed to be?

Huge thanks to the engineers who made this. Took 20 minutes to implement leg kinematics and was super easy. One of the best features Roblox has developed

3 Likes

IKcontrols still crash when using a caged rig. Setting target, endeffector and chainroot on caged rigs crashes studio completely. I would make a bug report but I don’t have access to that category.

This is what happens when I set all target, endeffector and chainroot properties, I apply endeffector last and you can see as soon as it’s set, studio just crashes: