Hey guys! I hope you are doing very very well! Being direct, I’m trying to make a complete arm movement but I Got a problem, when I replicate the movement, the arm movement to the player next to you is bugged and you see his arm into another position than the actual one:
Player 1 Screen:
Player 2 Screen:
Basically, there’s a cube on the workspace that is going to be cloned for every player on the game, so player1 has the “Target1” Cube, and player2 has the “Target2” Cube, etc.
This is because the arm is pointing to this cube. And when you move your mouse your “special” cube moves to the mouse position.
The problem is that as you can see the limbs bug for every player, and I don’t really know the why of this, I really really really appreciate your help if you can give me a hand with this, even if it’s the smallest one, and I also thank you for giving me your time reading this (and maybe trying to help me)
If you need more information don’t think of it, and write it down in the comments!
Here’s the script that moves your arm (with Inverse Kinematics):
(It’s a LocalScript)
local player = game.Players.LocalPlayer
--Cloning the players "special" cubes--
--The default cube that is going to be clonned is "Target"
local player1 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player1
local player2 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player2
local player3 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player3
local player4 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player4
local player5 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player5
local player6 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player6
local player7 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player7
local player8 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player8
local player9 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player9
local player10 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player10
local player11 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player11
local player12 = game.ReplicatedStorage:WaitForChild('PlayerPointTOCUBES').Player12
wait(25)
if player.Name == player1.Value then
local Cube1 = game.Workspace.Target:Clone()
Cube1.Parent = game.Workspace
Cube1.Name = "Target1"
elseif player.Name == player2.Value then
local Cube2 = game.Workspace.Target:Clone()
Cube2.Parent = game.Workspace
Cube2.Name = "Target2"
elseif player.Name == player3.Value then
local Cube3 = game.Workspace.Target:Clone()
Cube3.Parent = game.Workspace
Cube3.Name = "Target3"
elseif player.Name == player4.Value then
local Cube4 = game.Workspace.Target:Clone()
Cube4.Parent = game.Workspace
Cube4.Name = "Target4"
elseif player.Name == player5.Value then
local Cube5 = game.Workspace.Target:Clone()
Cube5.Parent = game.Workspace
Cube5.Name = "Target5"
elseif player.Name == player6.Value then
local Cube6 = game.Workspace.Target:Clone()
Cube6.Parent = game.Workspace
Cube6.Name = "Target6"
elseif player.Name == player7.Value then
local Cube7 = game.Workspace.Target:Clone()
Cube7.Parent = game.Workspace
Cube7.Name = "Target7"
elseif player.Name == player8.Value then
local Cube8 = game.Workspace.Target:Clone()
Cube8.Parent = game.Workspace
Cube8.Name = "Target8"
elseif player.Name == player9.Value then
local Cube9 = game.Workspace.Target:Clone()
Cube9.Parent = game.Workspace
Cube9.Name = "Target9"
elseif player.Name == player10.Value then
local Cube10 = game.Workspace.Target:Clone()
Cube10.Parent = game.Workspace
Cube10.Name = "Target10"
elseif player.Name == player11.Value then
local Cube11 = game.Workspace.Target:Clone()
Cube11.Parent = game.Workspace
Cube11.Name = "Target11"
elseif player.Name == player12.Value then
local Cube12 = game.Workspace.Target:Clone()
Cube12.Parent = game.Workspace
Cube12.Name = "Target12"
end
--Cloning the players "special" cubes--
local pi =math.pi
local halfpi =pi/2
local forwardV3 =Vector3.new(0,0,-1) -- Constant
--[[
OriginCFrame is the CF of the shoulder joint, this can be gotten using some CFrame:
upperTorso.CFrame * shoulderJoint.C0
Note that the shoulderJoint.C0 would be the INITIAL shoulderJoint C0, before anything has been done
targetPos is the target Position you are trying to point to, this will be a Vector3 in the world space
a is the length of the upper arm, I use 0.515
b is the length of the lower arm + the hand, I use 1.1031
--]]
local function solveArm(originCFrame,targetPosition,a,b)
-- Localize the targetPosition in regards to originCFrame
local localized = originCFrame:pointToObjectSpace(targetPosition)
local localizedUnit = localized.unit
-- Construct a CFrame pointing from the shoulder position to the target position
local axis = forwardV3:Cross(localizedUnit)
local angle = math.acos(-localizedUnit.Z)
local plane = originCFrame*CFrame.fromAxisAngle(axis,angle)
-- Get the length from the origin to our target position
local c = localized.Magnitude
-- If c is between the lengths of a and b then return an offsetted plane so that one of the lengths reaches the goal,
-- but the other length is folded so it looks natural
if c < math.max(a,b)-math.min(a,b) then
return plane * CFrame.new(0,0,math.max(b,a)-math.min(b-a)-c), -halfpi, pi
-- If c > a + b then return flat angles and an offsetted plane which reaches its target
elseif c > a+b then
return plane * CFrame.new(0,0,a+b-c), halfpi, 0
-- Otherwise, use the law of cosines
else
local theta1 = -math.acos((-(b * b) + (a * a) + (c * c)) / (2 * a * c)) -- law of cosines, gets the angle opposite b
local theta2 = math.acos(((b * b) - (a * a) + (c * c)) / (2 * b * c)) -- law of cosines, gets the angle opposite a
return plane, theta1 + halfpi, theta2 - theta1
end
end
wait(5)
-- Demonstration for how this can be called:
--Giving the cubes--
local Target = nil
if player.Name == player1.Value then
local targetObj = workspace:WaitForChild("Target1")
Target = "Target1"
elseif player.Name == player2.Value then
local targetObj = workspace:WaitForChild("Target2")
Target = "Target2"
elseif player.Name == player3.Value then
local targetObj = workspace:WaitForChild("Target3")
Target = "Target3"
elseif player.Name == player4.Value then
local targetObj = workspace:WaitForChild("Target4")
Target = "Target4"
elseif player.Name == player5.Value then
local targetObj = workspace:WaitForChild("Target5")
Target = "Target5"
elseif player.Name == player6.Value then
local targetObj = workspace:WaitForChild("Target6")
Target = "Target6"
elseif player.Name == player7.Value then
local targetObj = workspace:WaitForChild("Target7")
Target = "Target7"
elseif player.Name == player8.Value then
local targetObj = workspace:WaitForChild("Target8")
Target = "Target8"
elseif player.Name == player9.Value then
local targetObj = workspace:WaitForChild("Target9")
Target = "Target9"
elseif player.Name == player10.Value then
local targetObj = workspace:WaitForChild("Target10")
Target = "Target10"
elseif player.Name == player11.Value then
local targetObj = workspace:WaitForChild("Target11")
Target = "Target11"
elseif player.Name == player12.Value then
local targetObj = workspace:WaitForChild("Target12")
Target = "Target12"
end
--Giving the cubes--
local character = player.Character
local upperTorso =character:WaitForChild("UpperTorso")
local rightUpperArm =character:WaitForChild("RightUpperArm")
local rightLowerArm =character:WaitForChild("RightLowerArm")
local rightShoulder =rightUpperArm:WaitForChild("RightShoulder")
local rightElbow =rightLowerArm:WaitForChild("RightElbow")
local rightShoulderInit =rightShoulder.C0 -- This can be a preset value, since it will always be the same, it is the offset from the UpperTorso to the RightShoulder joint
local rightElbowInit =rightElbow.C0 -- This can be a preset value, since it will always be the same, it is the offset from the RightUpperArm to the RightElbow joint
local tp0 =CFrame.new((upperTorso.CFrame * CFrame.new(1.25,0,-1)).p)*CFrame.Angles(0,math.pi/2,0)
------------------Make everyone see your arm's position---
local tweenService = game:GetService("TweenService")
game.ReplicatedStorage.LookArm.OnClientEvent:Connect(function(otherPlayer, rightShoulderCFRAME, rightElbowCFRAME)
local RightShoulder = otherPlayer.Character.RightUpperArm:FindFirstChild("RightShoulder")
local RightElbow = otherPlayer.Character.RightLowerArm:FindFirstChild("RightElbow")
if RightShoulder then
tweenService:Create(RightShoulder, TweenInfo.new(.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out, 0, false, 0), {C0 = rightElbowCFRAME}):Play()
end
if RightElbow then
tweenService:Create(RightElbow, TweenInfo.new(.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out, 0, false, 0), {C0 = rightElbowCFRAME}):Play()
end
end)
-------------------Make everyone see your arm's position---
while wait() do
local targetObj = workspace:WaitForChild(Target)
local targetPos = targetObj.Position
local shoulderCF =upperTorso.CFrame * rightShoulderInit
local plane, shoulderAngle, elbowAngle = solveArm(shoulderCF, targetPos, 0.515, 1.031)
-- (Just ignore this because this was the old code) rightShoulder.C0 =upperTorso.CFrame:toObjectSpace(plane) * CFrame.Angles(shoulderAngle, 0, 0)
-- (Just ignore this because this was the old code) rightElbow.C0 =rightElbowInit * CFrame.Angles(elbowAngle, 0, 0)
local goalRightShoulderC0CFrame = upperTorso.CFrame:toObjectSpace(plane) * CFrame.Angles(shoulderAngle, 0, 0)
rightShoulder.C0 =goalRightShoulderC0CFrame.Rotation + rightShoulder.C0.Position
rightElbow.C0 =rightElbowInit * CFrame.Angles(elbowAngle, 0, 0)
game.ReplicatedStorage.PointToArm:FireServer(player, rightShoulder.C0, rightElbow.C0)
end
Thank you for your help and have a nice day! bye bye!
Don’t mind to ask for more information, just write what you need on the comments and I’ll be answering you!