kyo_kyo

custom tweenservice

May 7th, 2025
19
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.30 KB | None | 0 0
  1. local module = {}
  2.  
  3. functions = {
  4. Linear = {
  5. In = function(t) return t end,
  6. Out = function(t) return t end,
  7. InOut = function(t) return t end
  8. },
  9. Sine = {
  10. In = function(t) return 1 - math.cos((t * math.pi) / 2) end,
  11. Out = function(t) return math.sin((t * math.pi) / 2) end,
  12. InOut = function(t) return -(math.cos(math.pi * t) - 1) / 2 end
  13. },
  14. Quad = {
  15. In = function(t) return t * t end,
  16. Out = function(t) return 1 - (1 - t) * (1 - t) end,
  17. InOut = function(t) return t < 0.5 and 2 * t * t or 1 - 2 * (1 - t) * (1 - t) end
  18. },
  19. Cubic = {
  20. In = function(t) return t * t * t end,
  21. Out = function(t) return 1 - (1 - t) * (1 - t) * (1 - t) end,
  22. InOut = function(t) return t < 0.5 and 4 * t * t * t or 1 - 4 * (1 - t) * (1 - t) * (1 - t) end
  23. },
  24. Quart = {
  25. In = function(t) return t * t * t * t end,
  26. Out = function(t) return 1 - (1 - t) * (1 - t) * (1 - t) * (1 - t) end,
  27. InOut = function(t) return t < 0.5 and 8 * t * t * t * t or 1 - 8 * (1 - t) * (1 - t) * (1 - t) * (1 - t) end
  28. },
  29. Quint = {
  30. In = function(t) return t * t * t * t * t end,
  31. Out = function(t) return 1 - (1 - t) * (1 - t) * (1 - t) * (1 - t) * (1 - t) end,
  32. InOut = function(t) return t < 0.5 and 16 * t * t * t * t * t or 1 - 16 * (1 - t) * (1 - t) * (1 - t) * (1 - t) * (1 - t) end
  33. },
  34. Exponential = {
  35. In = function(t) return t == 0 and 0 or 2^(10 * (t - 1)) end,
  36. Out = function(t) return t == 1 and 1 or 1 - 2^(-10 * t) end,
  37. InOut = function(t)
  38. if t == 0 then return 0 end
  39. if t == 1 then return 1 end
  40. return t < 0.5 and 2^(20 * t - 10) / 2 or (2 - 2^(-20 * t + 10)) / 2
  41. end
  42. },
  43. Circular = {
  44. In = function(t) return 1 - math.sqrt(1 - t * t) end,
  45. Out = function(t) return math.sqrt(1 - (t - 1) * (t - 1)) end,
  46. InOut = function(t)
  47. return t < 0.5 and (1 - math.sqrt(1 - 4 * t * t)) / 2 or (math.sqrt(1 - (-2 * t + 2)^2) + 1) / 2
  48. end
  49. },
  50. Elastic = {
  51. In = function(t)
  52. if t == 0 then return 0 end
  53. if t == 1 then return 1 end
  54. return -2^(10 * t - 10) * math.sin((t * 10 - 10.75) * (2 * math.pi) / 3)
  55. end,
  56. Out = function(t)
  57. if t == 0 then return 0 end
  58. if t == 1 then return 1 end
  59. return 2^(-10 * t) * math.sin((t * 10 - 0.75) * (2 * math.pi) / 3) + 1
  60. end,
  61. InOut = function(t)
  62. if t == 0 then return 0 end
  63. if t == 1 then return 1 end
  64. t = t * 2
  65. if t < 1 then return -0.5 * 2^(10 * t - 10) * math.sin((t * 10 - 10.75) * 2 * math.pi / 3) end
  66. return 0.5 * 2^(-10 * (t - 1)) * math.sin((t * 10 - 10.75) * 2 * math.pi / 3) + 1
  67. end
  68. },
  69. Back = {
  70. In = function(t)
  71. local s = 1.70158
  72. return t * t * ((s + 1) * t - s)
  73. end,
  74. Out = function(t)
  75. local s = 1.70158
  76. t = t - 1
  77. return t * t * ((s + 1) * t + s) + 1
  78. end,
  79. InOut = function(t)
  80. local s = 1.70158 * 1.525
  81. t = t * 2
  82. if t < 1 then return 0.5 * (t * t * ((s + 1) * t - s)) end
  83. t = t - 2
  84. return 0.5 * (t * t * ((s + 1) * t + s) + 2)
  85. end
  86. },
  87. Bounce = {
  88. Out = function(t)
  89. if t < 4/11 then
  90. return (121 * t * t) / 16
  91. elseif t < 8/11 then
  92. return (363/40 * t * t) - (99/10 * t) + 17/5
  93. elseif t < 9/10 then
  94. return (4356/361 * t * t) - (35442/1805 * t) + 16061/1805
  95. else
  96. return (54/5 * t * t) - (513/25 * t) + 268/25
  97. end
  98. end,
  99. In = function(t)
  100. return 1 - functions.Bounce.Out(1 - t)
  101. end,
  102. InOut = function(t)
  103. if t < 0.5 then
  104. return (1 - functions.Bounce.Out(1 - 2 * t)) / 2
  105. else
  106. return (1 + functions.Bounce.Out(2 * t - 1)) / 2
  107. end
  108. end
  109. }
  110. }
  111.  
  112. local runs = game:GetService("RunService")
  113.  
  114. function module.tween(obj, prop, opts)
  115. opts = opts or {}
  116. local duration = opts.duration or 1
  117. local style = opts.style or "Linear"
  118. local direction = opts.direction or "In"
  119. local loop = opts.loop or false
  120.  
  121. if not functions[style] then
  122. style = "Linear"
  123. warn("Invalid easing style, defaulting to Linear")
  124. end
  125.  
  126. if not functions[style][direction] then
  127. direction = "In"
  128. warn("Invalid easing direction, defaulting to In")
  129. end
  130.  
  131. local ease = functions[style][direction]
  132. local init = {}
  133. local target = {}
  134.  
  135. for p, v in pairs(prop) do
  136. init[p] = obj[p]
  137. target[p] = v
  138. end
  139.  
  140. local controller = {
  141. Pause = false,
  142. SpeedMultiplier = 1,
  143. Completed = false,
  144. }
  145.  
  146. controller.Cancel = function()
  147. controller.Completed = true
  148. end
  149.  
  150. local function do_tween(from, to)
  151. local start = os.clock()
  152. local last = start
  153. local scaled = 0
  154. local paused = false
  155.  
  156. while not controller.Completed do
  157. while controller.Pause do
  158. task.wait(0.05)
  159. local now = os.clock()
  160. last = now
  161. end
  162.  
  163. local time_scale = workspace:GetAttribute("TimeScale") or 1
  164. if runs:IsStudio() and time_scale == 0 then
  165. time_scale = 1
  166. end
  167.  
  168. if time_scale == 0.001 then
  169. if not paused then
  170. paused = true
  171. last = os.clock()
  172. end
  173. task.wait(0.05)
  174. else
  175. if paused then
  176. paused = false
  177. last = os.clock()
  178. end
  179.  
  180. local combined = controller.SpeedMultiplier * math.max(0.001, time_scale)
  181.  
  182. local current = os.clock()
  183. local delta = current - last
  184. last = current
  185. scaled += delta * combined
  186.  
  187. local prog = ease(math.clamp(scaled / duration, 0, 1))
  188.  
  189. for p, i in pairs(from) do
  190. local tv = to[p]
  191. local cv
  192.  
  193. if typeof(tv) == "number" then
  194. cv = i + (tv - i) * prog
  195. elseif typeof(tv) == "Vector3" then
  196. cv = i:Lerp(tv, prog)
  197. elseif typeof(tv) == "Color3" then
  198. cv = i:Lerp(tv, prog)
  199. elseif typeof(tv) == "CFrame" then
  200. local pos = i.Position:Lerp(tv.Position, prog)
  201. local rot = i.Rotation:Lerp(tv.Rotation, prog)
  202. cv = CFrame.new(pos) * rot
  203. end
  204.  
  205. obj[p] = cv
  206. end
  207.  
  208. if scaled >= duration then
  209. break
  210. end
  211.  
  212. task.wait()
  213. end
  214. end
  215.  
  216. for p, tv in pairs(to) do
  217. obj[p] = tv
  218. end
  219. end
  220.  
  221. coroutine.wrap(function()
  222. while not controller.Completed do
  223. do_tween(init, target)
  224. if not loop or controller.Completed then break end
  225. do_tween(target, init)
  226. end
  227. controller.Completed = true
  228. end)()
  229.  
  230. return controller
  231. end
  232.  
  233. function module.wait(t)
  234. local e = 0
  235. while e < t do
  236. local timescale = workspace:GetAttribute("TimeScale") or 1
  237. timescale = math.clamp(timescale, 0.001, 10)
  238. local step = 0.05
  239. task.wait(step)
  240. e += step * timescale
  241. end
  242. end
  243.  
  244. return module
Advertisement
Add Comment
Please, Sign In to add comment