-
I’m trying to make the players right arm follow the position of the mouse in every axis (XYZ)
-
The issue is that the arm follows the mouse but also goes to the exact position of the mouse as well (disconnecting from the body). Other than that it functions in terms of orientation
-
I have tried using different calculations, scripts, and more. This script seems to be the most accurate other than positioning
Following Script shown below
local workspace = game:GetService("Workspace")
local storage = game:GetService("ReplicatedStorage")
local runService = game:GetService("RunService")
local goalPart = workspace:WaitForChild("GoalPosition")
local character = script.Parent
local upperTorso = character:WaitForChild("UpperTorso")
local rightShoulder = character:WaitForChild("RightUpperArm"):WaitForChild("RightShoulder")
local rightElbow = character:WaitForChild("RightLowerArm"):WaitForChild("RightElbow")
local rightWrist = character:WaitForChild("RightHand"):WaitForChild("RightWrist")
local solveModule = storage:WaitForChild("SolveIK")
local solveIK = require(solveModule)
----
local SHOULDER_C0_CACHE = rightShoulder.C0
local ELBOW_C0_CACHE = rightElbow.C0
local UPPER_LENGTH = math.abs(rightShoulder.C1.Y) + math.abs(rightElbow.C0.Y)
local LOWER_LENGTH = math.abs(rightElbow.C1.Y) + math.abs(rightWrist.C0.Y) + math.abs(rightWrist.C1.Y)
----
runService.Heartbeat:Connect(function()
local shoulderCFrame = upperTorso.CFrame * SHOULDER_C0_CACHE
local goalPosition = goalPart.Position
local planeCF, shoulderAngle, elbowAngle = solveIK(shoulderCFrame, goalPosition, UPPER_LENGTH, LOWER_LENGTH)
rightShoulder.C0 = upperTorso.CFrame:toObjectSpace(planeCF) * CFrame.Angles(shoulderAngle, 0, 0)
rightElbow.C0 = ELBOW_C0_CACHE * CFrame.Angles(elbowAngle, 0, 0)
end)
runService.Stepped:Connect(function()
rightShoulder.Transform = CFrame.new()
rightElbow.Transform = CFrame.new()
rightWrist.Transform = CFrame.new()
end)
The code above works and will go to the goal part (which is set by another script that follows the mouse cursor
The code below is the script (set in starterplayerscripts) that sets the goal part
local workspace = game:GetService("Workspace")
local runService = game:GetService("RunService")
local goalPart = workspace:WaitForChild("GoalPosition")
----
local HOME_CFRAME = goalPart.CFrame
local LENGTH = 2.3
local SPEED = 1
----
local Mouse = game.Players.LocalPlayer:GetMouse()
runService.RenderStepped:Connect(function()
if Mouse.Target then
Mouse.TargetFilter = goalPart
goalPart.CFrame = Mouse.Hit
end
end)
The Inverse Kinematic solving method is done by a module script called SolveIK which can be seen below
local function solveIK(originCF, targetPos, l1, l2)
-- build intial values for solving
local localized = originCF:pointToObjectSpace(targetPos)
local localizedUnit = localized.unit
local l3 = localized.magnitude
-- build a "rolled" planeCF for a more natural arm look
local axis = Vector3.new(0, 0, -1):Cross(localizedUnit)
local angle = math.acos(-localizedUnit.Z)
local planeCF = originCF * CFrame.fromAxisAngle(axis, angle)
-- case: point is to close, unreachable
-- action: push back planeCF so the "hand" still reaches, angles fully compressed
if l3 < math.max(l2, l1) - math.min(l2, l1) then
return planeCF * CFrame.new(0, 0, math.max(l2, l1) - math.min(l2, l1) - l3), -math.pi/2, math.pi
-- case: point is to far, unreachable
-- action: for forward planeCF so the "hand" still reaches, angles fully extended
elseif l3 > l1 + l2 then
return planeCF * CFrame.new(0, 0, l1 + l2 - l3), math.pi/2, 0
-- case: point is reachable
-- action: planeCF is fine, solve the angles of the triangle
else
local a1 = -math.acos((-(l2 * l2) + (l1 * l1) + (l3 * l3)) / (2 * l1 * l3))
local a2 = math.acos(((l2 * l2) - (l1 * l1) + (l3 * l3)) / (2 * l2 * l3))
return planeCF, a1 + math.pi/2, a2 - a1
end
end
----
return solveIK
R6 is not an option for this game and I have tried setting the position correctly in many ways, but this seems to be the best base position. I just don’t know how to set the arm to the shoulder attachment while also being able to move perfectly. If you could assist me in any of the scripts that would be very helpful!