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