Here is a detailed explanation of the script.
First, we declare some local variables to store references to the Players
service, the RunService
service, the local player, the local player’s character, and the mouse object:
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local plr = Players.LocalPlayer
local char = plr.Character
local mouse = plr:GetMouse()
Next, we calculate the armOffset variable, which represents the position and orientation of the right arm relative to the torso:
local armOffset = char.Torso.CFrame:Inverse() * char["Right Arm"].CFrame
This allows us to apply the correct rotation to the arm when it is attached to the torso using the weld object.
Next, we create a new Weld
object and set its Part0
and Part1
properties to the torso and the right arm, respectively. We also set the Parent
property of the weld object to the character:
local armWeld = Instance.new("Weld")
armWeld.Part0 = char.Torso
armWeld.Part1 = char["Right Arm"]
armWeld.Parent = char
This will attach the right arm to the torso using the weld object.
Next, we define a function called updateArmWeld
that takes a cframe
argument and sends a message to the server with the new armWeld.C0
value:
-- Function to update the armWeld.C0 value on the server
local function updateArmWeld(cframe)
-- Send a message to the server with the new armWeld.C0 value
local message = {
Type = "UpdateArmWeld",
Value = cframe,
}
game:GetService("ReplicatedStorage").UpdateArmWeld:FireServer(message)
end
This function will be called every time the armWeld.C0
value is changed, which will allow us to replicate the changes to all clients.
Next, we use the Changed
event on the armWeld
object to trigger a function that updates the value on the server. The Changed
event fires every time a property of the armWeld
object is changed. In this case, we are interested in the C0
property, which represents the position and orientation of the right arm relative to the torso:
-- Event that triggers when the armWeld.C0 value changes
armWeld.Changed:Connect(function(property)
if property == "C0" then
updateArmWeld(armWeld.C0)
end
end)
Finally, we use the RunService.Heartbeat
event to update the armWeld.C0
value every frame. This will rotate the arm to follow the mouse cursor:
RunService.Heartbeat:Connect(function()
local cframe = CFrame.new(char.Torso.Position, mouse.Hit.Position) * CFrame.Angles(math.pi/2, 0, 0)
armWeld.C0 = armOffset * char.Torso.CFrame:toObjectSpace