Recently, I have been trying to make a sword attack using the left arm. I finished the animations and the code for the keybind (F) for the attack. Until I got up to the part where I need to show the sword upon pressing but I have found no way to do that easily with just a script only.
Here is my current code:
local UIS = game:GetService("UserInputService")
UIS.InputBegan:Connect(function(input, IsTyping)
if IsTyping then
return
end
if input.KeyCode == Enum.KeyCode.F then
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://17508585054"
local Char = game.Players.LocalPlayer.Character
local AnimTrack = Char.Humanoid:LoadAnimation(Animation)
local Sword = game.ReplicatedStorage.Items.Sword:Clone()
AnimTrack:Play()
end
end)
I have tried to add my own code to try attach the sword onto the left arm, but I keep failing.
The quick and easy way would be to make a weld constraint between the left arm and the sword, and positioning the sword to where you want the grip to be.
The more quality option would be to user Motor6D if you are animating this sword. If you have already animated the right sword, then you can do the same thing as the right sword.
I’m not animating the sword, so I went with the 1st method you suggested. Is this what it’s suppose to look like? (one of the rarest times I work with welding)
Using attachments CFrame helps greatly in positioning and orientating it as @MonkeyIncorporated said. You can drag and rotate them using studio tools instead of guessing and predicting the correct 3 numbers.
here is a function i made that is basically a reverse engineering of Humanoid:AddAccessory(); as long as the AttachmentRef matches the name of an Attachment present in Character
i originally made it because Humanoid:AddAccessory() can only be called on server which is stupid
anyway the function i made fits ur use case quite well and the sample code below should give u a good idea on how it works:
--- Vanilla.Rig.AttachAccessoryPart()
--- a reverse-engineering of Humanoid:AddAccessory() \
--- for client-authoritative accessory creation/handling \
--- so the server does less work as it should :p
local function AttachAccessoryPart(Character: Model, APart: BasePart, AttachmentRef: string, Parent: Instance?): boolean
local A0 = Character:FindFirstChild(AttachmentRef, true) :: Attachment
if not A0 then return false end
if not A0:IsA("Attachment") then return false end
local A1 = APart:FindFirstChildOfClass("Attachment") :: Attachment?
if not A1 then return false end
APart.Anchored = false
APart.Massless = true
APart.CFrame = A0.WorldCFrame * A1.CFrame:Inverse()
--[[Vanilla.Instance.new{
ClassName = "WeldConstraint";
Part0 = APart;
Part1 = A0.Parent;
Parent = APart;
}]]
local WC = Instance.new("WeldConstraint")
WC.Part0 = APart
WC.Part1 = A0.Parent
WC.Parent = APart
APart.Parent = Parent or Character
return true
end
--[[
LinkedSword specialmesh properties:
MeshId = rbxassetid://16931393788;
TextureId = rbxassetid://16931393815;
Offset = Vector3.new(0, 1.7, 0);
]]
--[[
LinkedSword attachment properties:
CFrame = CFrame.fromOrientation(math.rad(90), 0, 0)
]]
local AttachTo = "RightGripAttachment"
local Sword = script:WaitForChild("LinkedSword")
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
game:GetService("UserInputService").InputBegan:Connect(function(InputObject: InputObject, SunkInput: boolean)
if SunkInput then return end
if InputObject.KeyCode == Enum.KeyCode.Q then
local Thing = Character:FindFirstChild("LinkedSword")
if Thing then
Thing:Destroy()
else
AttachAccessoryPart(Character, Sword:Clone(), AttachTo)
end
end
end)