Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function Service:LoadIKAnimator(Options)
- if Service.CharacterBeingHandled then
- repeat wait() until (not Service.CharacterBeingHandled)
- end
- local PreventLeftAnimator = Options.PreventLeftAnimator
- local IK = {}
- local Character = Service.Character
- local Humanoid = Character:WaitForChild("Humanoid")
- local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
- local LowerTorso = Character:WaitForChild("LowerTorso")
- local UpperTorso = Character:WaitForChild("UpperTorso")
- local LeftUpperArm = Character:WaitForChild("LeftUpperArm")
- local LeftLowerArm = Character:WaitForChild("LeftLowerArm")
- local LeftHand = Character:WaitForChild("LeftHand")
- local RightUpperArm = Character:WaitForChild("RightUpperArm")
- local RightLowerArm = Character:WaitForChild("RightLowerArm")
- local RightHand = Character:WaitForChild("RightHand")
- local LeftShoulder = LeftUpperArm:WaitForChild("LeftShoulder")
- local LeftElbow = LeftLowerArm:WaitForChild("LeftElbow")
- local LeftWrist = LeftHand:WaitForChild("LeftWrist")
- local LeftGripAttachment = LeftHand:WaitForChild("LeftGripAttachment")
- local RightShoulder = RightUpperArm:WaitForChild("RightShoulder")
- local RightElbow = RightLowerArm:WaitForChild("RightElbow")
- local RightWrist = RightHand:WaitForChild("RightWrist")
- local RightGripAttachment = RightHand:WaitForChild("RightGripAttachment")
- local HEIGHT_UT_HALF = UpperTorso.Size.Y / 2
- local HEIGHT_UT_QUAD = HEIGHT_UT_HALF / 2
- local CF_UT_HALF = CF(0, HEIGHT_UT_HALF, 0)
- local CF_UT_HALF_N = CF(0, -HEIGHT_UT_HALF, 0)
- local LSC0 = CF(-UpperTorso.Size.X / 2 - LeftUpperArm.Size.X / 2, UpperTorso.Size.Y / 4, 0)
- local LSC1 = CF(0, LeftUpperArm.Size.Y / 2, 0)
- local LEC0 = CF(0, -LeftUpperArm.Size.Y / 2, 0)
- local LEC1 = CF(0, LeftLowerArm.Size.Y / 2, 0)
- local RSC0 = CF(UpperTorso.Size.X / 2 + RightUpperArm.Size.X / 2, UpperTorso.Size.Y / 4, 0)
- local RSC1 = CF(0, RightUpperArm.Size.Y / 2, 0)
- local REC0 = CF(0, -RightUpperArm.Size.Y / 2, 0)
- local REC1 = CF(0, RightLowerArm.Size.Y / 2, 0)
- local LL1 = LeftUpperArm.Size.Y
- local LL2 = LEC1.Y
- - Service.Joints.LeftWrist.C0.Y
- + Service.Joints.LeftWrist.C1.Y
- - LeftGripAttachment.Position.Y
- local RL1 = RightUpperArm.Size.Y
- local RL2 = REC1.Y
- - Service.Joints.RightWrist.C0.Y
- + Service.Joints.RightWrist.C1.Y
- - RightGripAttachment.Position.Y
- local SolverLeft = IKSolver.new({
- SizeLimb0 = LL1,
- SizeLimb1 = LL2
- })
- local SolverRight = IKSolver.new({
- SizeLimb0 = RL1,
- SizeLimb1 = RL2
- })
- local SolverLeftPure = IKSolver.new({
- SizeLimb0 = LL1,
- SizeLimb1 = LL2 + LeftGripAttachment.Position.Y - Service.Joints.RightWrist.C1.Y
- })
- local SolverRightPure = IKSolver.new({
- SizeLimb0 = RL1,
- SizeLimb1 = RL2 + LeftGripAttachment.Position.Y - Service.Joints.RightWrist.C1.Y
- })
- local IKSolveLeft = SolverLeft.Solve
- local IKSolveRight = SolverRight.Solve
- local IKSolveLeftPure = SolverLeftPure.Solve
- local IKSolveRightPure = SolverRightPure.Solve
- local StopServerUpdateData = {}
- StopServerUpdateData[#StopServerUpdateData + 1] = {Service.Joints.RightShoulder.Joint, Service.Joints.RightShoulder.C0, Service.Joints.RightShoulder.C1}
- StopServerUpdateData[#StopServerUpdateData + 1] = {Service.Joints.RightElbow.Joint, Service.Joints.RightElbow.C0, Service.Joints.RightElbow.C1}
- StopServerUpdateData[#StopServerUpdateData + 1] = {Service.Joints.RightWrist.Joint, Service.Joints.RightWrist.C0}
- StopServerUpdateData[#StopServerUpdateData + 1] = {Service.Joints. LeftShoulder.Joint, Service.Joints. LeftShoulder.C0, Service.Joints.LeftShoulder.C1}
- StopServerUpdateData[#StopServerUpdateData + 1] = {Service.Joints. LeftElbow.Joint, Service.Joints. LeftElbow.C0, Service.Joints.LeftElbow.C1}
- StopServerUpdateData[#StopServerUpdateData + 1] = {Service.Joints. LeftWrist.Joint, Service.Joints. LeftWrist.C0}
- if Options.LookAroundConstraints then
- StopServerUpdateData[#StopServerUpdateData + 1] = {Service.Joints.Waist.Joint, Service.Joints.Waist.C0}
- StopServerUpdateData[#StopServerUpdateData + 1] = {Service.Joints.Neck .Joint, Service.Joints.Neck .C0}
- end
- IK.OverrideLook = nil
- IK.UpdateQueue = {}
- IK.UpdateFuncs = {}
- IK.Connections = {}
- IK.Events = {}
- IK.State = {}
- IK.State.Playing = false
- IK.State.Paused = false
- IK.State.LastStartTime = 0
- IK.State.LastStopTime = 0
- IK.State.AlignCharacter = false
- local LastServerUpdate = 0
- local LastServerUpdateData = {}
- local ServerRefreshWait = 0.1
- IK.GetGoalLeft = Options.GetGoalLeft
- IK.GetGoalRight = Options.GetGoalRight
- local UpdateFuncs = IK.UpdateFuncs
- local UpdateQueue = IK.UpdateQueue
- local Connections = IK.Connections
- local Events = IK.Events
- local State = IK.State
- local TRANS_FACTOR = Service.Constants.TRANS_FACTOR
- local TRANS_FIXED_STEP = Service.Constants.TRANS_FIXED_STEP
- function IK:SetGoalLeft(F)
- IK.GetGoalLeft = F
- end
- function IK:SetGoalRight(F)
- IK.GetGoalRight = F
- end
- function IK:CanAlignCharacter()
- return Humanoid:GetState() ~= Enum.HumanoidStateType.Seated
- end
- function IK:SetCharacterAlignEnabled(Enabled)
- State.AlignCharacter = Enabled
- end
- function IK:AddToUpdateQueue(F)
- UpdateQueue[#UpdateQueue + 1] = F
- end
- function IK:AddToUpdateQueuePerma(F)
- UpdateFuncs[#UpdateFuncs + 1] = F
- end
- local function Flush()
- RemoteService.Remotes.Event:FireServer(
- "ServerMotor6DReceive", LastServerUpdateData, 0.15
- )
- end
- function IK:SetupAlignCharacter()
- local CanAlignCharacter = IK.CanAlignCharacter
- local RootJoint = Service.Joints.Root
- local C0 = RootJoint.C0
- local Motor6D = RootJoint.Joint
- local _, AnglePosInit = C0:toEulerAnglesXYZ()
- local _, AnglePos = Motor6D.C0:toEulerAnglesXYZ()
- local MotorC0 = Angles(0, AnglePos, 0)
- local ServerData = {Motor6D, MotorC0}
- IK:AddToUpdateQueue(function(Now, Delta, Alpha, Hit, CF_HRP, CF_UT)
- debug.profilebegin("IKAlignCharacter")
- local Azimuth = GetPolar3(Polar3, CF_HRP:inverse() * Hit)
- local AnglePosDesired = (
- State.AlignCharacter and CanAlignCharacter()
- ) and -(Azimuth + PI_HALF) or AnglePosInit
- AnglePos = AnglePos
- + ((AnglePosDesired - AnglePos + PI) % PI_2 - PI)
- * clamp(1 - pow(1 - 0.2, 60 * Delta), 0, 1)
- MotorC0 = C0 * Angles(0,
- AnglePosInit + ((AnglePos - AnglePosInit + PI) % PI_2 - PI) * Alpha, 0)
- Motor6D.C0 = MotorC0
- ServerData[2] = MotorC0
- debug.profileend()
- return ServerData
- end)
- end
- function IK:SetupLookAround(Options)
- local RootJoint = Service.Joints.Root
- local C0 = RootJoint.C0
- local Motor6D = RootJoint.Joint
- local WaistData = Service.Joints.Waist
- local Waist = WaistData.Joint
- local WaistC0 = WaistData.C0
- local WaistC1 = WaistData.C1
- local NeckData = Service.Joints.Neck
- local Neck = NeckData.Joint
- local NeckC0 = NeckData.C0
- local NeckC1 = NeckData.C1
- local RootData = Service.Joints.Root
- local RootC0 = RootData.C0
- local RootC1 = RootData.C1
- local HeightAim = RootC0.Y - RootC1.Y + WaistC0.Y - WaistC1.Y + UpperTorso.Size.Y / 4
- local HeightAimCF = CF(0, HeightAim, 0)
- local HeightAimLT = WaistC0.Y - WaistC1.Y + UpperTorso.Size.Y / 4
- local HeightAimLTCF = CF(0, HeightAimLT, 0)
- local AngleX = Options.LimitTorsoAzimuth
- local AngleY = Options.LimitTorsoElevation
- local CurrX, CurrY = 0, 0
- local HeadA, HeadE = 0, 0
- local ServerDataWaist = {Waist, WaistC0}
- local ServerDataNeck = {Neck , NeckC0 }
- local VECTOR3_MULT_ZN = V3(1, 1, -1)
- IK:AddToUpdateQueue(function(Now, Delta, Alpha, Hit, CF_HRP, CF_UT)
- debug.profilebegin("IKLookAround")
- local LocalSpace = LookAtUV(Vector, CF_HRP.p, CF_HRP.p + CF_HRP.upVector, LowerTorso.CFrame.lookVector)
- local LocalSpaceHit = LocalSpace:pointToObjectSpace(Hit)
- if LocalSpaceHit.Z > 0 then
- Hit = LocalSpace:pointToWorldSpace(LocalSpaceHit * VECTOR3_MULT_ZN)
- end
- local Azimuth, Elevation = GetPolar3(
- Polar3, (LowerTorso.CFrame * HeightAimLTCF):pointToObjectSpace(Hit)
- )
- local X, Y = (Azimuth * (Azimuth > 0 and -1 or 1) + PI_HALF) / PI_HALF, Elevation / PI_HALF
- local Scale = clamp(1 - pow(1 - 0.1, 60 * Delta), 0, 1)
- CurrX = CurrX + (X - CurrX) * Scale
- CurrY = CurrY + (Y - CurrY) * Scale
- CurrX = CurrX * Alpha
- CurrY = CurrY * Alpha
- --[[
- local WC0 = WaistC0 * FromAxisAngle((LowerTorso.CFrame * WaistC0):vectorToObjectSpace(
- CF_HRP.upVector
- ), -CurrX * AngleX * Alpha) * Angles(CurrY * AngleY * Alpha, 0, 0)
- ]]
- local WC0 = WaistC0 * Angles(CurrY * AngleY * Alpha, -CurrX * AngleX * Alpha, 0)
- Waist.C0 = WC0
- ServerDataWaist[2] = WC0
- local A, E = GetPolar3(Polar3, (
- CF_UT * CF_UT_HALF
- ):inverse() * Hit)
- A = A > 0 and -A or A
- HeadA = HeadA + (A - HeadA) * Scale
- HeadE = HeadE + (E - HeadE) * Scale
- HeadA = HeadA + ((PI_HALF - HeadA) % PI_2 - PI) * (1 - Alpha)
- HeadE = HeadE * Alpha
- local NC0 = NeckC0 * LookAt(Vector,
- ZERO_VECTOR3, GetVector3(Polar3, HeadA, HeadE, 1), VECTOR3_UP
- )
- Neck.C0 = NC0
- ServerDataNeck[2] = NC0
- debug.profileend()
- return ServerDataWaist, ServerDataNeck
- end)
- end
- local C0LeftShoulder = Service.Joints.LeftShoulder.C0
- local C1LeftShoulder = Service.Joints.LeftShoulder.C1
- local C0LeftElbow = Service.Joints.LeftElbow.C0
- local C1LeftElbow = Service.Joints.LeftElbow.C1
- local C0LeftWrist = Service.Joints.LeftWrist.C0
- local C1LeftWrist = Service.Joints.LeftWrist.C1
- local CFLeftGripInv = LeftGripAttachment.CFrame:inverse()
- local C0RightShoulder = Service.Joints.RightShoulder.C0
- local C1RightShoulder = Service.Joints.RightShoulder.C1
- local C0RightElbow = Service.Joints.RightElbow.C0
- local C1RightElbow = Service.Joints.RightElbow.C1
- local C0RightWrist = Service.Joints.RightWrist.C0
- local C1RightWrist = Service.Joints.RightWrist.C1
- local CFRightGripInv = RightGripAttachment.CFrame:inverse()
- local ServerDataLeftShoulder = {LeftShoulder, LeftShoulder.C0}
- local ServerDataLeftElbow = {LeftElbow, LeftElbow.C0}
- local ServerDataLeftWrist = {LeftWrist, LeftWrist.C0}
- local ServerDataRightShoulder = {RightShoulder, RightShoulder.C0}
- local ServerDataRightElbow = {RightElbow, RightElbow.C0}
- local ServerDataRightWrist = {RightWrist, RightWrist.C0}
- local OffsetLeft = CF(-UpperTorso.Size.X / 2 - LeftUpperArm.Size.X / 2, UpperTorso.Size.Y / 4, 0)
- local OffsetLeftLowerArm = CF(0, -LeftLowerArm.Size.Y, 0)
- local OffsetRight = CF(UpperTorso.Size.X / 2 + RightUpperArm.Size.X / 2, UpperTorso.Size.Y / 4, 0)
- local OffsetRightLowerArm = CF(0, -RightLowerArm.Size.Y, 0)
- local function UpdateLeft(Now, Delta, Alpha, Hit, CF_HRP, CF_UT)
- debug.profilebegin("IKUpdateLeft")
- local GetGoalLeft = IK.GetGoalLeft
- local Playing = State.Playing
- local LSC0, LEC0, LWC0
- if not Playing and Alpha ~= 1 then
- LSC0 = C0LeftShoulder:lerp(LeftShoulder.C0, Alpha)
- LEC0 = C0LeftElbow:lerp(LeftElbow.C0, Alpha)
- LWC0 = C0LeftWrist:lerp(LeftWrist.C0, Alpha)
- elseif GetGoalLeft then
- local CFShoulder = CF_UT * LeftShoulder.C0--* OffsetLeft
- local Goal, GoalElbow, GripCFrame = GetGoalLeft(Now, Delta, Alpha, Hit, CF_HRP, CF_UT)
- local JointCFrameShoulder, JointCFrameElbow
- if GripCFrame then
- local GoalCF = GripCFrame * CFLeftGripInv * C1LeftWrist
- Goal = GoalCF.p
- JointCFrameShoulder, JointCFrameElbow = IKSolveLeftPure(
- SolverLeft, Goal, GoalElbow, CFShoulder,
- CFShoulder * LeftShoulder.C1:inverse() * LeftElbow.C0
- )
- JointCFrameElbow = JointCFrameElbow
- + (Goal - (JointCFrameElbow * OffsetLeftLowerArm).p) / 2
- LWC0 = (
- JointCFrameElbow * LeftElbow.C1:inverse()
- ):toObjectSpace(GoalCF)
- else
- JointCFrameShoulder, JointCFrameElbow = IKSolveLeft(
- SolverLeft, Goal, GoalElbow, CFShoulder,
- LeftLowerArm.CFrame * LeftElbow.C0
- )
- LWC0 = C0LeftWrist
- end
- LSC0 = CF_UT:toObjectSpace(JointCFrameShoulder * CFrame.Angles(0, -math.pi / 2, 0))
- LEC0 = (
- JointCFrameShoulder * LeftShoulder.C1:inverse() * CFrame.Angles(0, -math.pi / 2, 0)
- ):toObjectSpace(JointCFrameElbow)
- end
- LeftShoulder.C0 = LSC0
- LeftElbow.C0 = LEC0
- LeftWrist.C0 = LWC0
- ServerDataLeftShoulder[2] = LSC0
- ServerDataLeftElbow[2] = LEC0
- ServerDataLeftWrist[2] = LWC0
- debug.profileend()
- return ServerDataLeftShoulder, ServerDataLeftElbow, ServerDataLeftWrist
- end
- local ANGLES_PI = Angles(0, PI, 0)
- local function UpdateRight(Now, Delta, Alpha, Hit, CF_HRP, CF_UT)
- debug.profilebegin("IKUpdateRight")
- local GetGoalRight = IK.GetGoalRight
- local Playing = State.Playing
- local RSC0, REC0, RWC0
- if not Playing and Alpha ~= 1 then
- RSC0 = C0RightShoulder:lerp(RightShoulder.C0, Alpha)
- REC0 = C0RightElbow:lerp(RightElbow.C0, Alpha)
- RWC0 = C0RightWrist:lerp(RightWrist.C0, Alpha)
- elseif GetGoalRight then
- local CFShoulder = CF_UT * RightShoulder.C0--* OffsetRight
- local Goal, GoalElbow, GripCFrame = GetGoalRight(Now, Delta, Alpha, Hit, CF_HRP, CF_UT)
- local JointCFrameShoulder, JointCFrameElbow
- if GripCFrame then
- local GoalCF = GripCFrame * CFRightGripInv * C1RightWrist
- Goal = GoalCF.p
- JointCFrameShoulder, JointCFrameElbow = IKSolveRightPure(
- SolverRight, Goal, GoalElbow, CFShoulder,
- CFShoulder * RightShoulder.C1:inverse() * RightElbow.C0
- )
- JointCFrameElbow = JointCFrameElbow
- + (Goal - (JointCFrameElbow * OffsetRightLowerArm).p) / 2
- RWC0 = (
- JointCFrameElbow * RightElbow.C1:inverse()
- ):toObjectSpace(GoalCF)
- else
- JointCFrameShoulder, JointCFrameElbow = IKSolveRight(
- SolverRight, Goal, GoalElbow, CFShoulder,
- CFShoulder * RightShoulder.C1:inverse() * RightElbow.C0
- )
- RWC0 = C0RightWrist
- end
- RSC0 = CF_UT:toObjectSpace(JointCFrameShoulder) * Angles(0, -math.pi / 2, 0) --* ANGLES_PI
- REC0 = (
- JointCFrameShoulder * RSC1:inverse() * Angles(0, -math.pi / 2, 0)
- ):toObjectSpace(JointCFrameElbow)
- end
- RightShoulder.C0 = RSC0
- RightElbow.C0 = REC0
- RightWrist.C0 = RWC0
- ServerDataRightShoulder[2] = RSC0
- ServerDataRightElbow[2] = REC0
- ServerDataRightWrist[2] = RWC0
- debug.profileend()
- return ServerDataRightShoulder, ServerDataRightElbow, ServerDataRightWrist
- end
- local ServerDataRSC1 = {RightShoulder, nil, RightShoulder.C1}
- local ServerDataREC1 = {RightElbow, nil, RightElbow.C1}
- local ServerDataLSC1 = {LeftShoulder, nil, LeftShoulder.C1}
- local ServerDataLEC1 = {LeftElbow, nil, LeftElbow.C1}
- function IK:Update(Delta, ForceUpdateQueue)
- debug.profilebegin("IKUpdate")
- local UpdateQueue = ForceUpdateQueue or UpdateQueue
- local Now = tick()
- local Hit = IK.OverrideLook and IK.OverrideLook(Now, Delta) or LocalPlayerMouse.Hit.p
- local Alpha = State.Playing and
- (Now - State.LastStartTime) / 0.3 or
- 1 - (Now - State.LastStopTime ) / 0.3
- Alpha = Alpha < 0 and 0 or Alpha > 1 and 1 or Alpha
- RightShoulder.C1 = C1RightShoulder:lerp(RSC1, Alpha)
- RightElbow.C1 = C1RightElbow:lerp(REC1, Alpha)
- ServerDataRSC1[3] = RightShoulder.C1
- ServerDataREC1[3] = RightElbow.C1
- if not PreventLeftAnimator then
- LeftShoulder.C1 = C1LeftShoulder:lerp(LSC1, Alpha)
- LeftElbow.C1 = C1LeftElbow:lerp(LEC1, Alpha)
- ServerDataLEC1[3] = LeftElbow.C1
- ServerDataLSC1[3] = LeftShoulder.C1
- end
- local ServerUpdate = Now - LastServerUpdate > ServerRefreshWait
- if ServerUpdate then
- LastServerUpdate = Now
- LastServerUpdateData = {
- ServerDataRSC1,
- ServerDataREC1
- }
- if not PreventLeftAnimator then
- LastServerUpdateData[#LastServerUpdateData + 1] = ServerDataLSC1
- LastServerUpdateData[#LastServerUpdateData + 1] = ServerDataLEC1
- end
- end
- for _, QueueItem in pairs(UpdateQueue) do
- local ServerMotorData = {QueueItem(Now, Delta, Alpha, Hit, HumanoidRootPart.CFrame, UpperTorso.CFrame)}
- if ServerUpdate then
- for _, Data in pairs(ServerMotorData) do
- LastServerUpdateData[#LastServerUpdateData + 1] = Data
- end
- end
- end
- local ServerMotorData = {}
- ServerMotorData[1], ServerMotorData[2], ServerMotorData[3] =
- UpdateRight(Now, Delta, Alpha, Hit, HumanoidRootPart.CFrame, UpperTorso.CFrame)
- if not PreventLeftAnimator then
- ServerMotorData[4], ServerMotorData[5], ServerMotorData[6] =
- UpdateLeft(Now, Delta, Alpha, Hit, HumanoidRootPart.CFrame, UpperTorso.CFrame)
- else
- ServerMotorData[4], ServerMotorData[5], ServerMotorData[6] =
- {LeftShoulder, C0LeftShoulder, C1LeftShoulder},
- {LeftWrist, C0LeftWrist, C1LeftWrist},
- {LeftElbow, C0LeftElbow, C1LeftElbow}
- end
- if ServerUpdate then
- for _, Data in pairs(ServerMotorData) do
- LastServerUpdateData[#LastServerUpdateData + 1] = Data
- end
- Flush()
- end
- debug.profileend()
- return IK
- end
- local ServerDataC1 = {
- {RightShoulder, nil, C1RightShoulder},
- {RightElbow, nil, C1RightElbow}
- }
- if not PreventLeftAnimator then
- ServerDataC1[#ServerDataC1 + 1] = {LeftShoulder, nil, C1LeftShoulder}
- ServerDataC1[#ServerDataC1 + 1] = {LeftElbow, nil, C1LeftElbow}
- end
- function IK:Fade(UpdateQueue, Stopped)
- local LastStopTime = State.LastStopTime
- local Connection
- --local ConnectionStepped
- local Disconnected
- local Result = {}
- local function Disconnect()
- if Disconnected then return end
- Disconnected = true
- Connection:Disconnect()
- end
- Connection = RunService.RenderStepped:Connect(function(Delta)
- if
- (not Result.Stopped and Service.CurrentResponsiveAnimation ~= IK) or
- ( Result.Stopped and Service.CurrentResponsiveAnimation)
- then
- Connection:Disconnect()
- --ConnectionStepped:Disconnect()
- RightShoulder.C1 = C1RightShoulder
- RightElbow.C1 = C1RightElbow
- if not PreventLeftAnimator then
- LeftShoulder.C1 = C1LeftShoulder
- LeftElbow.C1 = C1LeftElbow
- end
- RemoteService.Remotes.Event:FireServer(
- "ServerMotor6DReceive", ServerDataC1, 0.15
- )
- else
- IK:Update(Delta, UpdateQueue)
- if tick() - LastStopTime > 0.3 then
- Disconnect()
- RemoteService.Remotes.Event:FireServer(
- "ServerMotor6DReceive", IK.StopServerUpdateData, 0.15)
- end
- end
- end)
- --ConnectionStepped = RunService.Stepped:Connect(IK.NegateTransform)
- Result.Stopped = Stopped
- Result.Disconnect = Disconnect
- return Result
- end
- --[[
- function IK:NegateTransform()
- local Now = tick()
- local Alpha = State.Playing and
- clamp((Now - State.LastStartTime) / 0.3, 0, 1) or
- clamp(1 - (Now - State.LastStopTime ) / 0.3, 0, 1)
- if Alpha == 1 then
- if Options.LookAroundConstraints then
- Service.Joints.Waist.Joint.Transform = ZERO_CFRAME
- Service.Joints.Neck.Joint.Transform = ZERO_CFRAME
- end
- RightShoulder.Transform = ZERO_CFRAME
- RightElbow.Transform = ZERO_CFRAME
- RightWrist.Transform = ZERO_CFRAME
- LeftShoulder.Transform = ZERO_CFRAME
- LeftElbow.Transform = ZERO_CFRAME
- LeftWrist.Transform = ZERO_CFRAME
- else
- Alpha = 1 - Alpha
- if Options.LookAroundConstraints then
- Service.Joints.Waist.Joint.Transform = ZERO_CFRAME:lerp(Service.Joints.Waist.Joint.Transform, Alpha)
- Service.Joints.Neck.Joint.Transform = ZERO_CFRAME:lerp(Service.Joints.Neck.Joint.Transform, Alpha)
- end
- RightShoulder.Transform = ZERO_CFRAME:lerp(RightShoulder.Transform, Alpha)
- RightElbow.Transform = ZERO_CFRAME:lerp(RightElbow.Transform, Alpha)
- RightWrist.Transform = ZERO_CFRAME:lerp(RightWrist.Transform, Alpha)
- LeftShoulder.Transform = ZERO_CFRAME:lerp(LeftShoulder.Transform, Alpha)
- LeftElbow.Transform = ZERO_CFRAME:lerp(LeftElbow.Transform, Alpha)
- LeftWrist.Transform = ZERO_CFRAME:lerp(LeftWrist.Transform, Alpha)
- end
- end]]
- function IK:Play()
- if State.Playing then return IK end
- if State.Paused then
- if Service.CurrentResponsiveAnimation ~= IK then
- Service.CurrentResponsiveAnimation:Stop()
- end
- State.Paused:Disconnect()
- State.Paused = false
- else
- if Service.CurrentResponsiveAnimation then
- Service.CurrentResponsiveAnimation:Stop()
- end
- IK:SetupAlignCharacter()
- if Options.LookAroundConstraints then
- IK:SetupLookAround(Options.LookAroundConstraints)
- end
- for _, Produce in pairs(IK.UpdateFuncs) do
- UpdateQueue[#UpdateQueue + 1] = Produce()
- end
- end
- local Now = tick()
- local StopTimeDelta = Now - State.LastStopTime
- State.Playing = true
- State.LastStartTime = StopTimeDelta < 0.3 and Now - 0.3 + StopTimeDelta or Now
- if PreventLeftAnimator then
- Service.Animations.Tracks.TorsoRight:Play(0)
- else
- Service.Animations.Tracks.Freeze:Play(0)
- end
- IK.Connections.Update = RunService.RenderStepped:Connect(
- General:ClassWrap(IK, IK.Update))
- if PreventLeftAnimator then
- LeftShoulder.C0 = C0LeftShoulder
- LeftShoulder.C1 = C1LeftShoulder
- LeftElbow.C0 = C0LeftElbow
- LeftElbow.C1 = C1LeftElbow
- LeftWrist.C0 = C0LeftWrist
- LeftWrist.C1 = C1LeftWrist
- end
- --Connections.NegateTransform = RunService.Stepped:Connect(IK.NegateTransform)
- Service.CurrentResponsiveAnimation = IK
- return IK
- end
- function IK:Stop()
- if not State.Playing and not State.Paused then return IK end
- if State.Paused then
- State.Paused.Stopped = true
- State.Paused = false
- else
- local Now = tick()
- local StartTimeDelta = Now - State.LastStartTime
- State.Playing = false
- State.LastStopTime = StartTimeDelta < 0.3 and Now - 0.3 + StartTimeDelta or Now
- General:ClearConnections(Connections)
- if Service.CurrentResponsiveAnimation == IK then
- Service.CurrentResponsiveAnimation = nil
- end
- if PreventLeftAnimator then
- Service.Animations.Tracks.TorsoRight:Stop(0.3)
- else
- Service.Animations.Tracks.Freeze:Stop(0.3)
- end
- IK:Fade(UpdateQueue, true)
- end
- IK.UpdateQueue = {}
- UpdateQueue = {}
- return IK
- end
- function IK:Pause()
- if not State.Playing then return IK end
- General:ClearConnections(Connections)
- local Now = tick()
- local StartTimeDelta = Now - State.LastStartTime
- State.Playing = false
- State.LastStopTime = StartTimeDelta < 0.3 and Now - 0.3 + StartTimeDelta or Now
- State.Paused = IK:Fade(UpdateQueue)
- if PreventLeftAnimator then
- Service.Animations.Tracks.TorsoRight:Stop(0.3)
- else
- Service.Animations.Tracks.Freeze:Stop(0.3)
- end
- return IK
- end
- return IK
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement