NotAshley
|
  |
| Joined: 16 Jan 2014 |
| Total Posts: 14257 |
|
|
| 25 Mar 2015 04:43 PM |
1) Set the Part1 property of all the character's Motor6Ds (excluding the neck) to nil, disconnecting each limb but keeping the Motor6Ds connected to the torso for use later.
2) Immediately create replacement welds with the same configuration as the Motor6Ds, with Part0 as the torso and Part1 as each limb. The neck Motor6D should remain normal because you can use it to animate without default animations getting in the way.
3) Adjust C0 and C1 of the new welds so that the limbs are in the correct position and rotate 1 stud up from the center, which is the center of the top half of the limb (not the very top, which is 1.5 studs up). This is especially important for the arms because each 90 degree turn will keep the arm level with the upper bit of the torso like it should be.
4) You should have variables for each limb (larm, rarm, lleg, rleg) and their welds (larmweld, rarmweld, llegweld, rlegweld).
5) A CFrame interpolation function will make the process of animating many times faster and more accurate. It's possible without one, but it involves best-guess math and lots of trial and error. A CFrame interpolation function allows you to get a new CFrame between 2 CFrames you specify based on a percentage (25% being a quarter of the way, 50% being halfway, etc). This percentage is usually a number between 0 and 1. A CFrame interpolation function differs from lerp() because it includes the full rotation matrix of a CFrame value. If you're feeling adventurous, you can try to write your own, but Stravant has an open source interpolation module that we can easily import into our script. You can find a standalone working version of the function here: http://pastebin.com/ZpBY48bi
6) When we want to start an animation, we need to create a pseudo animation track. I'll be explaining it in context with Stravant's function, but it will be similar no matter what interpolation function you're using. For each weld you want to animate, create an interpolator between that weld's current CFrame and the destination CFrame. Most of the time, the destination CFrame should be nothing more than the current CFrame * CFrame.Angles(). A very useful built-in function to help with this is math.rad(). It will take a number in degrees and convert it to radions. For example, CFrame.Angles(math.rad(90), math.rad(180), math.rad(45)) will set x to a 90 degree angle, y to a 180 degree angle, and z to a 45 degree angle.
7) To play your animation, make a for loop. The first number should be 1, and the second number should be the number of frames you want your animation to be. For example, "for i = 1, 20 do" would be a 20 frame animation. Inside the for loop, put a wait(). This will wait a very small amount of time between each frame, which we want. If you want to go even faster, you could use RenderStepped, but you might need to adjust the increment for the loop because it will speed it up a lot. Inside the for loop, use the interpolator function you set for each limb. For the 0 to 1 number, put i divided by the number of frames your animation is. This will essentially give you the percentage of how far your for loop has gone through from 0 to 1. In a loop from 1 to 20, using this algorithm, 10 give about 0.5, which is halfway.
8) Finally, we can use a sine/cosine algorithm to smooth the animation. This is something that not many people do. Consider the way sin/cos works. You have a number that gradually increases then decreases (think: sine wave) in a smoothed and non rigid manner. The CFrame interpolation function gives a new CFrame between 2 given CFrames based on a number from 0 to 1. If you use sin/cos to gradually increase a number from 0 to 1 (bottom of circle to top of circle) and feed that into the interpolation, the result is an animation with the start and end smoothed. The weapons in Strife by Fenrier use this technique. To save you the trouble, I've updated Stravant's interpolation function to automatically use this kind of smoothing when you animate it with loops. Here it is, along with instructions: http://pastebin.com/aGXsG8dn |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 04:48 PM |
Or just use the animation editor.
⬡ |
|
|
| Report Abuse |
|
|
NotAshley
|
  |
| Joined: 16 Jan 2014 |
| Total Posts: 14257 |
|
|
| 25 Mar 2015 04:50 PM |
"Or just use the animation editor."
Tell me when the animation editor can use the same kind of sine smoothing.
Also, I forgot to mention.
When you want to stop animating, simply destroy the welds and re-connect the Part1 of each Motor6D. |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 04:53 PM |
okay, tell me when you can animate welds without lag.
⬡ |
|
|
| Report Abuse |
|
|
NotAshley
|
  |
| Joined: 16 Jan 2014 |
| Total Posts: 14257 |
|
|
| 25 Mar 2015 04:55 PM |
"okay, tell me when you can animate welds without lag."
Animating from a LocalScript, for me, has caused absolutely no lag or performance problems. Get better internet or a better PC. The game Strife by Fenrier is a prime example of what can be accomplished with this. |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 04:57 PM |
| I love how youve been expanding on this. It seems to be so ething you enjoy. you should make a basic template i can study because im bad at this object oriented stuff. I want to see exactly how it interpolates from 1 cframe the others! Though i have an idea. |
|
|
| Report Abuse |
|
|
chimmihc
|
  |
| Joined: 01 Sep 2014 |
| Total Posts: 17143 |
|
|
| 25 Mar 2015 04:58 PM |
Good luck doing that with FE and you being the only person seeing the animations.
I script -~ chimmihc |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 04:59 PM |
did some research, it shouldn't be too hard to edit the animation editor/create a new one that uses sines.
⬡ |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 05:02 PM |
I have FE and only want the local player to see the animation.
Shoujld I do this? |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 05:04 PM |
| To make the server run the same animation could you not use a module? |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 05:05 PM |
| Which makes the animations smoother if you're working with FE, client-side? |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 05:08 PM |
Clientside is faster for the client.if you run from the server then the client I believe its better for people on the server to see it first. But for the server to see it after the client you run from the client then the server, from what ive seen COD uses the second method. |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 05:08 PM |
i need more info...
rarmweld.C1 = rarm.CFrame * CFrame.Angles(math.rad(0), math.rad(0), math.rad(45)) |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 05:10 PM |
| btw im doing this from command bar |
|
|
| Report Abuse |
|
|
NotAshley
|
  |
| Joined: 16 Jan 2014 |
| Total Posts: 14257 |
|
|
| 25 Mar 2015 05:16 PM |
"rarmweld.C1 = rarm.CFrame * CFrame.Angles(math.rad(0), math.rad(0), math.rad(45))"
Should be:
rarmweld.C1 = rarm.C1 * CFrame.Angles(math.rad(0), math.rad(0), math.rad(45))
This will set the C1's Z to a 45 degree angle. For animating, use loops. |
|
|
| Report Abuse |
|
|
NotAshley
|
  |
| Joined: 16 Jan 2014 |
| Total Posts: 14257 |
|
|
| 25 Mar 2015 05:17 PM |
| Sorry, I meant rarmweld.C1 * rarmweld.C1 (not rarm.C1) |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 05:33 PM |
thanks! :-) your guide is really helpful |
|
|
| Report Abuse |
|
|
BowtieMod
|
  |
| Joined: 01 Apr 2013 |
| Total Posts: 804 |
|
|
| 25 Mar 2015 05:34 PM |
Hm. A full-blown animation editor would be neat.
Would any of you like to work on that with me? |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 05:45 PM |
| @Cres: Yeah, I meant should I use the ROBLOX Anim editor or this method? |
|
|
| Report Abuse |
|
|
duckwit
|
  |
| Joined: 08 Aug 2008 |
| Total Posts: 1310 |
|
|
| 25 Mar 2015 05:55 PM |
| My current project, 'Frontier', is a good example of this animation technique. Use the shift key to see the sprinting animation. |
|
|
| Report Abuse |
|
|
MM233
|
  |
| Joined: 19 Jun 2008 |
| Total Posts: 925 |
|
|
| 25 Mar 2015 05:57 PM |
| What exactly do you mean by "smoothing" when using the sin/cos? |
|
|
| Report Abuse |
|
|
sycips
|
  |
| Joined: 21 Mar 2011 |
| Total Posts: 1368 |
|
|
| 25 Mar 2015 06:20 PM |
Animation editor from ROBLOX vs "Pseudo animations". Who wins?
Editor: because it's really easy to work with. The animations are smooth and can be created very easy!
Pseudo: Because the animations won't be stuck with 1 or 6 tracks. Also, other things could influence the animations, like your walkspeed. The animation can follow more than 1 track!
They both have their pro's and cons, but 1 thing is for sure! (If you create a "Pseudo animation" and Editor animation correctly,) Both ways of animating are equally lag-free!
~sycips~ |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 06:32 PM |
NotAshley can you give me an example of a pseudo animation script?
I'm more of an experimenter, it's hard for me to learn stuff just by reading it, anyways this is pretty cool!
But I still kinda don't understand cos, tan, sin, etc.
(I'm only in middle school) |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2015 06:36 PM |
add an npc named "NPC" to workspace
if workspace:FindFirstChild("NPC1") then workspace:FindFirstChild("NPC1"):Destroy() end
local npc = workspace.NPC:Clone() npc.Parent = workspace npc.Name = "NPC1" npc:MoveTo(Vector3.new(0,0,0))
local torso = npc.Torso local larm = npc["Left Arm"] local rarm = npc["Right Arm"] local lleg = npc["Left Leg"] local rleg = npc["Right Leg"]
torso["Left Hip"].Part0 = torso torso["Left Hip"].Part1 = nil torso["Right Hip"].Part0 = torso torso["Right Hip"].Part1 = nil torso["Left Shoulder"].Part0 = torso torso["Left Shoulder"].Part1 = nil torso["Right Shoulder"].Part0 = torso torso["Right Shoulder"].Part1 = nil
local function WeldTogether(Part0, Part1, JointType, WeldParent) JointType = JointType or "Weld" local NewWeld = Instance.new(JointType) NewWeld.Part0 = Part0; NewWeld.Part1 = Part1; NewWeld.C0 = CFrame.new(); NewWeld.C1 = Part1.CFrame:toObjectSpace(Part0.CFrame); NewWeld.Parent = WeldParent or Part0; return NewWeld end
for i,v in pairs(torso:GetChildren()) do if v:IsA("Weld") then v:Destroy() end end
local larmweld = WeldTogether(torso, larm) local rarmweld = WeldTogether(torso, rarm) local llegweld = WeldTogether(torso, lleg) local rlegweld = WeldTogether(torso, rleg)
local strav_fromAxisAngle = CFrame.fromAxisAngle local strav_components = CFrame.new().components local strav_inverse = CFrame.new().inverse local strav_v3 = Vector3.new local strav_acos = math.acos local strav_sqrt = math.sqrt local strav_invroot2 = 1/math.sqrt(2)
local interpolate = function(c0, c1, mode) local _, _, _, xx, yx, zx, xy, yy, zy, xz, yz, zz = strav_components(strav_inverse(c0)*c1) local cosTheta = (xx + yy + zz - 1)/2 local rotationAxis = strav_v3(yz-zy, zx-xz, xy-yx) local positionDelta = (c1.p - c0.p) local theta; if cosTheta >= 0.999 then return 0, function(t) return c0 + positionDelta*t end elseif cosTheta <= -0.999 then theta = math.pi xx = (xx + 1) / 2 yy = (yy + 1) / 2 zz = (zz + 1) / 2 if xx > yy and xx > zz then if xx < 0.001 then rotationAxis = strav_v3(0, strav_invroot2, strav_invroot2) else local x = strav_sqrt(xx) xy = (xy + yx) / 4 xz = (xz + zx) / 4 rotationAxis = strav_v3(x, xy/x, xz/x) end elseif yy > zz then if yy < 0.001 then rotationAxis = strav_v3(strav_invroot2, 0, strav_invroot2) else local y = strav_sqrt(yy) xy = (xy + yx) / 4 yz = (yz + zy) / 4 rotationAxis = strav_v3(xy/y, y, yz/y) end else if zz < 0.001 then rotationAxis = strav_v3(strav_invroot2, strav_invroot2, 0) else local z = strav_sqrt(zz) xz = (xz + zx) / 4 yz = (yz + zy) / 4 rotationAxis = strav_v3(xz/z, yz/z, z) end end else theta = strav_acos(cosTheta) end return theta, function(t) if mode == "start" then t = (-(math.cos(t * math.pi/2)) + 1) elseif mode == "stop" then t = ((math.sin(t * math.pi/2))) elseif mode == "both" then t = (((-(math.cos(t * math.pi)) * .5) - .5) + 1) end return c0*strav_fromAxisAngle(rotationAxis, theta*t) + positionDelta*t end end
----------
local c0 = rarmweld.C1 local c1 = CFrame.new(-1.5, 0.75, -0.5) * CFrame.Angles(math.rad(-177), 0, math.rad(-20)) local theta,int = interpolate(c0, c1, "both")
for i = 1, 20 do rarmweld.C1 = int(i / 20) wait() end
|
|
|
| Report Abuse |
|
|
| |
|