Very cool, just for the place to give off a more og feel as @RoninQV said above, change the lighting and decrease the gravity and jump power to get that og jump
Alright, I did it last night, and touched it up today:
It’s a bit more complicated… cause I like that I guess. But I made sure everything was well-commented, efficient, and organized.
The best viewing experience will be if you open the script in studio and right click “Collapse all Folds”
--=========================================================================================>
-- NAME: 2012 Animate Revamped
-- ORIGINAL AUTHOR: carrot (@KyjiPaws)
-- CURRENT AUTHOR: Sato (@IISato)
--==========================================================================================--
--!strict
--==========================================================================================--
-- DEFINE VARIABLES:
-- Service and Instance Variables:
local RunService : RunService, Humanoid : Humanoid, HumanoidRootPart: BasePart
-- Table Variables:
local TorsoData : any, PoseData : any, EventData: any
--==========================================================================================--
--[ UTILITY FUNCTIONS: ]
-- Function which returns whether the Character is moving based on MoveDirection magnitude:
local function IsMoving() : boolean
--=====================================================================--
-- Get Velocity of the HumanoidRootPart (Character Velocity)
local Velocity = math.floor(HumanoidRootPart.AssemblyLinearVelocity.Magnitude)
-- If MoveDirection Mag is greater than .99 (Meaning Player is trying to move)
-- AND the actual HumanoidRootPart Velocity (Actual Movement) is greater than 0
-- Will stop the Run Animation when walking into a wall. (New Feature..)
return Humanoid.MoveDirection.Magnitude > .99 and Velocity > 0
--=====================================================================--
end
-- Function which Changes the Pose from Standing to Running based on whether the Character is moving every frame:
local function RunningUpdate()
if PoseData.CurrentPose == "Standing" or PoseData.CurrentPose == "Running" then
PoseData.CurrentPose = if IsMoving() then "Running" else "Standing"
end
end
-- Function which will play the Animation for whichever Pose is active
local function PlayAnimations()
--=====================================================================--
-- Assign the CurrentPose value to a local Variable for looks.
local CurrentPose : string = PoseData.CurrentPose :: string
--=====================================================================--
if CurrentPose == "Dead" then
-- Clear the Event Connections:
for Index, Event in pairs(EventData) do Event:Disconnect() end
-- Destroy the Script:
script:Destroy()
end
if CurrentPose == "Jumping" or CurrentPose == "Freefall" then
TorsoData['Left Shoulder'].MaxVelocity = 0.5
TorsoData['Right Shoulder'].MaxVelocity = 0.5
TorsoData['Left Shoulder']:SetDesiredAngle(-math.pi)
TorsoData['Right Shoulder']:SetDesiredAngle(math.pi)
TorsoData['Left Hip']:SetDesiredAngle(0)
TorsoData['Right Hip']:SetDesiredAngle(0)
end
if CurrentPose == "Seated" then
TorsoData['Left Shoulder'].MaxVelocity = 0.15
TorsoData['Right Shoulder'].MaxVelocity = 0.15
TorsoData['Left Shoulder']:SetDesiredAngle(-math.pi / 2)
TorsoData['Right Shoulder']:SetDesiredAngle(math.pi / 2)
TorsoData['Left Hip']:SetDesiredAngle(-math.pi / 2)
TorsoData['Right Hip']:SetDesiredAngle(math.pi / 2)
end
if CurrentPose == "Running" or CurrentPose == "Swimming" then
TorsoData['Left Shoulder'].MaxVelocity = 0.15
TorsoData['Right Shoulder'].MaxVelocity = 0.15
local DesiredAngle = 1 * math.sin(os.clock() * 9)
TorsoData['Left Shoulder']:SetDesiredAngle(DesiredAngle - 0)
TorsoData['Right Shoulder']:SetDesiredAngle(DesiredAngle + 0)
TorsoData['Left Hip']:SetDesiredAngle(-DesiredAngle)
TorsoData['Right Hip']:SetDesiredAngle(-DesiredAngle)
end
if CurrentPose == "Climbing" then
if IsMoving() then
TorsoData['Left Shoulder'].MaxVelocity = 0.5
TorsoData['Right Shoulder'].MaxVelocity = 0.5
TorsoData['Left Hip'].MaxVelocity = 0.1
TorsoData['Right Hip'].MaxVelocity = 0.1
else
TorsoData['Left Shoulder'].MaxVelocity = 0
TorsoData['Right Shoulder'].MaxVelocity = 0
TorsoData['Left Hip'].MaxVelocity = 0
TorsoData['Right Hip'].MaxVelocity = 0
end
local DesiredAngle = 1 * math.sin(os.clock() * 9)
TorsoData['Left Shoulder']:SetDesiredAngle(DesiredAngle - math.pi)
TorsoData['Right Shoulder']:SetDesiredAngle(DesiredAngle + math.pi)
TorsoData['Left Hip']:SetDesiredAngle(-DesiredAngle)
TorsoData['Right Hip']:SetDesiredAngle(-DesiredAngle)
end
if CurrentPose == "Standing" then
TorsoData['Left Shoulder']:SetDesiredAngle(0)
TorsoData['Right Shoulder']:SetDesiredAngle(0)
TorsoData['Left Hip']:SetDesiredAngle(0)
TorsoData['Right Hip']:SetDesiredAngle(0)
end
--=====================================================================--
end
--==========================================================================================--
--[ SETUP FUNCTIONS: ]
-- Function which will set and declare any global variables, and setup Data:
local function SetVariables()
--=====================================================================--
-- Character Model Instance
local Character: Model = script:FindFirstAncestorOfClass("Model") :: Model
-- Character Torso Instance
local Torso : BasePart = Character:WaitForChild("Torso") :: BasePart
--=====================================================================--
-- Roblox RunService
RunService = game:GetService("RunService") :: RunService
-- Character Humanoid Instance
Humanoid = Character:WaitForChild("Humanoid") :: Humanoid
-- Character HumanoidRootPart Instance
HumanoidRootPart = Character:WaitForChild("HumanoidRootPart") :: BasePart
-- PoseData Dictionary, containing the humanoid states that are allowed as poses, and the currentpose.
PoseData = {
-- Allowed Humanoid States as Poses Array:
Poses = {"Running", "Climbing", "Jumping", "Freefall", "Seated", "Dead", "Swimming"},
-- CurrentPose the Character is in
CurrentPose = "Standing"
}
-- Empty TorsoData Dictionary to be filled with Instances
TorsoData = {
["Left Shoulder"] = "", ["Right Shoulder"] = "", ["Left Hip"] = "", ["Right Hip"] = "", ["Neck"] = ""
}
-- Declare EventData as an empty table
EventData = {}
--=====================================================================--
-- Fill the TorsoData Dict by waiting for each Index in the Torso Instance and adding it to the Dictionary.
for Index, TorsoChild in TorsoData do TorsoData[Index] = Torso:WaitForChild(Index) end
--=====================================================================--
end
-- Function which will Connect all the needed events in the script:
local function ConnectEvents()
--=====================================================================--
EventData["State"] = Humanoid.StateChanged:Connect(function(OldEnmuState, NewEnumState)
--===============================================================--
-- [ Format Variables: ]
-- Initiate new Variables which will be the formatted string version of the Enums:
local NewState: string, OldState: string = tostring(NewEnumState), tostring(OldEnmuState)
-- Replacement Pattern (so that I can one line the variable sets):
local Pattern = "Enum.HumanoidStateType."
-- Format the String Enums to not have the Enum parts:
NewState, OldState = string.gsub(NewState, Pattern, ""), string.gsub(OldState, Pattern, "")
--===============================================================--
-- If Pose is not in the PoseData poses table, return
if not table.find(PoseData.Poses, NewState) then return end
--===============================================================--
-- [ Set the changed Pose: ]
if NewState == "Running" then
PoseData.CurrentPose = if IsMoving() then "Running" else "Standing"
else
PoseData.CurrentPose = NewState
end
--===============================================================--
end)
EventData["Anim"] = RunService.PreAnimation:Connect(function()
--===============================================================--
-- Update the Pose if Moving:
RunningUpdate()
-- Motor Animations Function:
PlayAnimations()
--===============================================================--
end)
--=====================================================================--
end
--==========================================================================================--
--[ MAIN SCRIPT FUNCTION: ]
-- Function which will run the Script Setup Functions:
local function Main()
--=====================================================================--
-- Set Script global variables:
SetVariables()
-- Connect Events:
ConnectEvents()
--=====================================================================--
end
--==========================================================================================--
Main() -- Start the script:
--==========================================================================================--
Some Extras:
- Movement checker to determine whether the Character is moving to stop Animations from playing otherwise.
- Used movement check to have Climb Animation only play when moving and climbing and to freeze when still.
Looks like a massive amount of code for something that pretty much does the same thing…
Might look into adding a check for stopping the climbing animation, but at that point I think it’d become its own thing.
Intentionally making my game look ugly just to give off a “classic” vibe is not something I intend on doing.
Be honest, this looks awful.
This on the other hand…
I mean half the lines are comments, and I opted for the one state change event rather than individual state connections.
I’m just a little confused on why, considering the script was already like… 80 lines of code excluding comments. Just seems odd to over complicate what already works fine.
Your code is I believe 120.
Yeah, yours does work fine, it’s good. I just wanted to make it a little more advanced I guess.
My script is about 107 lines in it’s readable form (the condensed version is what i was referring to when I said 80 lines), While yours is about 265 lines.
I don’t really think nearly tripling the length of the script for like, two visible changes, is really worth it in my opinion, at least in the case of a simple little animate script that already takes less than about 10 microseconds to run.
You’re vastly over exaggerating the effect of a 100 lines of code.
Alright, I did a load time test of the scripts:
Miniscule difference, but not worse.
Sato’s:
Carrot’s
My point was that it didn’t matter. Saving 4 microseconds on startup isn’t significant. ;w;
Might need to work on the brightness for compatibility there.
Why are you coping so hard? I told you originally, I was just going to try writing it differently myself.
You’re the one who wanted to one-up my script so I think me criticizing your script is fair… (Which, now that I’m looking again, you deleted your message saying that… Odd…)
Yea that’s the problem… there’s a reason why Legacy
and Compatibility
were replaced!
Heh no I did not delete it, some dimwit reported it.
Works great with contrast adjustment. Adjusting by 0.5 is good.
Both of these images are compatibility:
The 2nd one is the one you posted, and I didn’t make any modifications to the lighting other than changing the contrast to .3 and changing technology to compatibility.
So please, don’t consider compatibility ugly when it looks like shadowmap but without the shadows.
I just realized that the tool animations are missing! I improved the animate script as well to include this and also slow down the update frequency when animations are “idle” (it makes it look more classic as well).
Additionally, it will also adjust the speed of the walk animation depending on the running speed. Here’s the updated script if you want to include some additions or ideas from it:
local RunService = game:GetService("RunService")
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local Torso = Character:WaitForChild("Torso")
local LeftShoulder = Torso:WaitForChild("Left Shoulder")
local RightShoulder = Torso:WaitForChild("Right Shoulder")
local LeftHip = Torso:WaitForChild("Left Hip")
local RightHip = Torso:WaitForChild("Right Hip")
local Neck = Torso:WaitForChild("Neck")
local GlobalSpeed = 0
local toolAnim = "None"
local toolAnimTime = .3
local updateFrequency = 0.2
local dynamicUpdateFrequency = true --Throttle the animations when necessary.
-- Current Animation
local Pose = "Standing"
-- Connect Events
Humanoid.Died:Connect(function()
-- No need to animate the dead!
script:Destroy()
end)
Humanoid.Running:Connect(function(Speed)
-- Sometimes the speed can get stuck at extremely small values, so this prevents the character running in place
-- Change '0.1' to '0' for the original behavior
if Speed > 0.1 then
Pose = "Running"
GlobalSpeed = Speed / 16 --default walkspeed
else
Pose = "Standing"
GlobalSpeed = 0
end
end)
Humanoid.Swimming:Connect(function()
Pose = "Running"
end)
Humanoid.Jumping:Connect(function()
Pose = "Jumping"
end)
Humanoid.Climbing:Connect(function()
Pose = "Climbing"
end)
Humanoid.FreeFalling:Connect(function()
Pose = "FreeFall"
end)
Humanoid.Seated:Connect(function()
Pose = "Seated"
end)
-- Update
local function JumpAnimation()
LeftShoulder.MaxVelocity = 0.5
RightShoulder.MaxVelocity = 0.5
LeftShoulder:SetDesiredAngle(-math.pi)
RightShoulder:SetDesiredAngle(math.pi)
LeftHip:SetDesiredAngle(0)
RightHip:SetDesiredAngle(0)
end
local function SitAnimation()
LeftShoulder.MaxVelocity = 0.15
RightShoulder.MaxVelocity = 0.15
LeftShoulder:SetDesiredAngle(-math.pi / 2)
RightShoulder:SetDesiredAngle(math.pi / 2)
LeftHip:SetDesiredAngle(-math.pi / 2)
RightHip:SetDesiredAngle(math.pi / 2)
end
function getTool()
for _, kid in ipairs(Character:GetChildren()) do
if kid.className == "Tool" then return kid end
end
return nil
end
function getToolAnim(tool)
for _, c in ipairs(tool:GetChildren()) do
if c.Name == "toolanim" and c.className == "StringValue" then
return c
end
end
return nil
end
function animateTool()
if (toolAnim == "None") then
RightShoulder:SetDesiredAngle(1.57)
return
end
if (toolAnim == "Slash") then
RightShoulder.MaxVelocity = 0.5
RightShoulder:SetDesiredAngle(0)
return
end
if (toolAnim == "Lunge") then
RightShoulder.MaxVelocity = 0.5
LeftShoulder.MaxVelocity = 0.5
RightHip.MaxVelocity = 0.5
LeftHip.MaxVelocity = 0.5
RightShoulder:SetDesiredAngle(1.57)
LeftShoulder:SetDesiredAngle(1.0)
RightHip:SetDesiredAngle(1.57)
LeftHip:SetDesiredAngle(1.0)
return
end
end
local lastUpdate = 0
RunService.RenderStepped:Connect(function()
local time = time()
if time - lastUpdate < updateFrequency then
return
end
lastUpdate = time
if Pose == "Jumping" or Pose == "FreeFall" then
JumpAnimation()
return
end
if Pose == "Seated" then
SitAnimation()
return
end
local Amplitude = 0.1
local Frequency = 1
-- I have no idea why this is called 'ClimbFudge'
local ClimbFudge = 0
if Pose == "Running" then
LeftShoulder.MaxVelocity = 0.15
RightShoulder.MaxVelocity = 0.15
Amplitude = 1
Frequency = 9 * GlobalSpeed
elseif Pose == "Climbing" then
LeftShoulder.MaxVelocity = 0.5
RightShoulder.MaxVelocity = 0.5
Amplitude = 1
Frequency = 9
ClimbFudge = math.pi
end
local DesiredAngle = Amplitude * math.sin(time * Frequency)
LeftShoulder:SetDesiredAngle(DesiredAngle - ClimbFudge)
RightShoulder:SetDesiredAngle(DesiredAngle + ClimbFudge)
LeftHip:SetDesiredAngle(-DesiredAngle)
RightHip:SetDesiredAngle(-DesiredAngle)
local tool = getTool()
if tool then
local animStringValueObject = getToolAnim(tool)
if animStringValueObject then
toolAnim = animStringValueObject.Value
-- message recieved, delete StringValue
animStringValueObject:Destroy()--.Parent = nil
toolAnimTime = time + .3
end
if time > toolAnimTime then
toolAnimTime = 0
toolAnim = "None"
end
animateTool()
else
toolAnim = "None"
toolAnimTime = 0
end
if dynamicUpdateFrequency then
updateFrequency = (Frequency > 1 and 0) or .1
end
end)
I apologize in advance for using camelCase variable names.
Sounds like a good idea! Not only would this be more performant, but it could possibly work with R15 using this thing I made to create animations with both rigs:
If you don’t choose to use it, that’s fine. I think it would be neat though.