local RunService = game:GetService("RunService") local Settings = { AnimateHead = false, ConnectionType = "Snap", RotationAmplitudeHead = 20, RotationAmplitudeChest = 15, } local AnimationSettings = { CameraOffset = CFrame.new(0.2, -0.37, 0.91) * CFrame.Angles(math.rad(0), math.rad(0), math.rad(0)), AimAmplifier = 0.5, AimMaxChange = 4, AimRetract = 15, AimMaxDegree = 20, } local knife = script.Parent.Parent local player: Player = game.Players.LocalPlayer local character = player.Character or player.CharacterAdded:Wait() local humanoid: Humanoid = (character:FindFirstChild("Humanoid") or character:WaitForChild("Humanoid")) :: Humanoid local camera: Camera = workspace.CurrentCamera local mouse: Mouse = player:GetMouse() function Interpolate(start: CFrame, dest: CFrame, alpha: number) local delta = dest.Position - start.Position local startRot = start - start.Position dest = dest - dest.Position local relRot = startRot:inverse() * dest local x, y, z = relRot:ToEulerAnglesXYZ() return (start + (delta * alpha)) * CFrame.Angles(x * alpha, y * alpha, z * alpha) end function Lerp(a: number, b: number, x: number) return a + ((b - a) * x) end function Easing(x: number, func: number) -- // Easing functions -- 1 = Linear -- 2 = Smoothstep (ease in, then out) -- 3 = Sine in -- 4 = Sine out if func == 1 then return x elseif func == 2 then return (x ^ 2) * (3 - 2 * x) elseif func == 3 then return math.sin(math.rad(x * 90)) elseif func == 4 then return 1 - math.sin(math.rad((1 - x) * 90)) end return x end function MakeKnifeBody() local body = Instance.new("Part") body.CanCollide = false body.BrickColor = BrickColor.new("Really black") body.Size = Vector3.new(0.2, 0.2, 0.2) body.TopSurface = 0 body.BottomSurface = 0 return body end local Animations = nil function LoadAnimations(transparency) Animations = { Default = { {{}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)} }, Equip = { {{}, transparency, CFrame.new(0, 0, 0) * CFrame.Angles(-1.571, 0, 0), CFrame.new(0, 0, 0) * CFrame.Angles(-1.571, 0, 0), CFrame.new(0, -1.3, -0.5) * CFrame.Angles(-2.618, 0, 0)}, {{0.8, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.524, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(0, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0.2, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, }, Idle1 = { {{}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0.3, 2}, transparency, CFrame.new(0.8, -0.301, 0.2) * CFrame.Angles(-0.35, 0, 0.872), CFrame.new(-0.201, 0, 0) * CFrame.Angles(0.523, 1.221, -0.699), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 1.221, 0)}, {{0.55, 2}, transparency, CFrame.new(0.2, -0.5, 0.2) * CFrame.Angles(-0.14, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(0, 1.221, -0.175), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.746, 1.221, 0.174)}, {{0.15, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, }, Idle2 = { {{}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0.3, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.524, 0, 0.872), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, -0.175, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0.523, 0)}, {{0.3, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(0.349, 0, 0.523), CFrame.new(-0.201, 0, 0) * CFrame.Angles(0.174, 0.698, -0.524), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, -1.222, 0)}, {{0.2, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(0.61, 0, 0.349), CFrame.new(-0.201, 0, 0) * CFrame.Angles(0.139, 0.663, -0.489), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, -1.222, 0)}, {{0.2, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)} }, Attack1 = { {{}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0.25, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-1.048, 0, 0.349), CFrame.new(-0.201, 0, 0) * CFrame.Angles(0.872, 0.349, 0.087), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0.15, 2}, transparency, CFrame.new(0.4, -0.101, 0.1) * CFrame.Angles(-1.571, 0, -0.35), CFrame.new(-0.301, -0.301, 0.1) * CFrame.Angles(-1.048, -0.175, -0.524), CFrame.new(0, -1.201, -0.801) * CFrame.Angles(-2.095, 0, 0)}, {{0.6, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)} }, Attack2 = { {{}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0.25, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.699, 0, 0.872), CFrame.new(-0.401, 0.3, 0.1) * CFrame.Angles(1.919, 2.443, -1.222), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0.15, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-1.048, 0, -0.524), CFrame.new(-0.5, -0.201, -0.101) * CFrame.Angles(0.523, 1.396, -0.873), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0.6, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)} }, Attack3 = { {{}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0.25, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-1.397, 0, 0.174), CFrame.new(-0.401, -0.201, 0) * CFrame.Angles(1.396, 0.698, -1.571), CFrame.new(0, -1.3, -0.401) * CFrame.Angles(-2.444, 0, 0)}, {{0.15, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-1.397, 0, 0.174), CFrame.new(-0.401, 0.1, 0) * CFrame.Angles(0.349, 2.094, -0.524), CFrame.new(0, -1.3, 0.1) * CFrame.Angles(-3.84, 0, 0)}, {{0.6, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)} }, Charge = { {{}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{1, 2}, transparency, CFrame.new(0.5, -0.301, 0.2) * CFrame.Angles(-0.35, 0, 1.047), CFrame.new(-0.201, 0, -0.201) * CFrame.Angles(1.396, 0.087, 0.174), CFrame.new(0, -0.801, -0.801) * CFrame.Angles(-1.222, 0, 0)} }, Throw = { {{}, 1, CFrame.new(0.5, -0.301, 0.2) * CFrame.Angles(-0.35, 0, 1.047), CFrame.new(-0.201, 0, -0.201) * CFrame.Angles(1.396, 0.087, 0.174), CFrame.new(0, -0.801, -0.801) * CFrame.Angles(-1.222, 0, 0)}, {{0.1, 2}, 1, CFrame.new(0.5, -0.301, 0.2) * CFrame.Angles(-0.873, 0, 0.523), CFrame.new(-0.201, -0.201, 0.1) * CFrame.Angles(-0.35, 0.087, -0.175), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0.5, 2}, 1, CFrame.new(0.5, -0.401, 0.2) * CFrame.Angles(-0.699, 0, 0.872), CFrame.new(-0.201, -0.201, 0) * CFrame.Angles(-1.92, -0.175, 0.174), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0, 2}, transparency, CFrame.new(0.5, -0.401, 0.2) * CFrame.Angles(-0.699, 0, 0.872), CFrame.new(-0.201, -0.201, 0) * CFrame.Angles(-1.92, -0.175, 0.174), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)}, {{0.4, 2}, transparency, CFrame.new(0.4, -0.201, 0.2) * CFrame.Angles(-0.873, 0, 0.698), CFrame.new(-0.201, 0, 0) * CFrame.Angles(-0.175, 0.349, -0.262), CFrame.new(0, -0.95, -0.801) * CFrame.Angles(-1.571, 0, 0)} } } end function PlayAnimation(name: string, timePos: number) timePos = math.clamp(timePos, 0, 1) local animation = Animations[name] if #animation == 1 then return { animation[1][3], animation[1][4], animation[1][5], animation[1][2] } else local pos1, pos2 = 1, 1 local duration = timePos for i = 2, #animation do duration = duration - animation[i][1][1] if duration <= 0 then pos1 = i - 1 pos2 = i break end end local amount = Easing((animation[pos2][1][1] + duration) / animation[pos2][1][1], animation[pos2][1][2]) return { Interpolate(animation[pos1][3], animation[pos2][3], amount), Interpolate(animation[pos1][4], animation[pos2][4], amount), Interpolate(animation[pos1][5], animation[pos2][5], amount), Lerp(animation[pos1][2], animation[pos2][2], amount) } end end local Weapon = MakeKnifeBody() Weapon.Name = "WeaponObject" local head = character.Head local motors = { character.LeftUpperArm:FindFirstChild("LeftShoulder"), character.RightUpperArm:FindFirstChild("RightShoulder"), character.Head:FindFirstChild("Neck"), } local welds = {nil, nil, nil} local weaponParts = {nil, nil} local weaponModel = nil function SetupWeapon(transparency, reflectance, brickColor, material, texture) Weapon.Transparency = transparency Weapon.Reflectance = reflectance Weapon.BrickColor = brickColor Weapon.Material = material local knifeTexture = Instance.new("SpecialMesh") knifeTexture.Parent = Weapon knifeTexture.Scale = Vector3.new(0.6, 0.6, 0.6) knifeTexture.MeshId = "rbxassetid://121944778" knifeTexture.TextureId = texture weaponParts = {Weapon:Clone(), Weapon:Clone()} LoadAnimations(transparency) end local partNames = { "LeftUpperArm", "RightUpperArm", "Head" } function EndAnimation() for i = 1, 3 do if motors[i] then motors[i].Part1 = character:FindFirstChild(partNames[i]) end if welds[i] then welds[i]:Destroy() welds[i] = nil end end weaponParts[1].Parent = nil if weaponModel then weaponModel.Parent = nil end end local animationModel = Instance.new("Model") animationModel.Name = "WeaponAnimation" weaponModel = animationModel local camLArm = MakeKnifeBody() camLArm.Parent = animationModel camLArm.Transparency = 0.4 local bMesh = Instance.new("BlockMesh") bMesh.Parent = camLArm bMesh.Scale = Vector3.new(5, 10, 5) local camRArm = camLArm:Clone() camRArm.Parent = animationModel local AnimationType, AnimationState = nil, nil function RunAnimation(type, state) AnimationType = type AnimationState = state end function StartAnimation() local check = { character.LeftUpperArm:FindFirstChild("LeftWeld"), character.RightUpperArm:FindFirstChild("RightWeld"), character.Head:FindFirstChild("HeadWeld") } if check[1] then check[1]:Destroy() end if check[2] then check[2]:Destroy() end if check[3] then check[3]:Destroy() end check = { character:FindFirstChild("WeaponObject"), camera:FindFirstChild("WeaponAnimation") } if check[1] then check[1].Parent = nil end if check[2] then check[2].Parent = nil end if motors[1] then motors[1].Part1 = nil end if motors[2] then motors[2].Part1 = nil end if motors[3] then motors[3].Part1 = nil end local weldParts = { { "UpperTorso", "LeftWeld", CFrame.new(-1.5, 0, 0), character.LeftUpperArm }, { "UpperTorso", "RightWeld", CFrame.new(1.5, 0, 0), character.RightUpperArm }, { "UpperTorso", "HeadWeld", CFrame.new(0, -1.43, 0), character.Head } } welds = { Instance.new(Settings.ConnectionType), Instance.new(Settings.ConnectionType), Instance.new(Settings.ConnectionType) } for i = 1, 3 do welds[i].Part0 = weldParts[i][4] welds[i].Part1 = character:FindFirstChild(weldParts[i][1]) welds[i].Name = weldParts[i][2] welds[i].C0 = weldParts[i][3] welds[i].Parent = weldParts[i][4] end weaponParts[1].Parent = character local weld = Instance.new(Settings.ConnectionType) weld.Part0 = character:FindFirstChild("RightUpperArm") -- wont be positioned correctly weld.Part1 = weaponParts[1] weld.C0 = CFrame.new() weld.Parent = weaponParts[1] local weld1, weld2, weld3 = unpack(welds) local camWelds = { Instance.new(Settings.ConnectionType), Instance.new(Settings.ConnectionType), Instance.new(Settings.ConnectionType) } camWelds[1].Part0 = character.UpperTorso camWelds[1].Part1 = camLArm camWelds[1].Parent = camLArm camWelds[2].Part0 = character.UpperTorso camWelds[2].Part1 = camRArm camWelds[2].Parent = camRArm camWelds[3].Part0 = camRArm camWelds[3].Part1 = weaponParts[2] camWelds[3].Parent = weaponParts[2] weaponParts[2].Parent = animationModel local animationSpeed = 3 local lastPos = Vector3.new() local moveAmount = 0 coroutine.wrap(function() while weld1.Parent ~= nil do local delta = task.wait(1 / 25) local currentPos = character.UpperTorso.Position if (currentPos - lastPos).Magnitude >= 0.1 then moveAmount = math.min(1, moveAmount + delta * animationSpeed) else moveAmount = math.max(0, moveAmount - delta * animationSpeed) end lastPos = currentPos end end)() local lastViewAngle1, lastViewAngle2, viewVelocity = 0, 0, {0, 0} coroutine.wrap(function() local last = tick() while weld1.Parent ~= nil do RunService.RenderStepped:Wait() local delta = tick() - last last = tick() local breatheAmp = 2 local breatheFrequency = 0.8 local breathe = math.sin(math.rad(tick() * 90 * breatheFrequency)) * breatheAmp local shakeFrequency = 5 local shakeAmp = {0.05, 0.05} local armShake = CFrame.new( math.sin(math.rad(tick() * 90 * shakeFrequency)) * moveAmount * shakeAmp[1], 0, math.abs(math.sin(math.rad(tick() * 90 * shakeFrequency)) * moveAmount * shakeAmp[2]) ) -- Loop local pDistance = (head.Position - mouse.Hit.Position).Magnitude if pDistance == 0 then pDistance = 0.0001 end local pHeight = mouse.Hit.Position.Y - head.Position.Y local viewAngle1 if pHeight ~= 0 then viewAngle1 = math.deg(math.asin(math.abs(pHeight) / pDistance)) * (math.abs(pHeight) / pHeight) else viewAngle1 = 0 end local camCFrame = camera.CFrame local focused = camCFrame * CFrame.new(0, 0, -100) local viewAngle2 = math.deg(math.atan2(camCFrame.Position.X - focused.Position.X, camCFrame.Position.Z - focused.Position.Z)) + 180 local viewDelta1, viewDelta2 local dir1, dir2 = 0, 0 viewDelta1 = math.abs(viewAngle1 - lastViewAngle1) if viewDelta1 ~= 0 then dir1 = (viewAngle1 - lastViewAngle1) / viewDelta1 end local viewAngleCheck = { math.abs(viewAngle2 - lastViewAngle2), 360 - math.abs(viewAngle2 - lastViewAngle2) } if viewAngle2 == lastViewAngle2 then dir2 = 0 viewDelta2 = 0 elseif viewAngleCheck[1] < viewAngleCheck[2] then viewDelta2 = viewAngleCheck[1] dir2 = (viewAngle2 - lastViewAngle2) / viewAngleCheck[1] else viewDelta2 = viewAngleCheck[2] if lastViewAngle2 > viewAngle2 then dir2 = 1 else dir2 = -1 end end lastViewAngle1 = viewAngle1 lastViewAngle2 = viewAngle2 viewVelocity[1] = viewVelocity[1] / (1 + (delta * AnimationSettings.AimRetract)) viewVelocity[2] = viewVelocity[2] / (1 + (delta * AnimationSettings.AimRetract)) local calc1 = viewDelta1 * dir1 * AnimationSettings.AimAmplifier if calc1 ~= 0 then viewVelocity[1] = viewVelocity[1] + (math.min(AnimationSettings.AimMaxChange, math.abs(calc1)) * (calc1 / math.abs(calc1))) end local calc2 = viewDelta2 * dir2 * AnimationSettings.AimAmplifier if calc2 ~= 0 then viewVelocity[2] = viewVelocity[2] + (math.min(AnimationSettings.AimMaxChange, math.abs(calc2)) * (calc2 / math.abs(calc2))) end if viewVelocity[1] ~= 0 then viewVelocity[1] = math.min(AnimationSettings.AimMaxDegree, math.abs(viewVelocity[1])) * (math.abs(viewVelocity[1]) / viewVelocity[1]) end if viewVelocity[2] ~= 0 then viewVelocity[2] = math.min(AnimationSettings.AimMaxDegree, math.abs(viewVelocity[2])) * (math.abs(viewVelocity[2]) / viewVelocity[2]) end if AnimationState == nil then AnimationState = 0 end if AnimationType ~= nil then if Animations[AnimationType] == nil then AnimationType = "Default" end else AnimationType = "Default" end local currentAnimation = PlayAnimation(AnimationType, AnimationState) local chestCFrame = CFrame.new(0, 0.5, 0) * CFrame.Angles(math.rad(math.max(-Settings.RotationAmplitudeChest, math.min(Settings.RotationAmplitudeChest, viewAngle1)) + 90 + breathe), 0, 0) weld1.C1 = (chestCFrame * currentAnimation[1] * CFrame.new(0, -0.5, 0)):Inverse() weld2.C1 = (chestCFrame * currentAnimation[2] * CFrame.new(0, -0.5, 0)):Inverse() weaponParts[1].Transparency = currentAnimation[4] if Settings.AnimateHead then weld3.C1 = (CFrame.new(0, 0, 0) * CFrame.Angles(math.rad(math.max(-Settings.RotationAmplitudeHead, math.min(Settings.RotationAmplitudeHead, viewAngle1))), 0, 0) * CFrame.Angles(0.0001, 0.0001, 0.0001)):Inverse() else weld3.C1 = (CFrame.new(0, 0, 0)):Inverse() end if (head.Position - camera.CFrame.Position).Magnitude < 3 then if animationModel.Parent == nil then animationModel.Parent = camera end camWelds[1].Parent = camLArm camWelds[2].Parent = camRArm camWelds[3].Parent = weaponParts[2] local camCF = camera.CFrame * CFrame.Angles(math.rad(90 + (breathe / 2) - viewVelocity[1]), 0, math.rad(viewVelocity[2])) * armShake * AnimationSettings.CameraOffset camWelds[1].C1 = (character.UpperTorso.CFrame:Inverse() * camCF * CFrame.new(-1.5, 0, 0) * currentAnimation[1] * CFrame.new(0, -0.5, 0)):Inverse() camWelds[2].C1 = (character.UpperTorso.CFrame:Inverse() * camCF * CFrame.new(1.5, 0, 0) * currentAnimation[2] * CFrame.new(0, -0.5, 0)):Inverse() camWelds[3].C1 = (currentAnimation[3]):Inverse() weaponParts[2].Transparency = currentAnimation[4] else if animationModel.Parent ~= nil then animationModel.Parent = nil end end end end)() end return {SetupWeapon, StartAnimation, RunAnimation, EndAnimation}