How can I replicate this specific movement?

Hey guys! I hope you all do very very well! Being direct, I’m trying to replicate an arm movement (LocalScript) to the Server, so that way everyone on the server can see it. The problem is that I got errors, and I don’t know how to fix those specific ones, so If you can give me a hand with this, even if it’s the smallest one, I’ll be very VERY VERY grateful not only with you but also with your heart.

Thank you for reading, and have a nice day! :grinning_face_with_smiling_eyes: :wink: :wave:

-Here’s the LocalScript and the ClientEvent:

local player = game.Players.LocalPlayer
local pi				=math.pi
local halfpi			=pi/2
local forwardV3			=Vector3.new(0,0,-1) -- Constant

--Multiplayer seen--
local tweenService = game:GetService("TweenService")
--Multiplayer seen--

--[[ 
	
		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:

local targetObj			=workspace:WaitForChild("Target")

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)

------------------------------------------------Multiplayer Seen---

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)

------------------------------------------------Multiplayer Seen---

while wait() do
	
	local targetPos		=targetObj.Position
	local shoulderCF	=upperTorso.CFrame * rightShoulderInit
	local plane, shoulderAngle, elbowAngle	= solveArm(shoulderCF, targetPos, 0.515, 1.031)


	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

-Here’s the RemoteEvent (ServerScript):

game.ReplicatedStorage:WaitForChild('PointToArm').OnServerEvent:Connect(function(player, rightShoulderCFRAME, rightElbowCFRAME)
	
	for key, value in pairs(game.Players:GetChildren()) do
		
		if value ~= player and (value.Character.RightUpperArm.Position - player.Character.RightUpperArm.Position).Magnitude < 111 and (value.Character.RightLowerArm.Position - player.Character.RightLowerArm.Position).Magnitude < 111 then
			
			game.ReplicatedStorage.LookArm:FireClient(value, player, rightShoulderCFRAME, rightElbowCFRAME)
		
		end
	end
end)

Thanks for helping me, and have a nice day! byee! :grinning_face_with_smiling_eyes: :wink: :wave:

1 Like

How about giving us error messages?

1 Like