Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local function init()
- local JointData = {}
- JointData["Right Shoulder"] = CFrame.new(1, 0.5, 0, 0, 0, 1, 0, 1, -0, -1, 0, 0)
- JointData["Left Shoulder"] = CFrame.new(-1, 0.5, 0, 0, 0, -1, 0, 1, 0, 1, 0, 0)
- JointData["Right Hip"] = CFrame.new(1, -1, 0, 0, 0, 1, 0, 1, -0, -1, 0, 0)
- JointData["Left Hip"] = CFrame.new(-1, -1, 0, 0, 0, -1, 0, 1, 0, 1, 0, 0)
- JointData["Neck"] = CFrame.new(0, 1, 0, -1, 0, 0, 0, 0, 1, 0, 1, -0)
- JointData["RootJoint"] = CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, -0)
- local Animator = {}
- local Playing = {}
- local JointC0 = {}
- local GlobalPlaying = _G['GlobalPlaying']
- if not GlobalPlaying then
- _G['GlobalPlaying'] = {}
- GlobalPlaying = _G['GlobalPlaying']
- end
- local global_welds = _G['global_welds']
- if not global_welds then
- _G['global_welds'] = {}
- global_welds = _G['global_welds']
- end
- local TS = game:GetService("TweenService")
- local function Ver(Model)
- if Model and Model.Parent then
- if not GlobalPlaying[Model] then
- GlobalPlaying[Model] = {}
- end
- if not Playing[Model] then
- Playing[Model] = {}
- return true
- end
- end
- end
- function Animator.create_welds(targchar)
- if not global_welds[targchar] then else
- return
- end
- local anim_welds = {}
- local char_welds = {}
- for i,v in ipairs(targchar:GetDescendants()) do
- if v:IsA("Motor6D") or v:IsA("Weld") then
- if game:GetService("CollectionService"):HasTag(v,'fakemotor') then
- anim_welds[v] = v.Part0
- elseif game:GetService("CollectionService"):HasTag(v,'realmotor') then
- char_welds[v] = v.Part0
- end
- end
- end
- for i,v in ipairs(targchar:GetDescendants()) do
- if v:IsA("Motor6D") and not char_welds[v] then
- local m = Instance.new("Weld")
- m.Name = v.Name
- m.Part0 = v.Part0
- m.Part1 = v.Part1
- m.C0 = v.C0
- m.C1 = v.C1
- m.Parent = v.Parent
- game:GetService("CollectionService"):AddTag(m,'fakemotor')
- game:GetService("CollectionService"):AddTag(v,'realmotor')
- anim_welds[m] = v.Part0
- char_welds[v] = v.Part0
- end
- end
- global_welds[targchar] = {
- anim_welds = anim_welds,
- char_welds = char_welds,
- taid = 0,
- }
- end
- function Animator.toggle_anim(mode,targchar)
- local welds = global_welds[targchar]
- if welds then else
- return
- end
- welds.taid += 1
- local cid = welds.taid
- local function run()
- if cid == welds.taid then else return end
- if mode then
- for i,v in pairs(welds.anim_welds) do
- i.Enabled = true
- end
- for i,v in pairs(welds.char_welds) do
- i.Enabled = false
- end
- else
- for i,v in pairs(welds.char_welds) do
- i.Enabled = true
- end
- for i,v in pairs(welds.anim_welds) do
- i.Enabled = false
- end
- end
- end
- if not mode then
- --task.delay(0.2,run)
- run()
- else
- run()
- end
- return cid
- end
- function Animator.get_aid(targchar)
- local welds = global_welds[targchar]
- return welds.taid
- end
- local function Play(self, FadeIn, Speed, Looped)
- self.TimePosition = 0
- self.StartInternal = os.clock()
- self.FadeIn = FadeIn or 0
- self.Speed = Speed or self.Speed
- self.Looped = Looped or self.Looped
- self.LastPlayed = os.clock()
- self.fired = {}
- self.RecoverFade = {}
- local StopEvent = Instance.new("BindableEvent")
- self.Stopped = StopEvent.Event
- self.StopEvent = StopEvent
- local LoopedEvent = Instance.new("BindableEvent")
- self.OnLooped = LoopedEvent.Event
- self.LoopedEvent = LoopedEvent
- local KeyframeReachedEvent = Instance.new("BindableEvent")
- self.KeyframeReached = KeyframeReachedEvent.Event
- self.KeyframeReachedEvent = KeyframeReachedEvent
- local MarkerReachedEvent = Instance.new("BindableEvent")
- self.MarkerReached = MarkerReachedEvent.Event
- self.MarkerReachedEvent = MarkerReachedEvent
- local I = Playing[self.Model]
- if I then else
- return
- end
- self.Playing = true
- I[self] = true
- end
- local function Stop(self,fire)
- local I = Playing[self.Model]
- if I then
- if fire then
- self.StopEvent:Fire()
- end
- end
- self.LastPlayed = 0
- self.Playing = false
- I[self] = nil
- self.Stopped = nil
- if self.StopEvent then
- self.StopEvent:Destroy()
- end
- self.StopEvent = nil
- self.OnLooped = nil
- if self.StopEvent then
- self.LoopedEvent:Destroy()
- end
- self.LoopedEvent = nil
- self.KeyframeReached = nil
- if self.StopEvent then
- self.KeyframeReachedEvent:Destroy()
- end
- self.KeyframeReachedEvent = nil
- self.MarkerReached = nil
- if self.StopEvent then
- self.MarkerReachedEvent:Destroy()
- end
- self.MarkerReachedEvent = nil
- self.FadeIn = nil
- end
- local function Resume(self)
- if self.PauseInternal then
- self.StartInternal = os.clock() - self.PauseInternal
- end
- local I = Playing[self.Model]
- self.Playing = true
- I[self] = true
- end
- local function Pause(self)
- local TimeSince = os.clock() - self.StartInternal
- self.PauseInternal = TimeSince
- local I = Playing[self.Model]
- self.Playing = false
- I[self] = nil
- end
- local function SetTime(self, Time)
- self.StartInternal = os.clock() - Time
- end
- local function AdjustSpeed(self, NewSpeed)
- self.Speed = NewSpeed
- end
- local function ft(t,c)
- for i,v in pairs(t) do
- --if i == 'Parent' or i == 'Name' or i == 'Marker' or i == 'Time' or i == 'CF' then continue end
- if typeof(v) == 'table' then
- ft(v,true)
- local name = v.Name
- v.Name = nil
- local index_t = {
- Parent = t,
- Name = name or i,
- }
- if v.Marker then
- index_t.Marker = v.Marker
- v.Marker = nil
- end
- if v.Time then
- index_t.Time = v.Time
- v.Time = nil
- end
- if v.CF then
- index_t.CF = v.CF
- v.CF = nil
- end
- if tonumber(i) and not v.CF then
- index_t.Time = tonumber(i)
- end
- v = setmetatable(v,{
- __index = index_t
- })
- end
- end
- return t
- end
- local function iter(t)
- local new_t = {}
- for i,v in pairs(t) do
- --if i == 'Parent' or i == 'Name' or i == 'Marker' or i == 'Time' or i == 'CF' then continue end
- table.insert(new_t,v)
- if typeof(v) == 'table' then
- for ii,vv in pairs(iter(v)) do
- table.insert(new_t,vv)
- end
- end
- end
- return new_t
- end
- local ModelAnimations = {}
- local hasloaded = {}
- local TrackKeyframes = {}
- function Animator.Preload(Track)
- if TrackKeyframes[Track] then
- return TrackKeyframes[Track]
- end
- Track.Keyframes = ft(Track.Keyframes)
- local kf = Track.Keyframes
- table.sort(kf, function(a, b) return a.Time < b.Time end)
- local Keyframes = {}
- local jdata = {}
- local largest_time = 0
- do
- for STime, SKeyframe in next, kf do
- STime = tonumber(STime)
- if STime > largest_time then
- largest_time = STime
- end
- local descendants = iter(SKeyframe)
- local function set_marker(name)
- if not Keyframes['_null'] then
- Keyframes['_null'] = {}
- end
- Keyframes['_null'][#Keyframes['_null'] + 1] = {Time = STime, Name = name, Marker = 1, ["Info"] = nil}
- end
- if 0 >= #descendants then
- set_marker(SKeyframe.Name)
- end
- for _,Pose in next, descendants do
- if typeof(Pose) ~= 'table' then continue end
- if Pose.Name == 'HumanoidRootPart' then continue end
- if Pose.Marker then
- set_marker(Pose.Name)
- end
- local P0 = Pose.Parent.Name
- local P1 = Pose.Name
- local JT = Keyframes[P0..'KEyjtsep'..P1]
- if not JT then
- JT = {}
- Keyframes[P0..'KEyjtsep'..P1] = JT
- jdata[P0..'KEyjtsep'..P1] = 1
- end
- local Style = Pose.ES or 'Linear'
- local Direction = Pose.ED or 'In'
- local Weight = Pose.Weight or 1
- local PCF = Pose.CF
- if not PCF then continue end
- local CF
- for i,v in pairs(PCF) do
- PCF[i] = tonumber(v)
- end
- if PCF[1] then
- CF = CFrame.new(PCF[1],PCF[2],PCF[3])
- else
- CF = CFrame.new()
- end
- if PCF[4] then
- CF = CF*CFrame.Angles(PCF[4],PCF[5],PCF[6])
- end
- local Info = {EasingStyle = Style, EasingDirection = Direction, Weight = Weight, CFrame = CF}
- JT[#JT+1] = {Time = STime, Name = SKeyframe.Name, ["Info"] = Info}
- end
- end
- for Joint,Poses in pairs(Keyframes) do
- table.sort(Poses, function(a, b) return a.Time < b.Time end)
- end
- TrackKeyframes[Track] = {
- Keyframes,
- jdata,
- largest_time
- }
- return TrackKeyframes[Track]
- end
- end
- function Animator.LoadAnimation(Track, Model)
- assert(Track,'No track.')
- assert(Model,'No model.')
- local notmodel
- if not ModelAnimations[Model] then
- notmodel = true
- ModelAnimations[Model] = {}
- ModelAnimations[Model].Joints = {}
- elseif ModelAnimations[Model][Track] then
- return ModelAnimations[Model][Track]
- end
- local Animation = {}
- ModelAnimations[Model][Track] = Animation
- if not hasloaded[Track] then
- Track.Properties.Priority = Enum.AnimationPriority[Track.Properties.Priority]
- end
- local set_model = Ver(Model)
- local largest_time = 0
- if not GlobalPlaying[Model][Animation] then
- GlobalPlaying[Model][Animation] = {}
- end
- if notmodel then
- local function new_joint(Obj)
- if Obj:IsA("Weld") then
- local P0 = Obj.Part0
- local P1 = Obj.Part1
- if not P0 or not P1 then return end
- local jd = JointData[Obj.Name]
- if jd then
- Obj.C0 = jd
- JointC0[Obj] = jd
- else
- JointC0[Obj] = Obj.C0
- end
- local T = ModelAnimations[Model].Joints[P0.Name]
- if not T then
- T = {}
- ModelAnimations[Model].Joints[P0.Name] = T
- end
- if not T[P1.Name] then
- T[P1.Name] = Obj
- end
- end
- end
- for _,v in ipairs(Model:GetDescendants()) do
- new_joint(v)
- end
- Model.DescendantAdded:Connect(new_joint)
- end
- local track_data = Animator.Preload(Track)
- if track_data then
- local Keyframes,jdata,lt = unpack(track_data)
- Animation.Keyframes = Keyframes
- GlobalPlaying[Model][Animation] = jdata
- largest_time = lt
- else
- error('No track preloaded.')
- end
- Animation.TimePosition = 0
- Animation.TimeLength = largest_time
- Animation.Track = Track
- Animation.Model = Model
- Animation.TimeScale = 1
- Animation.GeneralWeight = 1
- Animation.Play = Play
- Animation.Stop = Stop
- Animation.Resume = Resume
- Animation.Pause = Pause
- Animation.SetTime = SetTime
- Animation.AdjustSpeed = AdjustSpeed
- Animation.Looped = Track.Properties.Looping or false
- Animation.Speed = 1
- Animation.FadeIn = 0
- Animation.LastPlayed = 0
- Animation.i = 0
- Animation.Playing = false
- Animation.fired = {}
- Animation.RecoverFade = {}
- if Track.Properties.Priority == Enum.AnimationPriority.Idle then
- Animation.Priority = 1
- elseif Track.Properties.Priority == Enum.AnimationPriority.Movement then
- Animation.Priority = 2
- elseif Track.Properties.Priority == Enum.AnimationPriority.Action then
- Animation.Priority = 3
- else--if Track.Properties.Priority == Enum.AnimationPriority.Core then
- Animation.Priority = 0
- end
- Animation.StartInternal = 0
- Animation.PauseInternal = 0
- Animation.GetTimeOfKeyframe = function(name)
- for Time,v in ipairs(Animation.Keyframes) do
- if v.Name == name then
- return Time
- end
- end
- end
- hasloaded[Track] = true
- return Animation
- end
- local CF = CFrame.new()
- local function GetPose(TimeSince, Poses, Joint, Animation)
- for i = 1,#Poses do
- local Keyframe = Poses[i]
- local NextKeyframe = Poses[i+1]
- local Time = Keyframe.Time
- --local JT = Joint.Transform
- if TimeSince >= Time then
- if not Animation.fired[Keyframe.Name .. Time] and Keyframe.Name ~= 'Keyframe' then
- Animation.fired[Keyframe.Name .. Time] = 1
- if Keyframe.Marker then -- keymarker
- Animation.MarkerReachedEvent:Fire(Keyframe.Name)
- else -- keyframe
- Animation.KeyframeReachedEvent:Fire(Keyframe.Name)
- end
- end
- end
- if (TimeSince >= Time) or Poses[1].Time > TimeSince then
- if NextKeyframe then
- local NextTime = NextKeyframe.Time
- if TimeSince < NextTime then
- if Keyframe.Marker then
- return {nil, nil, Keyframe.Name, Time, Keyframe.Marker}
- end
- local Info1 = Keyframe.Info
- local Info2 = NextKeyframe.Info
- local Alpha = (TimeSince - Time) / (NextTime - Time)
- local CFA = CF:Lerp(Info1.CFrame, Info1.Weight)
- local CFB = CF:Lerp(Info2.CFrame, Info2.Weight)
- local Pose
- if Info2.EasingStyle == 'Constant' then
- Pose = CFA
- else
- Pose = CFA:Lerp(CFB, TS:GetValue(Alpha, Enum.EasingStyle[Info2.EasingStyle], Enum.EasingDirection[Info2.EasingDirection]))
- end
- return {Joint, Pose, Keyframe.Name, Time}
- end
- else
- if Keyframe.Marker then
- return {nil, nil, Keyframe.Name, Time, Keyframe.Marker}
- end
- return {Joint, Keyframe.Info.CFrame, Keyframe.Name, Time}
- end
- end
- end
- end
- local total_playing = 0
- local function UpdatePlaying()
- local tp = 0
- for Model, Animations in next, Playing do
- for Animation,_ in next, Animations do
- if not Animation.Playing then
- continue
- end
- if not Model or not Model.Parent then
- Playing[Model] = nil
- Animation.FadeIn = nil
- Animation.fired = {}
- Animation.Playing = false
- continue
- end
- local TimeSince = Animation.StartInternal
- TimeSince = os.clock() - ((os.clock() - TimeSince) * Animation.Speed)
- TimeSince = os.clock() - TimeSince
- --local TimeSince = os.clock() - Animation.StartInternal
- --TimeSince = TimeSince * Animation.Speed
- if Animation.FadeIn then
- Animation.OFadeIn = Animation.FadeIn
- end
- local Length = Animation.TimeLength
- if TimeSince > Length then
- Animation.FadeIn = nil
- Animation.fired = {}
- if Animation.Looped then
- Animation.LoopedEvent:Fire()
- if 0 >= Length then
- TimeSince = 0
- else
- TimeSince = TimeSince%Length
- end
- --Animation.StartInternal += Length-TimeSince
- else
- Animation.TimePosition = 0
- Playing[Model][Animation] = nil
- Animation.Playing = false
- Animation.StopEvent:Fire()
- continue
- end
- end
- local Keyframes = Animation.Keyframes
- if Keyframes then else continue end
- tp += 1
- local ToAnimate = {}
- local StartFade = nil
- for Joint, Poses in pairs(Keyframes) do
- local strjoint = Joint
- local jd = string.split(strjoint,'KEyjtsep')
- local Joint
- if jd[1] and jd[2] then
- Joint = ModelAnimations[Model].Joints[jd[1]]
- if not Joint then
- continue
- end
- Joint = Joint[jd[2]]
- if not Joint then
- continue
- end
- end
- if not Poses[1] or not Poses[1].Marker then
- local f,fade
- for i,using in pairs(GlobalPlaying[Model]) do
- if i ~= Animation then else
- continue
- end
- if i.Playing then else
- continue
- end
- if using[strjoint] then else
- continue
- end
- if i.Priority > Animation.Priority or (i.Priority == Animation.Priority and i.LastPlayed > Animation.LastPlayed) then else
- continue
- end
- f = true
- end
- if f then
- Animation.RecoverFade[Joint.Name] = os.clock()
- continue
- end
- end
- if Poses[1] and Poses[1].Time > TimeSince then
- --StartFade = Poses[1].Time * Animation.Speed
- end
- ToAnimate[#ToAnimate+1] = GetPose(TimeSince, Poses, Joint, Animation)
- end
- for i = 1,#ToAnimate do
- local Pose = ToAnimate[i]
- if not Pose[5] then
- local TCF = Pose[2]
- local FadeIn = Animation.FadeIn
- local RF = Animation.RecoverFade[Pose[1].Name]
- local TimeSince = TimeSince
- if RF then
- TimeSince = os.clock()-RF
- if TimeSince >= Length then
- Animation.RecoverFade[Pose[1].Name] = nil
- else
- FadeIn = Animation.OFadeIn
- end
- end
- TCF = JointC0[Pose[1]] * TCF
- if StartFade then
- TCF = Pose[1].C0:Lerp(TCF, TimeSince / StartFade)
- elseif FadeIn and TimeSince < FadeIn then
- TCF = Pose[1].C0:Lerp(TCF, TimeSince / FadeIn)
- end
- Pose[1].C0 = TCF
- end
- end
- Animation.TimePosition = TimeSince
- end
- end
- total_playing = tp
- end
- function Animator.GetPlaying()
- return total_playing
- end
- local con
- if game:GetService("RunService"):IsClient() then
- con = game:GetService("RunService").RenderStepped:Connect(UpdatePlaying)
- else
- con = game:GetService("RunService").Stepped:Connect(UpdatePlaying)
- end
- return Animator,con
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement