Thanks for the clarification! I didn’t realize there were more than one parameter on the function.
Now it works!
Thanks for the clarification! I didn’t realize there were more than one parameter on the function.
Now it works!
Hey, I’ve noticed that the controller performs quite poorly with R6, especially in terms of how accurate it is with it’s end destination.
Is there some way to fix this behavior?
The movement of the arms is dependent on two things, the joint position and the end effector.
The joint will rotate from the position of the joint, such that the end effector will reach the goal.
JointPosition modified to be at the top of the arm, with the end position located at the tip of the hand:
Resulting motion:
I believe you can try adjusting the position of the Motor6D Joint until you get the behavior you want, but with the default R6 Joint position with the joint located at the torso you will get some weird results.
For reference default R6 rig position with same end effector setup:
Someone fix his shoulder please:
Thank you so much for the in-depth explanation! Works phenomenally now
I can’t get over how easy this module is to use… I’ve had so many issues trying to use FABRIK that after a week of trying I just gave up. Amazing module!
Hey, quick follow-up question: what is the step
parameter in CCDIKIterateUntil
? Is it expected to be a value between [0, 1]
, or is it just
RunService.Heartbeat:Connect(function(Delta)
Step += Delta
, with no clamping?
Oh just realized having step in IterateUntil is pretty weird, never tested IterateUntil, never had any use of it for now.
So yeah step is deltatime returned from a run service according to API naming conventions RunService | Roblox Creator Documentation. It’s expected to be between [0,1] but theres a safety measure with math.min there so it should be fine, no clamping should be required.
The only function in CCDIK which needs step:
--Controls the primary CCDIK Method but instead of going fully towards the goal it lerps slowly towards it instead
function CCDIKController:rotateJointFromToWithLerp(motor6DJoint : Motor6D,u,v,axis,step)
local rotationCFrame = getRotationBetween(u,v,axis)
rotationCFrame = motor6DJoint.Part0.CFrame:Inverse()*rotationCFrame*motor6DJoint.Part1.CFrame
rotationCFrame = rotationCFrame-rotationCFrame.Position
local goalC0CFrame = CFrame.new(motor6DJoint.C0.Position)*rotationCFrame
local lerpAlpha = self.LerpAlpha
local currentC0 = motor6DJoint.C0
if step and self.ConstantLerpSpeed then
local angularDistance = VectorUtil.AngleBetween(currentC0.LookVector,goalC0CFrame.LookVector)
local estimatedTime = self.AngularSpeed/angularDistance
lerpAlpha = math.min(step*estimatedTime,1)
end
motor6DJoint.C0 = currentC0:Lerp(goalC0CFrame,lerpAlpha)
end
Ah, seems like I shouldn’t really be using it then. Is there an alternate method for smoothly ‘tweening’ an arm towards a target goal? I’ve noticed the properties such as AngularSpeed, but I’m not fully sure on how to utilize them properly.
To those interested, I made a quick and easy AnimateGoal
function which works flawlessly for my intents
local CurrentlyAnimating = {}
local function AnimateGoal(Controller, Target, Length)
local AlreadyAnimating = CurrentlyAnimating[Controller]
if AlreadyAnimating then
AlreadyAnimating.Iteration:Disconnect()
AlreadyAnimating.Transform:Disconnect()
end
local IterationConn
local TransformConn
local Step = 0
IterationConn = RunService.Heartbeat:Connect(function(Delta)
Step += Delta
if Step > Length then
IterationConn:Disconnect()
TransformConn:Disconnect()
end
Controller:CCDIKIterateOnce(Target, 0.05, Step / Length)
end)
TransformConn = RunService.Stepped:Connect(function()
for _, Motor in next, Controller.Motor6DTable do
Motor.Transform = CFrame.new()
end
end)
CurrentlyAnimating[Controller] = {
Iteration = IterationConn,
Transform = TransformConn
}
end
An issue I’ve been experiencing would be the lack of communication on the API page, though. I had to look through the source to find out about the Motor6DTable
property of the CCDIKController
object. Other than that, I’ve yet to have any annoying issues with this module!
What would be the proper way to stop a CCDIKController? Even if I stop calling any functions, the arm keeps being animated weird even after I restore the C0 and C1 properties of the Motor6D object.
What’s weirder is that I don’t even have to call any methods for the weird behavior to occur - the moment I create a new CCDIKController object, the animation for the left arm becomes off:
:Destroy()
this remains
I’m assuming the behavior has to do with how you reset the rotation here:
But it seems pretty hard to restore the original Motor6D behavior nevertheless
It’s probably due to the C0 and C1 resets I included when creating the CCDIK controller which @nurokoi pointed out since I reset the orientation to CFrame.new() which probably messed up the direction the animations were made in.
You can probably include a method to reset it to original orientation once the CCDIK controller is destroyed.
Yeah, I fixed it by just resetting the C0 and C1 values back to default right after creating the CCDIKController object. Would this cause any unexpected behavior when using the Controller’s methods later on? Because I’m thinking of wrapping the CCDIKController.new
method to safely reset the C0 and C1 properties back to default right after creating the controller object.
EDIT: Yeah I see what you mean by what nurokoi pointed out now - it seems like I need to nullify all rotation right before calling any CCDIK methods to fix this behavior… Really weird workaround, but it’ll sadly have to do
I got it working
So, I’ve now ran into an issue where the CCDIK module iterates from seemingly the default resting position of the right arm - is there a way to change this behavior to iterate from the current arm’s position? Currently what I’m doing is lerping an arm onto a target, but if I keep lerping it once it reached that target once, the arm will start from it’s default position and rise quickly to the target position like so:
CCDIKController.LerpMode
, but I don’t know what they do and messing around with them doesn’t see to do much either.
Is there some solution to this, or do I need to alter the source to get the behavior I’d like?
There isn’t any method that returns the CFrame that the limb would be at either without actually changing the limb, so I can’t use a binary search to figure out the right step
parameter to seamlessly lerp towards the end goal either.
EDIT: It seems like CCDIKIterateUntil
fixes most of the problem in regards to random snapping - I don’t lerp after the first time (i.e when the arm reaches for the door), which also addresses my other issue above.
https://cdn.discordapp.com/attachments/785870115463626765/852636743148634122/LqelvIBfrc.mp4
Hey, I am attempting to make a mech similar to yours. Now my problem is not that I cant use the module but I’m unsure on how to make the legs move as if their walking.
This is what iv got. If my explanation isnt clear enough then basically I am trying to replicated the legs movement in your post “Haha mech go stomp”
[Haha Mech go stomp, any feedback?]
This is like my third post sorry if I am doing this thing really wrong lol.
Thanks in advance.
Is this will work with R15 as well?
A good method for this is to move the torso (main part which is not IK) forward. When the legs, which are IK, cannot reach the red cubes, move the red cubes forward to the original offset. Repeat. This will give the illusion of walking.
As for the module itself, great job! Looks so smooth!
Very cool module!
By the way, I believe you can put devforum links in model descriptions:
Should I create invisible fake legs so that the IK legs dont make the mech fall?
Sure. Or, you can anchor the mech’s torso and lerp the CFrame to move it. For collisions, you would use :GetTouchingParts() and raycast to find the direction of collision. It’s a bit advanced, but would give you more control.
Or, alternatively, you can just use a humanoid with supports/fake legs
I cant anchor the torso due to Network ownership (for smooth player control) . Also I have been using humanoid. So from that I am going to create invisible legs for support .
Then I will find a good offset position for the red parts alternating with maybe a debounce system? Only thing I cant work out is going left and right. I am also assuming ill use CCDIKIterateUntil.
Thank you for the quick and helpful responses I am quite new to DevForums so this has given me a great first experience pro man.