Guys, are you seriously trying to get IK to work without disconnecting the character’s leg motors?
I feel I should remind you that a client can move their character’s parts any way they want, and it’ll replicate.
What are you talking about?
And no Motor6D’s don’t replicate.
@WhoBloxedWho so I’m trying to work with your code, but it doesn’t seem to work properly for some reason can you check it out and see what’s wrong? Or am I the one doing it wrong?
Could you DM me a code snippet or the rbxl of that place?
There’s a way to make character leg stay in place, by using roblox animation. Looping it in normal position.
Motor6D doesn’t need to be disconnected anymore. Just need to be moved.
You can also just set a motors .Transform CFrame to an empty CFrame every runService.Stepped. It’s something that should be done client side, so it’s not a big deal as you should also be doing procedural animation client side.
What I’m talking about is that there does not need to be any physical justification of how a character is moving their limbs.
Motor6Ds are a pain to work with, but you can disconnect them and move the character’s legs by setting CFrames clientside, and the server will happily replicate that.
Ok, so I’ve figured out how to do most of it and it works pretty well, but now I can’t figure out how to make the foot properly adjust itself so the leg looks like it’s actually sitting ontop of something. I tried cross product, but it didn’t really work. Any ideas?
You can shoot a ray downward. The third variable findpartonray returns is the surface normal
Yes, but how do I compensate for the leg rotation? The foot is already rotated by how much the lowerleg is rotated so if I were to rotate it to the surface normal it still wouldn’t be right.
Oh, hmm…
I’ve never been good with IK, sorry…
I wouldn’t use the surface normal since this is prone to glitches if your foot is over multiple surfaces. I’d fire a downwards ray at the toes position, then just get the angle between the heel & wherever that hits.
In case anyone gets stuck where I did, here’s some more info from WhoBloxedWho
I have been messing with this for a while, but I can’t seem to get it to work…
https://gyazo.com/d53e7776b913948b62ba056fac56e80c
local fromAxisAngle = CFrame.fromAxisAngle
local acos = math.acos
local max = math.max
local min = math.min
local cfNew = CFrame.new
local forwardV3 = Vector3.new(0, 0, -1)
local pi = math.pi
local cfAngles = CFrame.Angles
wait(2)
local upperTorso = workspace.ViewModel.UpperTorso
local shoulderMotor = workspace.ViewModel.RightUpperArm.RightShoulder
local elbowMotor = workspace.ViewModel.RightLowerArm.RightElbow
local lowerC0 = elbowMotor.C0
-- OriginCF is the CFrame of the shoulder, direction is important
-- TargetPos is the Vector3 position we're reaching to
-- l1 and l2 are both numbers that represent the length of the segments of the arm
local function solveIK(originCF, targetPos, l1, l2)
-- put our position into local space in regards to the originCF
local localized = originCF:pointToObjectSpace(targetPos)
-- this breaks if OriginCF and targetPos are at the same position
local localizedUnit = localized.unit
-- the distance to from originCF.p to targetPos
local l3 = localized.magnitude
-- build an axis of rotation for rolling the arm
-- forwardV3 is Vector3.new(0, 0, -1)
local axis = forwardV3:Cross(localizedUnit)
-- find the angle to rotate our plane at
local angle = acos(-localizedUnit.Z)
-- create a rotated plane to base the angles off of
local planeCF = originCF * fromAxisAngle(axis, angle)
-- L3 is between the length of l1 and l2
-- return an offset plane so that one part reaches the goal and "folded" angles
if l3 < max(l2, l1) - min(l2, l1) then
return planeCF * cfNew(0, 0, max(l2, l1) - min(l2, l1) - l3), -pi/2, pi
-- l3 is greater than both arm lengths
-- return an offset plane so the arm reaches its goal and flat angles
elseif l3 > l1 + l2 then
return planeCF * cfNew(0, 0, l1 + l2 - l3), pi/2, 0
-- the lengths check out, do the law of cosines math and offset the plane to reach the targetPos
-- return the offset plane, and the 2 angles for our "arm"
else
local a1 = -acos((-(l2 * l2) + (l1 * l1) + (l3 * l3)) / (2 * l1 * l3))
local a2 = acos(((l2 * l2) - (l1 * l1) + (l3 * l3)) / (2 * l2 * l3))
return planeCF, a1 + pi/2, a2 - a1
end
end
-- simple demo for how its called
local TARGET_POS = Vector3.new(0, 3, 0)
local SHOULDER_C0_VALUE = CFrame.new(1, 0.4, 0)
game:GetService("RunService").RenderStepped:Connect(function()
--local shoulderCF = upperTorso.CFrame * shoulderMotor.C0
local shoulderCF = shoulderMotor.Part0.CFrame
local plane, shoulderAngle, elbowAngle = solveIK(shoulderCF, workspace.Front.Position, shoulderMotor.Part0.Size.Y, shoulderMotor.Part1.Size.Y)
shoulderMotor.C0 = upperTorso.CFrame:toObjectSpace(plane) * cfAngles(shoulderAngle, 0, 0)
elbowMotor.C0 = lowerC0 * cfAngles(elbowAngle, 0, 0)
end)
If you’re trying to keep the arm from moving a point past its length. @systack quoted @WhoBloxedWho Regarding this right before your post.
You will want to change this condition statement.
elseif l3 > l1 + l2 then
return planeCF * cfNew(0, 0, l1 + l2 - l3), pi/2, 0
To
elseif l3 > l1 + l2 then
return planeCF, math.pi/2, 0
I figured out how to keep it at a fixed point. However, if you look at the gif, the arm isn’t grabbing the block exactly how it should.
Could it possibly be the lengths in which the function is solving with (l1 and l2)? I’ve noticed instead of using the two values 0.515 and 1.1031
you are using both part’s Size.Y.
I am using the code provided by @LMH_Hutch. It works alright assuming that the joints are all lined up.
But they aren’t. I am cframing the hand to the weapon, and using the wrist position from the hand as the targetpoint, but the wrist position from the lower arm does not connect to it. Anyone have suggestions on how I can take attachments into account?
you could use attachments as target points just set the goal to Attachment.WorldPosition
That is what I am doing, but all of the other attachments in the parts that make up the arm are not lining up with the target point. The code assumes I am trying to line up the arm. I am not trying to line up the arm, but trying to line up the attachment in the arm.
Oh so you are using attachments instead of motor6ds ? If then even i tried it and it kept glitching out