276 lines
7.7 KiB
Lua
276 lines
7.7 KiB
Lua
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
-- Services
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
local CollectionService = game:GetService("CollectionService")
|
|
local RunService = game:GetService("RunService")
|
|
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
-- Animator Data
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
local Animators = {}
|
|
|
|
local function createAnimator(humanoid)
|
|
local Figure = humanoid.Parent
|
|
|
|
local Torso = Figure:WaitForChild("Torso", 5)
|
|
local Climbing = Figure:WaitForChild("Climbing", 5)
|
|
|
|
if not (Torso and Climbing) then
|
|
return
|
|
end
|
|
|
|
local animator = {}
|
|
animator.Joints = {}
|
|
|
|
do
|
|
local joints =
|
|
{
|
|
RightShoulder = Torso:WaitForChild("Right Shoulder", 5);
|
|
LeftShoulder = Torso:WaitForChild("Left Shoulder", 5);
|
|
RightHip = Torso:WaitForChild("Right Hip", 5);
|
|
LeftHip = Torso:WaitForChild("Left Hip", 5);
|
|
}
|
|
|
|
if not (joints.RightShoulder and joints.LeftShoulder) then
|
|
return
|
|
end
|
|
|
|
if not (joints.RightHip and joints.LeftHip) then
|
|
return
|
|
end
|
|
|
|
for name, joint in pairs(joints) do
|
|
local object =
|
|
{
|
|
JointObject = joint;
|
|
MaxVelocity = joint.MaxVelocity;
|
|
DesiredAngle = joint.DesiredAngle;
|
|
CurrentAngle = joint.CurrentAngle;
|
|
}
|
|
|
|
animator.Joints[name] = object
|
|
end
|
|
end
|
|
|
|
local joints = animator.Joints
|
|
|
|
local pi = math.pi
|
|
local sin = math.sin
|
|
|
|
local pose = "Standing"
|
|
local toolAnim = "None"
|
|
local toolAnimTime = 0
|
|
|
|
local RightShoulder = joints.RightShoulder
|
|
local LeftShoulder = joints.LeftShoulder
|
|
|
|
local RightHip = joints.RightHip
|
|
local LeftHip = joints.LeftHip
|
|
|
|
function animator:SetMaxVelocities(value)
|
|
RightShoulder.MaxVelocity = value
|
|
LeftShoulder.MaxVelocity = value
|
|
|
|
RightHip.MaxVelocity = value
|
|
LeftHip.MaxVelocity = value
|
|
end
|
|
|
|
function animator:Update()
|
|
local now = tick()
|
|
|
|
if Climbing.Value then
|
|
pose = "Climbing"
|
|
else
|
|
local stateType = humanoid:GetState()
|
|
pose = stateType.Name
|
|
|
|
if pose == "Running" then
|
|
local speed = humanoid.WalkSpeed
|
|
local movement = (Torso.Velocity * Vector3.new(1, 0, 1)).Magnitude
|
|
|
|
if (speed * movement) < 1 then
|
|
pose = "Standing"
|
|
end
|
|
end
|
|
end
|
|
|
|
if pose == "Jumping" then
|
|
self:SetMaxVelocities(.5)
|
|
|
|
RightShoulder.DesiredAngle = 1
|
|
LeftShoulder.DesiredAngle = -1
|
|
|
|
RightHip.DesiredAngle = 0
|
|
LeftHip.DesiredAngle = 0
|
|
elseif pose == "Freefall" then
|
|
self:SetMaxVelocities(.5)
|
|
|
|
RightShoulder.DesiredAngle = pi
|
|
LeftShoulder.DesiredAngle = -pi
|
|
|
|
RightHip.DesiredAngle = 0
|
|
LeftHip.DesiredAngle = 0
|
|
elseif pose == "Seated" then
|
|
self:SetMaxVelocities(.15)
|
|
|
|
RightShoulder.DesiredAngle = pi / 2
|
|
LeftShoulder.DesiredAngle = -pi / 2
|
|
|
|
RightHip.DesiredAngle = pi / 2
|
|
LeftHip.DesiredAngle = -pi / 2
|
|
else
|
|
local climbFudge = 0
|
|
local amplitude = .1
|
|
local frequency = 1
|
|
|
|
if pose == "Running" then
|
|
self:SetMaxVelocities(0.15)
|
|
amplitude = 1
|
|
frequency = 9
|
|
elseif pose == "Climbing" then
|
|
self:SetMaxVelocities(0.5)
|
|
climbFudge = pi
|
|
|
|
amplitude = 1
|
|
frequency = 9
|
|
end
|
|
|
|
local desiredAngle = amplitude * sin(now * frequency)
|
|
|
|
RightShoulder.DesiredAngle = desiredAngle + climbFudge
|
|
LeftShoulder.DesiredAngle = desiredAngle - climbFudge
|
|
|
|
RightHip.DesiredAngle = -desiredAngle
|
|
LeftHip.DesiredAngle = -desiredAngle
|
|
|
|
local tool = Figure:FindFirstChildWhichIsA("Tool")
|
|
|
|
if tool and tool.RequiresHandle and not CollectionService:HasTag(tool, "Flag") then
|
|
local animString = tool:FindFirstChild("toolanim")
|
|
|
|
if animString and animString:IsA("StringValue") then
|
|
-- apply tool animation
|
|
toolAnim = animString.Value
|
|
toolAnimTime = now + .3
|
|
|
|
-- delete event sender
|
|
animString:Destroy()
|
|
end
|
|
|
|
if now > toolAnimTime then
|
|
toolAnimTime = 0
|
|
toolAnim = "None"
|
|
end
|
|
|
|
if toolAnim == "None" then
|
|
RightShoulder.DesiredAngle = pi / 2
|
|
elseif toolAnim == "Slash" then
|
|
RightShoulder.MaxVelocity = 0.5
|
|
RightShoulder.DesiredAngle = 0
|
|
elseif toolAnim == "Lunge" then
|
|
self:SetMaxVelocities(0.5)
|
|
|
|
RightShoulder.DesiredAngle = pi / 2
|
|
RightHip.DesiredAngle = pi / 2
|
|
|
|
LeftShoulder.DesiredAngle = 1
|
|
LeftHip.DesiredAngle = 1
|
|
end
|
|
else
|
|
toolAnim = "None"
|
|
toolAnimTime = 0
|
|
end
|
|
end
|
|
end
|
|
|
|
return animator
|
|
end
|
|
|
|
local function createAnimatorAsync(humanoid, callback)
|
|
local async = coroutine.wrap(function ()
|
|
local animator = createAnimator(humanoid)
|
|
callback(animator)
|
|
end)
|
|
|
|
async()
|
|
end
|
|
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
-- Collection Handler
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
local animTag = "Animator"
|
|
|
|
local animAdded = CollectionService:GetInstanceAddedSignal(animTag)
|
|
local animRemoved = CollectionService:GetInstanceRemovedSignal(animTag)
|
|
|
|
local function onAnimatorAdded(humanoid)
|
|
if humanoid:IsA("Humanoid") then
|
|
createAnimatorAsync(humanoid, function (animator)
|
|
if CollectionService:HasTag(humanoid, animTag) then
|
|
Animators[humanoid] = animator
|
|
end
|
|
end)
|
|
end
|
|
end
|
|
|
|
local function onAnimatorRemoved(humanoid)
|
|
if Animators[humanoid] then
|
|
Animators[humanoid] = nil
|
|
end
|
|
end
|
|
|
|
for _,humanoid in pairs(CollectionService:GetTagged(animTag)) do
|
|
onAnimatorAdded(humanoid)
|
|
end
|
|
|
|
animAdded:Connect(onAnimatorAdded)
|
|
animRemoved:Connect(onAnimatorRemoved)
|
|
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
-- Motor Angle Updater
|
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
local desiredFPS = 30 -- The framerate that would be expected given the MaxVelocity in use.
|
|
|
|
local function updateAnimations(deltaTime)
|
|
local velocityAdjust = desiredFPS * deltaTime
|
|
|
|
for humanoid, animator in pairs(Animators) do
|
|
-- Update the motor states
|
|
animator:Update()
|
|
|
|
-- Step the motor angles
|
|
for name, jointData in pairs(animator.Joints) do
|
|
local joint = jointData.JointObject
|
|
local maxVelocity = jointData.MaxVelocity
|
|
|
|
local desiredAngle = jointData.DesiredAngle
|
|
local currentAngle = jointData.CurrentAngle
|
|
|
|
-- Adjust the MaxVelocity based on the current framerate
|
|
maxVelocity = math.abs(maxVelocity * velocityAdjust)
|
|
|
|
-- Update the CurrentAngle
|
|
local delta = (desiredAngle - currentAngle)
|
|
|
|
if math.abs(delta) < maxVelocity then
|
|
currentAngle = desiredAngle
|
|
elseif delta > 0 then
|
|
currentAngle = currentAngle + maxVelocity
|
|
else
|
|
currentAngle = currentAngle - maxVelocity
|
|
end
|
|
|
|
-- Apply the motor transform
|
|
joint.Transform = CFrame.Angles(0, 0, currentAngle)
|
|
jointData.CurrentAngle = currentAngle
|
|
end
|
|
end
|
|
end
|
|
|
|
RunService:BindToRenderStep("UpdateAnimations", 301, updateAnimations)
|
|
|
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |