SHOW:
|
|
- or go back to the newest paste.
1 | function waitForChild(parent, childName) | |
2 | local child = parent:findFirstChild(childName) | |
3 | if child then return child end | |
4 | while true do | |
5 | child = parent.ChildAdded:wait() | |
6 | if child.Name==childName then return child end | |
7 | end | |
8 | end | |
9 | ||
10 | local Figure = script.Parent | |
11 | local Torso = waitForChild(Figure, "Torso") | |
12 | local RightShoulder = waitForChild(Torso, "Right Shoulder") | |
13 | local LeftShoulder = waitForChild(Torso, "Left Shoulder") | |
14 | local RightHip = waitForChild(Torso, "Right Hip") | |
15 | local LeftHip = waitForChild(Torso, "Left Hip") | |
16 | local Neck = waitForChild(Torso, "Neck") | |
17 | local Humanoid = waitForChild(Figure, "Humanoid") | |
18 | local pose = "Standing" | |
19 | ||
20 | local currentAnim = "" | |
21 | local currentAnimInstance = nil | |
22 | local currentAnimTrack = nil | |
23 | local currentAnimKeyframeHandler = nil | |
24 | local currentAnimSpeed = 1.0 | |
25 | local animTable = {} | |
26 | local animNames = { | |
27 | idle = { | |
28 | { id = "http://www.roblox.com/asset/?id=180435571", weight = 9 }, | |
29 | { id = "http://www.roblox.com/asset/?id=180435792", weight = 1 } | |
30 | }, | |
31 | walk = { | |
32 | - | { id = "http://www.roblox.com/asset/?id=180426354", weight = 10 } |
32 | + | { id = "http://www.roblox.com/asset/?id=1546679674", weight = 10 } |
33 | }, | |
34 | run = { | |
35 | { id = "run.xml", weight = 10 } | |
36 | }, | |
37 | jump = { | |
38 | { id = "http://www.roblox.com/asset/?id=125750702", weight = 10 } | |
39 | }, | |
40 | fall = { | |
41 | { id = "http://www.roblox.com/asset/?id=180436148", weight = 10 } | |
42 | }, | |
43 | climb = { | |
44 | { id = "http://www.roblox.com/asset/?id=180436334", weight = 10 } | |
45 | }, | |
46 | sit = { | |
47 | { id = "http://www.roblox.com/asset/?id=178130996", weight = 10 } | |
48 | }, | |
49 | toolnone = { | |
50 | { id = "http://www.roblox.com/asset/?id=182393478", weight = 10 } | |
51 | }, | |
52 | toolslash = { | |
53 | { id = "http://www.roblox.com/asset/?id=129967390", weight = 10 } | |
54 | -- { id = "slash.xml", weight = 10 } | |
55 | }, | |
56 | toollunge = { | |
57 | { id = "http://www.roblox.com/asset/?id=129967478", weight = 10 } | |
58 | }, | |
59 | wave = { | |
60 | { id = "http://www.roblox.com/asset/?id=128777973", weight = 10 } | |
61 | }, | |
62 | point = { | |
63 | { id = "http://www.roblox.com/asset/?id=128853357", weight = 10 } | |
64 | }, | |
65 | dance1 = { | |
66 | { id = "http://www.roblox.com/asset/?id=182435998", weight = 10 }, | |
67 | { id = "http://www.roblox.com/asset/?id=182491037", weight = 10 }, | |
68 | { id = "http://www.roblox.com/asset/?id=182491065", weight = 10 } | |
69 | }, | |
70 | dance2 = { | |
71 | { id = "http://www.roblox.com/asset/?id=182436842", weight = 10 }, | |
72 | { id = "http://www.roblox.com/asset/?id=182491248", weight = 10 }, | |
73 | { id = "http://www.roblox.com/asset/?id=182491277", weight = 10 } | |
74 | }, | |
75 | dance3 = { | |
76 | { id = "http://www.roblox.com/asset/?id=182436935", weight = 10 }, | |
77 | { id = "http://www.roblox.com/asset/?id=182491368", weight = 10 }, | |
78 | { id = "http://www.roblox.com/asset/?id=182491423", weight = 10 } | |
79 | }, | |
80 | laugh = { | |
81 | { id = "http://www.roblox.com/asset/?id=129423131", weight = 10 } | |
82 | }, | |
83 | cheer = { | |
84 | { id = "http://www.roblox.com/asset/?id=129423030", weight = 10 } | |
85 | }, | |
86 | } | |
87 | local dances = {"dance1", "dance2", "dance3"} | |
88 | ||
89 | -- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote | |
90 | local emoteNames = { wave = false, point = false, dance1 = true, dance2 = true, dance3 = true, laugh = false, cheer = false} | |
91 | ||
92 | function configureAnimationSet(name, fileList) | |
93 | if (animTable[name] ~= nil) then | |
94 | for _, connection in pairs(animTable[name].connections) do | |
95 | connection:disconnect() | |
96 | end | |
97 | end | |
98 | animTable[name] = {} | |
99 | animTable[name].count = 0 | |
100 | animTable[name].totalWeight = 0 | |
101 | animTable[name].connections = {} | |
102 | ||
103 | -- check for config values | |
104 | local config = script:FindFirstChild(name) | |
105 | if (config ~= nil) then | |
106 | -- print("Loading anims " .. name) | |
107 | table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end)) | |
108 | table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end)) | |
109 | local idx = 1 | |
110 | for _, childPart in pairs(config:GetChildren()) do | |
111 | if (childPart:IsA("Animation")) then | |
112 | table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end)) | |
113 | animTable[name][idx] = {} | |
114 | animTable[name][idx].anim = childPart | |
115 | local weightObject = childPart:FindFirstChild("Weight") | |
116 | if (weightObject == nil) then | |
117 | animTable[name][idx].weight = 1 | |
118 | else | |
119 | animTable[name][idx].weight = weightObject.Value | |
120 | end | |
121 | animTable[name].count = animTable[name].count + 1 | |
122 | animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight | |
123 | -- print(name .. " [" .. idx .. "] " .. animTable[name][idx].anim.AnimationId .. " (" .. animTable[name][idx].weight .. ")") | |
124 | idx = idx + 1 | |
125 | end | |
126 | end | |
127 | end | |
128 | ||
129 | -- fallback to defaults | |
130 | if (animTable[name].count <= 0) then | |
131 | for idx, anim in pairs(fileList) do | |
132 | animTable[name][idx] = {} | |
133 | animTable[name][idx].anim = Instance.new("Animation") | |
134 | animTable[name][idx].anim.Name = name | |
135 | animTable[name][idx].anim.AnimationId = anim.id | |
136 | animTable[name][idx].weight = anim.weight | |
137 | animTable[name].count = animTable[name].count + 1 | |
138 | animTable[name].totalWeight = animTable[name].totalWeight + anim.weight | |
139 | -- print(name .. " [" .. idx .. "] " .. anim.id .. " (" .. anim.weight .. ")") | |
140 | end | |
141 | end | |
142 | end | |
143 | ||
144 | -- Setup animation objects | |
145 | function scriptChildModified(child) | |
146 | local fileList = animNames[child.Name] | |
147 | if (fileList ~= nil) then | |
148 | configureAnimationSet(child.Name, fileList) | |
149 | end | |
150 | end | |
151 | ||
152 | script.ChildAdded:connect(scriptChildModified) | |
153 | script.ChildRemoved:connect(scriptChildModified) | |
154 | ||
155 | ||
156 | for name, fileList in pairs(animNames) do | |
157 | configureAnimationSet(name, fileList) | |
158 | end | |
159 | ||
160 | -- ANIMATION | |
161 | ||
162 | -- declarations | |
163 | local toolAnim = "None" | |
164 | local toolAnimTime = 0 | |
165 | ||
166 | local jumpAnimTime = 0 | |
167 | local jumpAnimDuration = 0.3 | |
168 | ||
169 | local toolTransitionTime = 0.1 | |
170 | local fallTransitionTime = 0.3 | |
171 | local jumpMaxLimbVelocity = 0.75 | |
172 | ||
173 | -- functions | |
174 | ||
175 | function stopAllAnimations() | |
176 | local oldAnim = currentAnim | |
177 | ||
178 | -- return to idle if finishing an emote | |
179 | if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false) then | |
180 | oldAnim = "idle" | |
181 | end | |
182 | ||
183 | currentAnim = "" | |
184 | currentAnimInstance = nil | |
185 | if (currentAnimKeyframeHandler ~= nil) then | |
186 | currentAnimKeyframeHandler:disconnect() | |
187 | end | |
188 | ||
189 | if (currentAnimTrack ~= nil) then | |
190 | currentAnimTrack:Stop() | |
191 | currentAnimTrack:Destroy() | |
192 | currentAnimTrack = nil | |
193 | end | |
194 | return oldAnim | |
195 | end | |
196 | ||
197 | function setAnimationSpeed(speed) | |
198 | if speed ~= currentAnimSpeed then | |
199 | currentAnimSpeed = speed | |
200 | currentAnimTrack:AdjustSpeed(currentAnimSpeed) | |
201 | end | |
202 | end | |
203 | ||
204 | function keyFrameReachedFunc(frameName) | |
205 | if (frameName == "End") then | |
206 | ||
207 | local repeatAnim = currentAnim | |
208 | -- return to idle if finishing an emote | |
209 | if (emoteNames[repeatAnim] ~= nil and emoteNames[repeatAnim] == false) then | |
210 | repeatAnim = "idle" | |
211 | end | |
212 | ||
213 | local animSpeed = currentAnimSpeed | |
214 | playAnimation(repeatAnim, 0.0, Humanoid) | |
215 | setAnimationSpeed(animSpeed) | |
216 | end | |
217 | end | |
218 | ||
219 | -- Preload animations | |
220 | function playAnimation(animName, transitionTime, humanoid) | |
221 | ||
222 | local roll = math.random(1, animTable[animName].totalWeight) | |
223 | local origRoll = roll | |
224 | local idx = 1 | |
225 | while (roll > animTable[animName][idx].weight) do | |
226 | roll = roll - animTable[animName][idx].weight | |
227 | idx = idx + 1 | |
228 | end | |
229 | -- print(animName .. " " .. idx .. " [" .. origRoll .. "]") | |
230 | local anim = animTable[animName][idx].anim | |
231 | ||
232 | -- switch animation | |
233 | if (anim ~= currentAnimInstance) then | |
234 | ||
235 | if (currentAnimTrack ~= nil) then | |
236 | currentAnimTrack:Stop(transitionTime) | |
237 | currentAnimTrack:Destroy() | |
238 | end | |
239 | ||
240 | currentAnimSpeed = 1.0 | |
241 | ||
242 | -- load it to the humanoid; get AnimationTrack | |
243 | currentAnimTrack = humanoid:LoadAnimation(anim) | |
244 | ||
245 | -- play the animation | |
246 | currentAnimTrack:Play(transitionTime) | |
247 | currentAnim = animName | |
248 | currentAnimInstance = anim | |
249 | ||
250 | -- set up keyframe name triggers | |
251 | if (currentAnimKeyframeHandler ~= nil) then | |
252 | currentAnimKeyframeHandler:disconnect() | |
253 | end | |
254 | currentAnimKeyframeHandler = currentAnimTrack.KeyframeReached:connect(keyFrameReachedFunc) | |
255 | ||
256 | end | |
257 | ||
258 | end | |
259 | ||
260 | ------------------------------------------------------------------------------------------- | |
261 | ------------------------------------------------------------------------------------------- | |
262 | ||
263 | local toolAnimName = "" | |
264 | local toolAnimTrack = nil | |
265 | local toolAnimInstance = nil | |
266 | local currentToolAnimKeyframeHandler = nil | |
267 | ||
268 | function toolKeyFrameReachedFunc(frameName) | |
269 | if (frameName == "End") then | |
270 | -- print("Keyframe : ".. frameName) | |
271 | playToolAnimation(toolAnimName, 0.0, Humanoid) | |
272 | end | |
273 | end | |
274 | ||
275 | ||
276 | function playToolAnimation(animName, transitionTime, humanoid) | |
277 | ||
278 | local roll = math.random(1, animTable[animName].totalWeight) | |
279 | local origRoll = roll | |
280 | local idx = 1 | |
281 | while (roll > animTable[animName][idx].weight) do | |
282 | roll = roll - animTable[animName][idx].weight | |
283 | idx = idx + 1 | |
284 | end | |
285 | -- print(animName .. " * " .. idx .. " [" .. origRoll .. "]") | |
286 | local anim = animTable[animName][idx].anim | |
287 | ||
288 | if (toolAnimInstance ~= anim) then | |
289 | ||
290 | if (toolAnimTrack ~= nil) then | |
291 | toolAnimTrack:Stop() | |
292 | toolAnimTrack:Destroy() | |
293 | transitionTime = 0 | |
294 | end | |
295 | ||
296 | -- load it to the humanoid; get AnimationTrack | |
297 | toolAnimTrack = humanoid:LoadAnimation(anim) | |
298 | ||
299 | -- play the animation | |
300 | toolAnimTrack:Play(transitionTime) | |
301 | toolAnimName = animName | |
302 | toolAnimInstance = anim | |
303 | ||
304 | currentToolAnimKeyframeHandler = toolAnimTrack.KeyframeReached:connect(toolKeyFrameReachedFunc) | |
305 | end | |
306 | end | |
307 | ||
308 | function stopToolAnimations() | |
309 | local oldAnim = toolAnimName | |
310 | ||
311 | if (currentToolAnimKeyframeHandler ~= nil) then | |
312 | currentToolAnimKeyframeHandler:disconnect() | |
313 | end | |
314 | ||
315 | toolAnimName = "" | |
316 | toolAnimInstance = nil | |
317 | if (toolAnimTrack ~= nil) then | |
318 | toolAnimTrack:Stop() | |
319 | toolAnimTrack:Destroy() | |
320 | toolAnimTrack = nil | |
321 | end | |
322 | ||
323 | ||
324 | return oldAnim | |
325 | end | |
326 | ||
327 | ------------------------------------------------------------------------------------------- | |
328 | ------------------------------------------------------------------------------------------- | |
329 | ||
330 | ||
331 | function onRunning(speed) | |
332 | if speed>0.01 then | |
333 | playAnimation("walk", 0.1, Humanoid) | |
334 | - | if currentAnimInstance and currentAnimInstance.AnimationId == "http://www.roblox.com/asset/?id=180426354" then |
334 | + | if currentAnimInstance and currentAnimInstance.AnimationId == "http://www.roblox.com/asset/?id=1546679674" then |
335 | setAnimationSpeed(speed / 14.5) | |
336 | end | |
337 | pose = "Running" | |
338 | else | |
339 | if emoteNames[currentAnim] == nil then | |
340 | playAnimation("idle", 0.1, Humanoid) | |
341 | pose = "Standing" | |
342 | end | |
343 | end | |
344 | end | |
345 | ||
346 | function onDied() | |
347 | pose = "Dead" | |
348 | end | |
349 | ||
350 | function onJumping() | |
351 | playAnimation("jump", 0.1, Humanoid) | |
352 | jumpAnimTime = jumpAnimDuration | |
353 | pose = "Jumping" | |
354 | end | |
355 | ||
356 | function onClimbing(speed) | |
357 | playAnimation("climb", 0.1, Humanoid) | |
358 | setAnimationSpeed(speed / 12.0) | |
359 | pose = "Climbing" | |
360 | end | |
361 | ||
362 | function onGettingUp() | |
363 | pose = "GettingUp" | |
364 | end | |
365 | ||
366 | function onFreeFall() | |
367 | if (jumpAnimTime <= 0) then | |
368 | playAnimation("fall", fallTransitionTime, Humanoid) | |
369 | end | |
370 | pose = "FreeFall" | |
371 | end | |
372 | ||
373 | function onFallingDown() | |
374 | pose = "FallingDown" | |
375 | end | |
376 | ||
377 | function onSeated() | |
378 | pose = "Seated" | |
379 | end | |
380 | ||
381 | function onPlatformStanding() | |
382 | pose = "PlatformStanding" | |
383 | end | |
384 | ||
385 | function onSwimming(speed) | |
386 | if speed>0 then | |
387 | pose = "Running" | |
388 | else | |
389 | pose = "Standing" | |
390 | end | |
391 | end | |
392 | ||
393 | function getTool() | |
394 | for _, kid in ipairs(Figure:GetChildren()) do | |
395 | if kid.className == "Tool" then return kid end | |
396 | end | |
397 | return nil | |
398 | end | |
399 | ||
400 | function getToolAnim(tool) | |
401 | for _, c in ipairs(tool:GetChildren()) do | |
402 | if c.Name == "toolanim" and c.className == "StringValue" then | |
403 | return c | |
404 | end | |
405 | end | |
406 | return nil | |
407 | end | |
408 | ||
409 | function animateTool() | |
410 | ||
411 | if (toolAnim == "None") then | |
412 | playToolAnimation("toolnone", toolTransitionTime, Humanoid) | |
413 | return | |
414 | end | |
415 | ||
416 | if (toolAnim == "Slash") then | |
417 | playToolAnimation("toolslash", 0, Humanoid) | |
418 | return | |
419 | end | |
420 | ||
421 | if (toolAnim == "Lunge") then | |
422 | playToolAnimation("toollunge", 0, Humanoid) | |
423 | return | |
424 | end | |
425 | end | |
426 | ||
427 | function moveSit() | |
428 | RightShoulder.MaxVelocity = 0.15 | |
429 | LeftShoulder.MaxVelocity = 0.15 | |
430 | RightShoulder:SetDesiredAngle(3.14 /2) | |
431 | LeftShoulder:SetDesiredAngle(-3.14 /2) | |
432 | RightHip:SetDesiredAngle(3.14 /2) | |
433 | LeftHip:SetDesiredAngle(-3.14 /2) | |
434 | end | |
435 | ||
436 | local lastTick = 0 | |
437 | ||
438 | function move(time) | |
439 | local amplitude = 1 | |
440 | local frequency = 1 | |
441 | local deltaTime = time - lastTick | |
442 | lastTick = time | |
443 | ||
444 | local climbFudge = 0 | |
445 | local setAngles = false | |
446 | ||
447 | if (jumpAnimTime > 0) then | |
448 | jumpAnimTime = jumpAnimTime - deltaTime | |
449 | end | |
450 | ||
451 | if (pose == "FreeFall" and jumpAnimTime <= 0) then | |
452 | playAnimation("fall", fallTransitionTime, Humanoid) | |
453 | elseif (pose == "Seated") then | |
454 | playAnimation("sit", 0.5, Humanoid) | |
455 | return | |
456 | elseif (pose == "Running") then | |
457 | playAnimation("walk", 0.1, Humanoid) | |
458 | elseif (pose == "Dead" or pose == "GettingUp" or pose == "FallingDown" or pose == "Seated" or pose == "PlatformStanding") then | |
459 | -- print("Wha " .. pose) | |
460 | stopAllAnimations() | |
461 | amplitude = 0.1 | |
462 | frequency = 1 | |
463 | setAngles = true | |
464 | end | |
465 | ||
466 | if (setAngles) then | |
467 | desiredAngle = amplitude * math.sin(time * frequency) | |
468 | ||
469 | RightShoulder:SetDesiredAngle(desiredAngle + climbFudge) | |
470 | LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge) | |
471 | RightHip:SetDesiredAngle(-desiredAngle) | |
472 | LeftHip:SetDesiredAngle(-desiredAngle) | |
473 | end | |
474 | ||
475 | -- Tool Animation handling | |
476 | local tool = getTool() | |
477 | if tool and tool:FindFirstChild("Handle") then | |
478 | ||
479 | animStringValueObject = getToolAnim(tool) | |
480 | ||
481 | if animStringValueObject then | |
482 | toolAnim = animStringValueObject.Value | |
483 | -- message recieved, delete StringValue | |
484 | animStringValueObject.Parent = nil | |
485 | toolAnimTime = time + .3 | |
486 | end | |
487 | ||
488 | if time > toolAnimTime then | |
489 | toolAnimTime = 0 | |
490 | toolAnim = "None" | |
491 | end | |
492 | ||
493 | animateTool() | |
494 | else | |
495 | stopToolAnimations() | |
496 | toolAnim = "None" | |
497 | toolAnimInstance = nil | |
498 | toolAnimTime = 0 | |
499 | end | |
500 | end | |
501 | ||
502 | -- connect events | |
503 | Humanoid.Died:connect(onDied) | |
504 | Humanoid.Running:connect(onRunning) | |
505 | Humanoid.Jumping:connect(onJumping) | |
506 | Humanoid.Climbing:connect(onClimbing) | |
507 | Humanoid.GettingUp:connect(onGettingUp) | |
508 | Humanoid.FreeFalling:connect(onFreeFall) | |
509 | Humanoid.FallingDown:connect(onFallingDown) | |
510 | Humanoid.Seated:connect(onSeated) | |
511 | Humanoid.PlatformStanding:connect(onPlatformStanding) | |
512 | Humanoid.Swimming:connect(onSwimming) | |
513 | ||
514 | -- setup emote chat hook | |
515 | game.Players.LocalPlayer.Chatted:connect(function(msg) | |
516 | local emote = "" | |
517 | if msg == "/e dance" then | |
518 | emote = dances[math.random(1, #dances)] | |
519 | elseif (string.sub(msg, 1, 3) == "/e ") then | |
520 | emote = string.sub(msg, 4) | |
521 | elseif (string.sub(msg, 1, 7) == "/emote ") then | |
522 | emote = string.sub(msg, 8) | |
523 | end | |
524 | ||
525 | if (pose == "Standing" and emoteNames[emote] ~= nil) then | |
526 | playAnimation(emote, 0.1, Humanoid) | |
527 | end | |
528 | ||
529 | end) | |
530 | ||
531 | ||
532 | -- main program | |
533 | ||
534 | local runService = game:service("RunService"); | |
535 | ||
536 | -- initialize to idle | |
537 | playAnimation("idle", 0.1, Humanoid) | |
538 | pose = "Standing" | |
539 | ||
540 | while Figure.Parent~=nil do | |
541 | local _, time = wait(0.1) | |
542 | move(time) | |
543 | end |